我有一个程序,myprogram,它与一个静态便利库链接,称之为libconvenience.a,它包含一个函数func().在myprogram中的任何地方都不调用函数func();它需要能够从插件库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`
如果我在myprogram中的某处向func()添加一个虚拟调用,那么func()也会显示在myprogram的符号中.但我认为–export-dynamic应该导出所有符号,无论它们是否在程序中使用过!
我在Fedora 14上使用automake 1.11.1和gcc 4.5.1.我也使用Libtool 2.2.10来构建plugin.so(但不是便利库.)
我没有忘记在myprogram_LDFLAGS中放置-Wl,– export-dynamic,也没有忘记在libconvenience_a_SOURCES中放置包含func()的源代码(一些Google搜索表明这些是导致此问题的常见原因.)
有人可以帮我理解这里发生了什么吗?
Linkers add to the binary product every object file specified explicitly on the command line,but they only extract from archives those object files that are actually referenced in the code being linked.
要抵消这种行为,可以将–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