Linux “链接”找不到符号,但已读取库且符号存在
我一直在试图编译我的项目,但我得到了Linux “链接”找不到符号,但已读取库且符号存在,linux,g++,ld,shared-objects,Linux,G++,Ld,Shared Objects,我一直在试图编译我的项目,但我得到了未定义的引用错误。例如: installertest.cpp:(.text+0x9d1): undefined reference to `XmlRpcValue::makeArray()' ... installertest.cpp:(.text+0xede): undefined reference to `dbcancel' installertest.cpp:(.text+0xefd): undefined reference to `dbfcmd'
未定义的引用
错误。例如:
installertest.cpp:(.text+0x9d1): undefined reference to `XmlRpcValue::makeArray()'
...
installertest.cpp:(.text+0xede): undefined reference to `dbcancel'
installertest.cpp:(.text+0xefd): undefined reference to `dbfcmd'
installertest.cpp:(.text+0xf0f): undefined reference to `dbsqlexec'
installertest.cpp:(.text+0xf2d): undefined reference to `SHA1_Init'
...
我的命令行是:
g++ -o installertest \
-lsybdb \
-lxmlrpc \
-lxmlrpc_cpp \
-lxmlrpc_xmlparse \
-lxmlrpc_xmltok \
-lxmlrpc_util \
-lxmlrpc++ \
-lxmlrpc_server_cgi \
-lssl \
-std=c++0x \
ContractData.o installertest.o
objdump-T
显示符号在.so文件中。例如:
libsybdb.so:
...
0000000000011c30 g DF .text 0000000000000083 Base dbcancel
...
/usr/lib/libxmlrpc_cpp.so:
...
0000000000002e78 g DF .text 0000000000000092 Base _ZN11XmlRpcValue9makeArrayEv
...
strace
显示链接器正在打开和读取库文件:
...
[pid 5019] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libsybdb.so", {st_mode=S_IFREG|0644, st_size=421608, ...}) = 0
[pid 5019] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libsybdb.so", O_RDONLY) = 7
[pid 5019] fcntl(7, F_GETFD) = 0
[pid 5019] fcntl(7, F_SETFD, FD_CLOEXEC) = 0
[pid 5019] fstat(7, {st_mode=S_IFREG|0644, st_size=421608, ...}) = 0
[pid 5019] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b16c200c000
[pid 5019] lseek(7, 0, SEEK_SET) = 0
[pid 5019] read(7, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\237\0\0\0\0\0\0"..., 4096) = 4096
...
[pid 5019] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libxmlrpc.so", {st_mode=S_IFREG|0644, st_size=80936, ...}) = 0
[pid 5019] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libxmlrpc.so", O_RDONLY) = 8
[pid 5019] fcntl(8, F_GETFD) = 0
[pid 5019] fcntl(8, F_SETFD, FD_CLOEXEC) = 0
[pid 5019] fstat(8, {st_mode=S_IFREG|0644, st_size=80936, ...}) = 0
[pid 5019] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b16c200d000
[pid 5019] lseek(8, 0, SEEK_SET) = 0
[pid 5019] read(8, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300?\0\0\0\0\0\0"..., 4096) = 4096
...
所有涉及的文件都是针对x86-64的,C库的头是extern“C”
。我已经尝试了我能想到的一切,但仍然无法链接
我甚至尝试过删除所有C++11代码并在没有命令行开关的情况下编译,但仍然一无所获
我的系统是使用g++(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3的64位Ubuntu Precise(12.04)。所有软件包都是从软件包管理器安装的,开发软件包也已安装
编辑(2017-05-30):标记为的副本
另一个问题是为什么争论的顺序很重要。当提出问题时,不知道参数顺序是一个问题。此外,前面的问题没有包含任何有用的扩展,而这个问题显示了当前的问题。
上一个问题可能被视为对本问题答案的有益扩展,但不是重复。您必须将库的链接器标志放在对象文件之后。因此,与其
g++ -o installertest \
-lsybdb \
-lxmlrpc \
-lxmlrpc_cpp \
-lxmlrpc_xmlparse \
-lxmlrpc_xmltok \
-lxmlrpc_util \
-lxmlrpc++ \
-lxmlrpc_server_cgi \
-lssl \
-std=c++0x \
ContractData.o installertest.o
使用
只是试过了,成功了。真正地真不敢相信事情会这么简单。对于其他任何一个遇到这个问题的人来说,这就是原因。似乎gcc现在会根据需要向ld发送链接器标志。这样做的效果是丢弃没有链接所需符号的任何指定库。在第一个实例中,由于没有未解析的符号,所有库都被丢弃,然后在链接阶段,无法找到符号。在第二个例子中,ld收集了未解析符号的列表,然后在指定的库中找到它们,因此在实际链接阶段保留它们。嗨,Ben。你能告诉我如何使用strace检查流程吗。我的主要困难是如何获得PID,因为编译过程很快就结束了。我只使用ps aux | grep获取PID,但进程已经死了。@XingWang,没问题。您只需在命令行前面加上“strace-f-e trace=all”。根据您的系统,您可能还需要添加“sudo”。因此,从我的示例中可以看出:“strace-f-e trace=all g++-o installertest ContractData.o installertest.o”…可能是
g++ -o installertest \
ContractData.o installertest.o \
-lsybdb \
-lxmlrpc \
-lxmlrpc_cpp \
-lxmlrpc_xmlparse \
-lxmlrpc_xmltok \
-lxmlrpc_util \
-lxmlrpc++ \
-lxmlrpc_server_cgi \
-lssl \
-std=c++0x