Make 找不到函数
Make is unable to find the functions
我正在尝试编译 C 程序,同时链接 APR 库。
我收到以下错误消息:
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
这是我的makefile,应该可以在不同的电脑上编译,其中PREFIX
变量是相对于电脑的位置。
(这个程序本质上应该有一天可以移植到任何OS。现在我只想能够成功编译它)
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
我自己去文件夹里搜索了一下,结果是这样的:
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
经过我的研究,我清楚地知道这是一个链接器问题。但我找不到执行此操作的命令。
提前致谢。
看起来您缺少 link 选项,该选项告诉 cc
要 link 使用哪个库。我不确定你的 LDFLAGS
宏中的 .aprutil-1
和 .apr-1
是什么,因为你用 -L 指定它们,我会假设它们是目录。
但是,如果您更改您的行以添加 -l
选项来指定库,它应该会让您更接近。
编辑:因为 linker 是单通道工具,所有库都需要在 对象之后 列出,因此符号不会被优化掉. LDLIBS
是指定库的宏的典型名称,您可以将它们附加到 compile/link 命令的末尾,它应该可以工作。
LDFLAGS= -L${PREFIX}/apr/lib -L .aprutil-1 -L .apr-1
LDLIBS= -lapr-1 -laprutil-1
最后两个参数告诉 linker 哪些库名称(前缀为 lib 并附加 .a)使用。 -L
选项指定用于搜索库的其他目录,它实际上不包含任何内容。
或者,您也可以设置 LD_LIBRARY_PATH
指向您的库目录。
如果您需要更多帮助调试,您可以参考 this site(以及其他)作为参考。
尝试用 LDLIBS 替换 LDFLAGS,如:
LDLIBS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
而不是:
LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
这是因为 LDFLAGS 变量用于链接器的非库选项,而在本例中您使用的是库。
我正在尝试编译 C 程序,同时链接 APR 库。 我收到以下错误消息:
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
这是我的makefile,应该可以在不同的电脑上编译,其中PREFIX
变量是相对于电脑的位置。
(这个程序本质上应该有一天可以移植到任何OS。现在我只想能够成功编译它)
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
我自己去文件夹里搜索了一下,结果是这样的:
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
经过我的研究,我清楚地知道这是一个链接器问题。但我找不到执行此操作的命令。
提前致谢。
看起来您缺少 link 选项,该选项告诉 cc
要 link 使用哪个库。我不确定你的 LDFLAGS
宏中的 .aprutil-1
和 .apr-1
是什么,因为你用 -L 指定它们,我会假设它们是目录。
但是,如果您更改您的行以添加 -l
选项来指定库,它应该会让您更接近。
编辑:因为 linker 是单通道工具,所有库都需要在 对象之后 列出,因此符号不会被优化掉. LDLIBS
是指定库的宏的典型名称,您可以将它们附加到 compile/link 命令的末尾,它应该可以工作。
LDFLAGS= -L${PREFIX}/apr/lib -L .aprutil-1 -L .apr-1
LDLIBS= -lapr-1 -laprutil-1
最后两个参数告诉 linker 哪些库名称(前缀为 lib 并附加 .a)使用。 -L
选项指定用于搜索库的其他目录,它实际上不包含任何内容。
或者,您也可以设置 LD_LIBRARY_PATH
指向您的库目录。
如果您需要更多帮助调试,您可以参考 this site(以及其他)作为参考。
尝试用 LDLIBS 替换 LDFLAGS,如:
LDLIBS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
而不是:
LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
这是因为 LDFLAGS 变量用于链接器的非库选项,而在本例中您使用的是库。