我有一个程序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}}这个问题的常见原因。)
有人可以帮我理解这里发生了什么吗?
答案 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作为中间步骤。