【问题标题】:Undefined Symbols even with explicit links未定义的符号,即使有明确的链接
【发布时间】:2012-08-08 22:37:21
【问题描述】:

过去一天一直在处理链接器地狱,我想我会把它扔在那里,看看是否有人可以帮助我。

我正在构建两个共享库:一个名为“libhttp”的共享库具有一些用于 http 协议的帮助函数,这似乎是在构建更好或更坏的协议。第二个称为“libvpcutil”,它导致了问题。它取决于 libhttp 中的符号,因此我将其链接到 libhttp。这是编译指令(从 make 文件中分解出来),其中包含一些小东西,比如我个人的 openssl 生成路径:

g++ -shared -Wl,-soname,libvpcutil.so.1 -o libvpcutil.so.1.0  vpcreg/registry.o \
vpcreg/vpcreg2.o  dbase/dbase.o dbase/sqlutils.o  diaglog/diaglog.o  errmsg/errmsg.o  \
faillib/faillib.o  failover/failover.o  initerr/init_err.o  kmq/kmq.o kmq/publish.o  \
kthread/kcom.o kthread/kthread.o  libobdi/odi_serv.o  mutex/mutex.o  netserv/netserv.o  \
newmem/newmem.o  rmtstore/avlmem.o rmtstore/rmtstore.o rmtstore/shm_aloc.o  \
servhand/servhand.o  timers/timers.o  vpcstamp/vpcstamp.o  websql/websql.o  types/blob.o \
types/hitime.o types/ticks.o types/timestamp.o  odasm/odasm.o  webvibapi/webvibapi.o  \
vibusfeed/vibusfeed.o  propstore/propstore2.o  cardlib/cardlib.o cardlib/sortlist.o  \
gapi/genapi.o -L/usr/lib/i386-linux-gnu -lm -lrt -lxml2 -lodbc -L/usr/lib/i386-linux-gnu -\
lcurl -Wl,-Bsymbolic-functions -Wl,-z,relro \
-L/pathtoopenssl/openssl -lssl -lcrypto  -lxml2   -lreadline -\
lcurses -Wl,-rpath=.:/pathtobin/bin http/libhttp.so.1.0 ../ddldata/ddldata.o 
../cardddl/cardddl.o ../gendata/generic.o

编译和链接成功完成。希望您注意到 http/libhttp.so.1.0 的链接步骤。

现在,如果我在 libhttp.so.1.0 上执行 nm,我会得到以下输出(以及其他输出):

00015d5a T _ZN12http_cookiesC1Ev
00015d5a T _ZN12http_cookiesC2Ev
00015d7e T _ZN12http_cookiesD1Ev
00015d7e T _ZN12http_cookiesD2Ev
00011574 T _ZN12http_headers11url_expressERSo
00011466 T _ZN12http_headers12http_expressERSo

但是当我在 libvpcutil.so.1.0 上运行 nm 时,我基本上得到:

     U _ZN12http_cookiesC1Ev
     U _ZN12http_cookiesD1Ev
     U _ZN12http_headers11url_expressERSo
     U _ZN12http_headers3setEPKcRKSs
     U _ZN12http_headers3setEPKcS1_
     U _ZN12http_headersC1Ev
     U _ZN12http_headersD1Ev

我显然在这里剪断,但我被困在这里的是符号在 libhttp 中明确定义,我为 libvpcutil 链接它,但随后符号在 libvpcutil 中未定义。这会产生运行时错误。

有人看到这个问题吗?

【问题讨论】:

  • 通常表示签名不匹配。检查声明、实现和调用函数的源代码(如果需要任何帮助,请将其放在这里)。
  • @littleadv,如果签名不匹配,错误将在运行前发生,您只需查看nm 输出即可查看它们是否匹配。跨度>
  • @JonathanWakely 我敢肯定我们正在寻找不同的东西。在问题中,您有两个nm 输出,其中列出了一堆具有重载参数的函数,并且只有一个与另一个配对。
  • @littleadv,我不清楚,我的意思是 OP 可以查看它们是否匹配,并说 “我显然在这里剪断,但我被困在这里的是符号在 libhttp" 中明确定义,所以我假设它们确实匹配,不需要检查代码,检查 nm 输出就足够了。真正的重点是符号 supposedlibvpcutil 中未定义,动态链接无法按照 OP 的预期方式工作。

标签: linux linker g++ shared-libraries undefined-symbol


【解决方案1】:

这看起来像预期的行为。

链接到共享库与链接到静态库不同,所需的符号不会被复制到输出文件中,您只需获得对仍必须在运行时解析的符号的引用。所以nm将符号显示为U是正常的。

什么是运行时错误?这可能意味着在运行时找不到libhttp.so.1.0 库。您应该能够在 libvpcutil.so 和可执行文件上运行 ldd,以查看它们是否依赖于 libhttp.so.1.0,以及它们是否找到了正确的。

libhttp.so.1.0 有设置 soname 吗?如果它与文件名不同,您是否有与 soname 同名的符号链接? (例如,如果 soname 是 libhttp.so.1,您将需要一个符号链接 libhttp.so.1 -> libhttp.so.1.0)。我还看到您的 libhttp.so.1.0 位于名为 http 的目录中,但它不在您的 RPATH 中,因此在运行时找不到。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2010-09-17
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多