便利库中的符号未在可执行文件中导出

时间:2010-11-14 01:58:08

标签: linux gcc linker autotools

我有一个程序myprogram,它与静态便捷库链接,称之为libconvenience.a,其中包含一个函数func()。函数func()不会在myprogram中的任何位置调用;它需要能够从插件库plugin.so调用。

符号func()未在myprogram中动态导出。如果我跑

nm myprogram | grep func

我一无所获。但是,libconvenience.a

并未遗漏
  

nm libconvenience/libconvenience.a | grep func
  00000000 T func

我正在使用automake,但是如果我在命令行上手动执行最后一个链接步骤,它也不起作用:

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries`

但是,如果我链接这样的程序,跳过使用便利库并链接直接进入libconvenience.a的目标文件,func()会显示在myprogram中它的符号应该是:

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries`

如果我在func()的某处向myprogram添加虚拟来电,则func()也会显示在myprogram的符号中。但我认为--export-dynamic应该导出所有符号,无论它们是否在程序中使用过!

我在Fedora 14上使用的是automake 1.11.1和gcc 4.5.1。我也使用Libtool 2.2.10来构建plugin.so(但不是便利库。)

我没有忘记将-Wl,--export-dynamic放在myprogram_LDFLAGS中,也没有忘记将包含func()的来源放在libconvenience_a_SOURCES中(有些Google搜索表明这些是{{1}}这个问题的常见原因。)

有人可以帮我理解这里发生了什么吗?

2 个答案:

答案 0 :(得分:4)

我设法解决了这个问题。正是约翰卡尔科特出色的Autotools书中的这篇笔记指出了我正确的方向:

  

链接器将在命令行中显式指定的每个目标文件添加到二进制产品中,但它们只从归档中提取那些在链接的代码中实际引用的目标文件。

要抵消此行为,可以将--whole-archive标志用于libtool。但是,这会导致所有系统库中的所有符号也被拉入,从而导致大量双符号定义错误。因此--whole-archive需要在链接器命令行上libconvenience.a之前,并且需要--no-whole-archive后跟{...}},以便其他库不会被这样处理。这有点困难,因为automake和libtool并不能保证在命令行上保持标志的顺序相同,但Makefile.am中的这一行做了诀窍:

myprogram_LDFLAGS = -Wl,--export-dynamic \
    -Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive

答案 1 :(得分:0)

如果你需要func在plugin.so中,你应该尝试在那里找到它。便利库就是这样 - 方便链接到可执行文件或lib作为中间步骤。