链接无法找到符号,但读取库并存在符号

Ben*_*all 6 linux g++ ld shared-objects

我一直在努力编译我的项目而且我遇到了undefined reference错误.例如.:

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'
...
Run Code Online (Sandbox Code Playgroud)

我的命令行是:

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
Run Code Online (Sandbox Code Playgroud)

objdump -T显示符号位于.so文件中.例如.:

libsybdb.so:
...
0000000000011c30 g    DF .text  0000000000000083  Base        dbcancel
...

/usr/lib/libxmlrpc_cpp.so:
...
0000000000002e78 g    DF .text  0000000000000092  Base        _ZN11XmlRpcValue9makeArrayEv
...
Run Code Online (Sandbox Code Playgroud)

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
...
Run Code Online (Sandbox Code Playgroud)

涉及的所有文件都针对x86-64,C库的标头是extern "C".我已经尝试了我能想到的一切,它仍然无法链接.

我甚至尝试删除所有C++ 11代码并在没有命令行开关的情况下进行编译,但仍然没有.

我的系统是Ubuntu Precise(12.04)64位使用g ++(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3如果有帮助的话.所有软件包都是从软件包管理器安装的,并且安装了开发包.

编辑(2017-05-30):标记为/sf/ask/3159481/的副本-gcc
其他问题询问为什么参数的顺序很重要.当问到问题时,参数顺序不是一个问题.
此外,之前的问题不包含任何有用的扩展,而这个问题显示了手头的问题.
以前的问题可能被视为对这个问题的答案的有益扩展,但不是重复.

小智 11

你必须把图书馆的连接标志的目标文件.所以,而不是

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
Run Code Online (Sandbox Code Playgroud)

使用

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
Run Code Online (Sandbox Code Playgroud)

  • 刚刚正确尝试,成功了。真的吗!?不敢相信事情就这么简单。 (2认同)
  • 对于遇到这个问题的其他人来说,这就是推理.似乎gcc现在将链接器标志--as-needed发送到ld.这具有丢弃任何没有链接所需符号的指定库的效果.在第一种情况下,由于在链接阶段没有未解析的符号,所有库都被丢弃,因此无法找到符号.在第二个实例中,ld收集了未解析的符号列表,然后在指定的库中找到它们,因此在实际链接阶段保留它们. (2认同)