EmbDev.net

Forum: ARM programming with GCC/GNU tools undefined reference to `memcpy'


von Jose S. (israel)


Rate this post
useful
not useful
hi!
i'm trying for the first time with YAGARTO tollchain, but when i use
fuctions like sprintf, strncpy...i get an error message like:

C:\Documents and
Settings\Israel\workspace\demo2106_blink_flash/main.c:63: undefined
reference to `memcpy'
C:\Documents and
Settings\Israel\workspace\demo2106_blink_flash/main.c:64: undefined
reference to `strncpy'.

may someone help me with this?


Israel

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Jose Sousa wrote:
> hi!
> i'm trying for the first time with YAGARTO tollchain, but when i use
> fuctions like sprintf, strncpy...i get an error message like:
>
> C:\Documents and
> Settings\Israel\workspace\demo2106_blink_flash/main.c:63: undefined
> reference to `memcpy'
> C:\Documents and
> Settings\Israel\workspace\demo2106_blink_flash/main.c:64: undefined
> reference to `strncpy'.

-lc given als linker-paramter?

Give the complete output of the build-process including the paramters
passed to the tools. And try to avoid blanks in pathes (like
Documents[blank]and...) may cause problems.

von Jose S. (israel)


Rate this post
useful
not useful
Martin Thomas wrote:
> Jose Sousa wrote:
>> hi!
>> i'm trying for the first time with YAGARTO tollchain, but when i use
>> fuctions like sprintf, strncpy...i get an error message like:
>>
>> C:\Documents and
>> Settings\Israel\workspace\demo2106_blink_flash/main.c:63: undefined
>> reference to `memcpy'
>> C:\Documents and
>> Settings\Israel\workspace\demo2106_blink_flash/main.c:64: undefined
>> reference to `strncpy'.
>
> -lc given als linker-paramter?
>
> Give the complete output of the build-process including the paramters
> passed to the tools. And try to avoid blanks in pathes (like
> Documents[blank]and...) may cause problems.

----------------------------------------------------------------------

Hi Martin, thanks for reply. Here goes my makefile, main.c and the
output.

Current makefile:


NAME   = demo2106_blink_flash

CC      = arm-elf-gcc
LD      = arm-elf-ld  -v
AR      = arm-elf-ar
AS      = arm-elf-as
CP      = arm-elf-objcopy
OD    = arm-elf-objdump

CFLAGS  = -I./ -c -fno-common -O0 -g
AFLAGS  = -ahls -mapcs-32 -o crt.o

LFLAGS +=  -L'C:\Program Files\yagarto\lib\gcc\arm-elf\4.1.1\' -lgcc -lc


LFLAGS  += -Map main.map -T  demo2106_blink_flash.cmd
CPFLAGS = -O binary
ODFLAGS  = -x --syms

all: test

clean:
  -rm crt.lst main.lst crt.o main.o main.out main.bin main.hex main.map
main.dmp

test: main.out
  @ echo "...copying"
  $(CP) $(CPFLAGS) main.out main.hex
  $(CP) $(CPFLAGS) main.out main.bin
  $(OD) $(ODFLAGS) main.out > main.dmp

main.out: crt.o main.o demo2106_blink_flash.cmd
  @ echo "..linking"
  $(LD) $(LFLAGS) -o main.out  crt.o main.o

crt.o: crt.s
  @ echo ".assembling"
  $(AS) $(AFLAGS) crt.s > crt.lst

main.o: main.c
  @ echo ".compiling"
  $(CC) $(CFLAGS) main.c


---------------------------------------------
Console; Output
---------------------------------------------

make -k all
.compiling
arm-elf-gcc   -I./ -c -fno-common -O0 -g  main.c
..linking
arm-elf-ld  -v    -L'C:\Program Files\yagarto\lib\gcc\arm-elf\4.1.1\'
-lgcc -lc -Map main.map -T  demo2106_blink_flash.cmd   -o main.out
crt.o main.o
GNU ld version 2.17
main.o: In function `main':
C:\Documents and
Settings\Israel\workspace\demo2106_blink_flash/main.c:64: undefined
reference to `memcpy'
C:\Documents and
Settings\Israel\workspace\demo2106_blink_flash/main.c:65: undefined
reference to `strncpy'
C:\Documents and
Settings\Israel\workspace\demo2106_blink_flash/main.c:66: undefined
reference to `puts'
make: *** [main.out] Error 1
make: Target `all' not remade because of errors.


---------------------------------------------
Partial code (main.c):
---------------------------------------------

/**********************************************************
                  Header files
 **********************************************************/
#include "LPC210x.h"
#include <stdio.h>
#include "stdio.h"
#include "string.h"

/**********************************************************
                  Global Variables
 **********************************************************/
int    q;        // global uninitialized variable
int    r;        // global uninitialized variable
int    s;        // global uninitialized variable

short  h = 2;      // global initialized variable
short  i = 3;      // global initialized variable
char  j = 6;      // global initialized variable




/**********************************************************
                       MAIN
**********************************************************/

int  main (void) {

  int    j;                    // loop counter (stack variable)
  static int    a,b,c;              // static uninitialized variables
  static  char  d;                // static uninitialized variables
  static int    w = 1;              // static initialized variable
  static long  x = 5;                // static initialized variable
  static  char  y = 0x04;            // static initialized variable
  static int    z = 7;              // static initialized variable
  const  char  *pText = "The Rain in Spain";
  char str[24];
  char str1[24];



  // Initialize the system
  Initialize();

  // set io pins for led P0.7
  IODIR |= 0x00000080;  // pin P0.7 is an output, everything else is
input after reset
  IOSET =  0x00000080;  // led off
  IOCLR =  0x00000080;  // led on



  sprintf(str, "Ola! \n");
  strncpy(str1,str,20);
  printf("Olá\n");

  // endless loop to toggle the red  LED P0.7
  while (1) {

    for (j = 0; j < 5000000; j++ );    // wait 500 msec
    IOSET = 0x00000080;           // red led off
    for (j = 0; j < 5000000; j++ );    // wait 500 msec
    IOCLR = 0x00000080;           // red led on
  }
}



Thanks for attention.

von Magnus Sundell (Guest)


Rate this post
useful
not useful
For what it's worth, I had the same issue the other day. I was working 
on an ARM project with the STM32 Cortex-M3 MCU. The quick fix I tried 
was to use gcc.exe instead of ld.exe for linking.

It removed the problem with undefined references, but after debugging 
the project I discovered that the toolchain inserted illegal 
instructions for the Cortex-M3. To be specific, every time e.g. memcpy 
or memset would be called, the assembler instruction generated was BLX 
address, which generates a HardFault on Cortex M3 (or so I think). On 
this type of processor, it should only generate BLX register.

So I switched back to ld.exe for linking, but now had to specify the 
-lgcc and -lc switches manually. I also had to specify where ld should 
look for libraries. After trying a few times, I discovered that the 
YAGARTO toolchain includes libc.a and libgcc.a libraries specifically 
for Thumb and ARMV7-M cores. Including these in LFLAGS did help ld.exe 
find the libraries, but the undefined references remained.

So I had a read on the -l option for GCC linker. The example with 'foo.o 
-lz bar.o' inspired me to move the -L and -l options to the end of the 
link command. I.e.

$(LD) $(FLAGS) -o main.out <objfiles> 
-L"E:/yagarto/lib/gcc/arm-none-eabi/4.5.1/thumb/v7m" -lgcc 
-L"E:/yagarto/arm-none-eabi/lib/thumb/v7m" -lc

This removed the problem with undefined references, and now the build 
generates correct BLX instructions (for my project).

So it seems to be that the -L and -l options should be placed after the 
list of object files which are linked. As the GCC documentation states, 
if an object file listed after the libraries uses functions from those 
libraries, they may not be loaded (order matters).

I am aware that this thread is over two years old, but I thought that 
I'd provide my two cents in solving a problem which I have myself spent 
some hours battling. At the same time, present a solution to a 
STM32-specific problem with invalid BLX instruction being generated.

// MS

von Frikkie Thirion (Guest)


Rate this post
useful
not useful
Good day,
Thank you for your post - I've had problems for months referencing c 
library calls. I basically gave up just to finish my project, coding my 
own versions of memcpy() and memset()
The problem was that I was referencing
-L/opt/arm_codesourcery/lib/gcc/arm-none-eabi/4.5.1 and
-L/opt/arm_codesourcery/lib/gcc/arm-none-eabi/4.5.1/thumb2
in my LDFLAGS

Both directories contains libgcc.a
It seems the linker picked up the wrong library due to the library 
order. I've removed the reference to 
"-L/opt/arm_codesourcery/lib/gcc/arm-none-eabi/4.5.1" and now everything 
works great!

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.