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

pto*_*ato 7 linux linker gcc autotools

我有一个程序,myprogram它与一个静态便利库链接,调用它libconvenience.a,它包含一个函数,func().该函数func()不会在任何地方调用myprogram; 它需要能够从插件库中调用plugin.so.

该符号func()未动态导出myprogram.如果我跑

nm myprogram | grep func
Run Code Online (Sandbox Code Playgroud)

我一无所获.但是,它不会遗漏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`
Run Code Online (Sandbox Code Playgroud)

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

gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries`
Run Code Online (Sandbox Code Playgroud)

如果我在func()某处添加一个虚拟调用myprogram,那么func()也会显示在myprogram符号中.但我认为--export-dynamic应该导出所有符号,无论它们是否在程序中使用过!

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

我没有忘记把-Wl,--export-dynamicmyprogram_LDFLAGS,我也没有忘记把包含源func()libconvenience_a_SOURCES(谷歌搜索的一些建议,这些都是这个问题的常见原因.)

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

pto*_*ato 7

我设法解决了它。正是约翰·卡尔科特 (John Calcote) 出色的 Autotools 书中的注释为我指明了正确的方向:

链接器将命令行上明确指定的每个目标文件添加到二进制产品中,但它们仅从存档中提取被链接的代码中实际引用的目标文件。

为了抵消这种行为,可以使用--whole-archivelibtool的标志。但是,这会导致所有系统库中的所有符号也被拉入,从而导致大量双重符号定义错误。所以--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
Run Code Online (Sandbox Code Playgroud)