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.
Advertisement
Answer
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.