我的主要可执行文件链接到一个静态库,该静态库的符号需要可用于通过dlopen((加载的动态库。我知道我需要使用-Wl,--export-dynamic,--whole-archive
标志来使它工作。然而,link命令中指定了许多库,有些可能未使用,并且我很难在当前构建基础结构中通过cmake将--whole-archive
选择性地应用于所需的库。我看到的是,如果只使用-Wl,--export-dynamic
,并且可执行文件调用感兴趣的静态库中的一个函数,那么整个库就会被包括在内,就像为它指定--whole-archive
一样,这正是我所需要的。我可以依靠这种行为将整个归档隐式地强加给其符号被可执行文件引用的库吗?
我看到的是,如果只使用-Wl,--export dynamic,并且可执行文件调用感兴趣的静态库中的一个函数,那么整个库就会被包括在内,就像为它指定--whole archive一样,这正是我所需要的。
这是不应该发生的,很可能你误解了你所看到的。
示例:
// foo.c
int foo() { return 42; }
// bar.c
int bar() { return 24; }
// main.c
int main() { return foo() - 42; }
gcc -w -c foo.c bar.c main.c
ar ruv libfoobar.a foo.o bar.o
gcc -Wl,--export-dynamic main.o -L. -lfoobar
nm a.out | egrep ' (foo|bar)'
000000000000113c T foo
正如您所看到的,整个libfoobar.a
是而不是包含在可执行文件中。对比:
gcc -Wl,--export-dynamic main.o -L. -Wl,--whole-archive -lfoobar -Wl,--no-whole-archive
nm a.out | egrep ' (foo|bar)'
0000000000001147 T bar
000000000000113c T foo
更新:
如果我将函数
foo1()
添加到foo.c
,它会被拉入,但无论是否提供--export-dynamic
,它也会发生。
这是意料之中的:链接器不会"分割";一个单独的.o
文件——要么全部得到,要么什么都没有得到。
您可以通过在编译时使用-ffunction-sections
(和-fdata-sections
作为衡量标准(和在链接时使用-Wl,--gc-sections
来更改此行为。
成本增加了.o
的大小和更长的链路时间。好处是可执行性较小。