Linking with newlib: undefined reference to memcpy - arm

I'm trying to build an arm boot loader, and it's relying on newlib to supply some system calls (like memcpy).
When I run:
arm-elf-ld -static -L /usr/arm-elf/lib/thumb/ -lc -nostdlib -nostartfile -Map=loader.map --cref -T loader.lds --gc-sections -Ttext 0x000000 -n -o loader.elf start.o _udivsi3.o _umodsi3.o main.o util.o gpio.o spi.o flashatmel.o flashjedec.o image.o time.o clock.o led.o register.o sdram.o
I get the following:
flashatmel.o flashjedec.o image.o time.o clock.o led.o register.o sdram.o
main.o: In function `TtyPutConfiguration':
/home/shawn/projects/netbridge-fx/loader/main.c:19: undefined reference to `memcpy'
main.o: In function `main':
/home/shawn/projects/netbridge-fx/loader/main.c:135: undefined reference to `__gnu_thumb1_case_uqi'
/home/shawn/projects/netbridge-fx/loader/main.c:145: undefined reference to `__gnu_thumb1_case_uqi'
/home/shawn/projects/netbridge-fx/loader/main.c:155: undefined reference to `__gnu_thumb1_case_uqi'
/home/shawn/projects/netbridge-fx/loader/main.c:165: undefined reference to `__gnu_thumb1_case_uqi'
gpio.o: In function `GpioTest':
/home/shawn/projects/netbridge-fx/loader/gpio.c:139: undefined reference to `__gnu_thumb1_case_uqi'
For now, I'm attacking the memcpy, and hoping the others follow. When I run nm /usr/arm-elf/lib/thumb/libc.a (which, I believe, is the newlib version of libc), it shows:
lib_a-memcpy.o:
00000010 N $d
00000000 t $t
00000001 T memcpy
So, that shows that memcpy is defined in the library.
I ran strace on the ld command above to make sure it's actually looking at that file, and indeed, it is.
What am I missing here? Why is it complaining about an undefined memcpy?

This looks fishy:
-lc -nostdlibs
I think -nostdlibs is canceling out -lc. Try linking libc.a directly and see what happens.
While you're at it, I see you're linking in some intrinsic implementations (like _udivsi3.o). Try linking with libgcc.a, it should have definitions for all of the intrinsics you need.

Related

Error while compiling PortAudio examples

(I am on Ubuntu) I am trying to run the PortAudio examples, but getting many errors (mentioned below). I have placed the header file portaudio.h in the directory of the program. I have no idea about it. I think it is linker error. Please help!
/tmp/cc5EbTlT.o: In function main':
paex_record.c:(.text+0x37e): undefined reference toPa_Initialize'
paex_record.c:(.text+0x397): undefined reference to Pa_GetDefaultInputDevice'
paex_record.c:(.text+0x3de): undefined reference toPa_GetDeviceInfo'
paex_record.c:(.text+0x436): undefined reference to Pa_OpenStream'
paex_record.c:(.text+0x45a): undefined reference toPa_StartStream'
paex_record.c:(.text+0x493): undefined reference to Pa_Sleep'
paex_record.c:(.text+0x4c2): undefined reference toPa_IsStreamActive'
paex_record.c:(.text+0x4eb): undefined reference to Pa_CloseStream'
paex_record.c:(.text+0x5fa): undefined reference toPa_GetDefaultOutputDevice'
paex_record.c:(.text+0x641): undefined reference to Pa_GetDeviceInfo'
paex_record.c:(.text+0x6b2): undefined reference toPa_OpenStream'
paex_record.c:(.text+0x6e3): undefined reference to Pa_StartStream'
paex_record.c:(.text+0x71c): undefined reference toPa_Sleep'
paex_record.c:(.text+0x728): undefined reference to Pa_IsStreamActive'
paex_record.c:(.text+0x74e): undefined reference toPa_CloseStream'
paex_record.c:(.text+0x77d): undefined reference to Pa_Terminate'
paex_record.c:(.text+0x7e5): undefined reference toPa_GetErrorText'
collect2: error: ld returned 1 exit status
Assuming you are compiling using gcc and you have a single C file foo.c, the compiler command would be
gcc -o foo foo.c -lrt -lasound -ljack -lpthread -lportaudio
The -l parameters are there to link the required libraries to your program, e.g. -lrt will link librt.a. The order does matter.
I got the required libraries from here: http://www.portaudio.com/docs/v19-doxydocs/compile_linux.html#comp_linux3. Don't know if they are correct. At least you need -lportaudio, obviously.
If the libraries are not found, you have to provide gcc a path, e.g.
gcc -L/usr/lib -o foo foo.c -lrt -lasound -ljack -lpthread -lportaudio
Regarding the header, you don't actually need to copy it into your program's directory. You'd rather include it as
#include <portaudio.h>
and add its directory to the include search path:
gcc -I/usr/include -L/usr/lib -o foo foo.c -lrt -lasound -ljack -lpthread -lportaudio
Of course, all this is better done in a Makefile.

Make is unable to find the functions

I am trying to compile a C program, while linking the APR library.
I am getting the following error message:
cc -g -Wall -pthread -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -L/usr/local/apr/lib -L .aprutil-1 -L .apr-1 devpkg.c bstrlib.o db.o shell.o commands.o -o devpkg
/tmp/cczC53x5.o: In function `main':
/home/yotam/Dropbox/Development/C/devpkg/devpkg.c:14: undefined reference to `apr_pool_initialize'
/home/yotam/Dropbox/Development/C/devpkg/devpkg.c:15: undefined reference to `apr_pool_create_ex'
/home/yotam/Dropbox/Development/C/devpkg/devpkg.c:29: undefined reference to `apr_getopt_init'
/home/yotam/Dropbox/Development/C/devpkg/devpkg.c:31: undefined reference to `apr_getopt'
db.o: In function `DB_init':
/home/yotam/Development/C/devpkg/db.c:89: undefined reference to `apr_pool_initialize'
/home/yotam/Development/C/devpkg/db.c:90: undefined reference to `apr_pool_create_ex'
/home/yotam/Development/C/devpkg/db.c:93: undefined reference to `apr_dir_make_recursive'
/home/yotam/Development/C/devpkg/db.c:105: undefined reference to `apr_pool_destroy'
/home/yotam/Development/C/devpkg/db.c:109: undefined reference to `apr_pool_destroy'
shell.o: In function `Shell_exec':
/home/yotam/Development/C/devpkg/shell.c:16: undefined reference to `apr_pool_create_ex'
/home/yotam/Development/C/devpkg/shell.c:38: undefined reference to `apr_pool_destroy'
/home/yotam/Development/C/devpkg/shell.c:44: undefined reference to `apr_pool_destroy'
shell.o: In function `Shell_run':
/home/yotam/Development/C/devpkg/shell.c:55: undefined reference to `apr_procattr_create'
/home/yotam/Development/C/devpkg/shell.c:58: undefined reference to `apr_procattr_io_set'
/home/yotam/Development/C/devpkg/shell.c:62: undefined reference to `apr_procattr_dir_set'
/home/yotam/Development/C/devpkg/shell.c:65: undefined reference to `apr_procattr_cmdtype_set'
/home/yotam/Development/C/devpkg/shell.c:68: undefined reference to `apr_proc_create'
/home/yotam/Development/C/devpkg/shell.c:71: undefined reference to `apr_proc_wait'
commands.o: In function `Command_fetch':
/home/yotam/Development/C/devpkg/commands.c:44: undefined reference to `apr_uri_parse'
/home/yotam/Development/C/devpkg/commands.c:48: undefined reference to `apr_fnmatch'
/home/yotam/Development/C/devpkg/commands.c:51: undefined reference to `apr_fnmatch'
/home/yotam/Development/C/devpkg/commands.c:70: undefined reference to `apr_fnmatch'
/home/yotam/Development/C/devpkg/commands.c:78: undefined reference to `apr_dir_make_recursive'
/home/yotam/Development/C/devpkg/commands.c:84: undefined reference to `apr_fnmatch'
/home/yotam/Development/C/devpkg/commands.c:90: undefined reference to `apr_dir_make_recursive'
collect2: error: ld returned 1 exit status
make: *** [devpkg] Error 1
Here is my makefile, it should be able to compile on different computers, where the PREFIX variable is the location relative to the computer.
(this program in essence should one day be portable to any OS. for now I would just like to be able to compile it successfully)
PREFIX?=/usr/local
LDFLAGS= -L${PREFIX}/apr/lib -L .aprutil-1 -L .apr-1
CFLAGS=-g -Wall -pthread -I${PREFIX}/apr/include/apr-1 -I${PREFIX}/apr/include/apr-util-1
all: devpkg
devpkg: bstrlib.o db.o shell.o commands.o
install: all \
install -d $(DESTDIR)/$(PREFIX)/bin/ \
install devpkg $(DESTDIR)/$(PREFIX)/bin/
clean:
rm -f *.o \
rm -f devpkg \
rm -rf *.dSYM
I've gone and searched for it myself in the folders and this is what I got:
yotam#yotam-HP-ProBook-450://usr$ grep -r apr_pool_initialize .
./local/apr/include/apr-1/apr_pools.h:APR_DECLARE(apr_status_t) apr_pool_initialize(void);
Binary file ./local/apr/lib/libapr-1.so.0.4.6 matches
Binary file ./local/apr/lib/libapr-1.a matches
Binary file ./local/apr/lib/libapr-1.so.0.5.1 matches
Binary file ./local/apr/lib/libapr-1.so.0.4.5 matches
./local/apr/lib/apr.exp:apr_pool_initialize
After the reaserch I did, I clearly understand that this is a linker problem. but I wasn't able to find the command to do the trick.
Thanks in advance.
Looks like you're missing the link option that tells cc which library to link with. I'm not sure what .aprutil-1 and .apr-1 are in your LDFLAGS macro, since you specify them with -L, I will assume they are directories.
However, if you change your line to add the -l option to specify the library, it should get you closer.
EDIT: Because the linker is a single pass tool, all the libraries need to be listed after the objects, so the symbols will not be optimized away. LDLIBS is a typical name for the macro where libraries are specified, and you can tack them on to the end of the compile/link command and it should work.
LDFLAGS= -L${PREFIX}/apr/lib -L .aprutil-1 -L .apr-1
LDLIBS= -lapr-1 -laprutil-1
The last two args tell the linker which library names (prepended with lib and appended with .a) to use. The -L option specifies additional directories to search for libraries, it doesn't actually include anything.
Alternatively, you can also set LD_LIBRARY_PATH to point to your library directories.
You can consult this site (among others) as a reference, if you need more help debugging.
Try replacing LDFLAGS with LDLIBS, as in:
LDLIBS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
instead of:
LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
This is because the LDFLAGS variable is meant for non-library options for the linker, whereas in this case you are using libraries.

"undefined reference" even the lib has a symbol of the function

When i linked the .o files,some problems happened:
gcc -L/usr/local/apr/lib -lapr-1 -pthread -laprutil-1 devpkg.o bstrlib.o db.o shell.o commands.o -o devpkg
devpkg.o: In function `main':
/root/workspace/devpkg/devpkg.c:21: undefined reference to `apr_pool_initialize'
/root/workspace/devpkg/devpkg.c:22: undefined reference to `apr_pool_create_ex'
/root/workspace/devpkg/devpkg.c:36: undefined reference to `apr_getopt_init'
/root/workspace/devpkg/devpkg.c:38: undefined reference to `apr_getopt'
I used "objdump -T" to check the lib,it returned:
objdump -T libapr-1.so|grep apr_pool_initialize
000000000001db00 g DF .text 00000000000000fb Base apr_pool_initialize
Why did this happen?
This is most likely just a simple dependency issue. You might want to try listing all the libraries you link to after the .o files, in the right order based on their dependencies with one another.

undefined reference to curl_global_init, curl_easy_init and other function(C)

I am trying to use Curl in C.
I visited Curl official page, and copied sample source code.
below is the link:
http://curl.haxx.se/libcurl/c/sepheaders.html
when I run this code with command "gcc test.c",
the console shows message like below.
/tmp/cc1vsivQ.o: In function `main':
test.c:(.text+0xe1): undefined reference to `curl_global_init'
test.c:(.text+0xe6): undefined reference to `curl_easy_init'
test.c:(.text+0x10c): undefined reference to `curl_easy_setopt'
test.c:(.text+0x12e): undefined reference to `curl_easy_setopt'
test.c:(.text+0x150): undefined reference to `curl_easy_setopt'
test.c:(.text+0x17e): undefined reference to `curl_easy_cleanup'
test.c:(.text+0x1b3): undefined reference to `curl_easy_cleanup'
test.c:(.text+0x1db): undefined reference to `curl_easy_setopt'
test.c:(.text+0x1e7): undefined reference to `curl_easy_perform'
test.c:(.text+0x1ff): undefined reference to `curl_easy_cleanup'
I do not know how to solve this.
You don't link with the library.
When using an external library you must link with it:
$ gcc test.c -lcurl
The last option tells GCC to link (-l) with the library curl.
In addition to Joachim Pileborg's answer, it is useful to remember that gcc/g++ linking is sensitive to order and that your linked libraries must follow the things that depend upon them.
$ gcc -lcurl test.c
will fail, missing the same symbols as before. I mention this because I came to this page for forgetting this fact.
I have the same problem, but i use g++ with a make file.
This is a linker issue.
You need to add option -lcurl on the compiler and on the linker.
In my case on the make file:
CC ?= gcc
CXX ?= g++
CXXFLAGS += -I ../src/ -I ./ -DLINUX -lcurl <- compile option
LDFLAGS += -lrt -lpthread -lcurl <- linker option
Gerard
Depending how bad things are you might need an -L/somewhere in LDFLAGS to let the linker know where the libraries are. ldconfig is supposed to pick them up and find them on every boot but on a new machine it can take a little prodding, like adding a directory to your /etc/ld.so.conf.

MinGW undefined reference to malloc, free, sprintf, _beginthreadex

I'm using MinGW. I have some code which calls malloc and a few other general purpose functions. When I type:
gcc TestCode.c
I get an a.exe file, it works perfect, and I don't get any warnings.
If I type this:
gcc -c TestCode.c -o TestCode.o
ld *.o
I get a whole bunch of warnings such as:
TestCode.o:TestCode.c:(.text+0xa): undefined reference to `__main'
TestCode.o:TestCode:(.text+0x2e): undefined reference to `printf'
TestCode.o:TestCode:(.text+0x42): undefined reference to `_strerror'
TestCode.o:TestCode:(.text+0x69): undefined reference to `snprintf'
TestCode.o:TestCode:(.text+0x7e): undefined reference to `malloc'
TestCode.o:TestCode:(.text+0x93): undefined reference to `_strerror'
TestCode.o:TestCode:(.text+0xb1): undefined reference to `sprintf'
TestCode.o:TestCode:(.text+0xcf): undefined reference to `free'
I'm assuming this is an issue with how I'm calling the linker. As such, I'll only post the code if it isn't clear what the problem is. I'm hoping this is an easy fix and that I simply forgot to include some super obvious library when linking.
It appears that your ld doesn't link any libraries by default. From your error messages, it looks like you need at least the C runtime and libc. Use gcc to link to get some handy defaults linked in for you:
gcc -c TestCode.c -o TestCode.o
gcc *.o
If you really want to use ld directly, you're going to need to figure out the names of your C runtime library and libc. For example (assuming libraries named libcrt and libc):
ld *.o -lcrt -lc
As Carl Norum said, you can pass object files to gcc and it'll know it doesn't need to compile them - it just passes them on to the linker (whether or not you're compiling other source files in the same invocation).
And you should probably do that because there's a fair amount of detail that goes into linking in the CRT and windows support libraries (unless you have a very specific need to not use the default runtime). My current MinGW setup links in the following items along with my object files:
crt2.o
crtbegin.o
-ladvapi32
-lshell32
-luser32
-lkernel32
-lmingw32
-lgcc
-lmoldname
-lmingwex
-lmsvcrt
crtend.o
Use the --verbose option to see how gcc links for you.

Resources