未定义的符号,即使是显式链接

时间:2012-08-08 22:37:22

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

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

我正在构建两个共享库:一个名为“libhttp”,它具有一些http协议的辅助函数,似乎正在构建好或坏。第二个叫做“libvpcutil”,它引起了问题。它取决于libhttp中的符号,所以我将它链接到libhttp。这是编译指令(从make文件中分解出来),其中有一些小问题,比如我的openssl generified的个人路径:

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中是未定义的。这会产生运行时错误。

有人看到了这个问题吗?

1 个答案:

答案 0 :(得分:1)

这看起来像预期的行为。

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

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

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