我正在创建一个共享库,我注意到使用 __attribute__((visibility("default")))
(连同 -fvisibility=hidden
)我的图书馆也导出 _init
和 _fini
符号。如果我使用 exported_symbols 列表(连同 -Wl,--version-script=<file_list>
),lib 只导出我的函数,这是完美的。
是否可以使用第一个解决方案并仅导出我的函数,而不使用 _init
和 _fini
?谢谢
最佳答案
首先,问题不仅限于 _init
和 _fini
- GNU 工具链默认导出其他无用的符号,例如_edata
等。这些符号确实是完全不需要的(动态链接器通过不同的方式获得指向ctors/dtors的指针)。
我最近已将此问题报告给 gcc-help和 Binutils列出。 Bintools 列表中的回复是,虽然这些符号在 Linux 系统上确实没有使用,但删除它们必须非常小心,需要大量测试,性能提升可以忽略不计。我没有在 gcc-help 中得到答案(在 gcc 开发人员列表中重新发布可能有意义)。
作为解决方法,您可以通过版本脚本显式隐藏不需要的符号:
$ cat myapp.version
{
global: XML_*; _INTERNAL_*;
local: *;
};
$ cat Makefile
...
LDFLAGS += -Wl,--version-script=myapp.version
可以找到 Expat 项目的示例 here .这种方法的一个问题(除了将样板添加到所有项目而不是在 Binutils/GCC 中一次修复它之外)是很难使用 Autoconf 使其正确。
请注意,即使您使用版本脚本,您仍然需要使用 -fvisibility=hidden
进行编译(它允许编译器对隐藏符号执行更积极的优化,而在版本脚本的情况下,编译器不知道最终隐藏了什么)。
关于c++ - 在共享库中隐藏 "_init"和 "_fini"符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50660881/