我有一个myprogram与静态便利库链接的程序,称为它libconvenience.a,其中包含一个函数func()。该函数func()未在中的任何地方调用myprogram;它需要能够从插件库调用plugin.so。
myprogram
libconvenience.a
func()
plugin.so
该符号func()未在中动态导出myprogram。如果我跑步
nm myprogram | grep func
我什么都没有。但是,它并不缺少libconvenience.a:
nm libconvenience/libconvenience.a | grep func 00000000 T功能
nm libconvenience/libconvenience.a | grep 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应该导出所有符号,而不管程序中是否使用了它们!
--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(谷歌搜索的一些建议,这些都是这个问题的常见原因。)
-Wl,--export- dynamic
myprogram_LDFLAGS
libconvenience_a_SOURCES
有人可以帮我了解这里发生了什么吗?
我设法解决了。约翰·卡索特(John Calcote)出色的《自动工具》(Autotools)书中的这条注释为我指明了正确的方向:
链接器将在命令行上显式指定的每个目标文件添加到二进制产品中,但是它们仅从归档中提取在链接的代码中实际引用的那些目标文件。
要抵消这种行为,可以使用该--whole- archive标志来libtool。但是,这也会导致从所有系统库中提取所有符号,从而导致许多双重符号定义错误。因此,--whole- archive需要libconvenience.a在链接器命令行上紧接其前,并且紧随其后,--no-whole- archive以免其他库受到这种对待。这有点困难,因为automake和libtool不能真正保证在命令行上将标志保持相同的顺序,但是这一行Makefile.am起到了作用:
--whole- archive
--no-whole- archive
Makefile.am
myprogram_LDFLAGS = -Wl,--export-dynamic \ -Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive