我正在构建一个C ++可执行文件。我正在静态链接我正在使用的几个C和C ++库,包括一个自定义库。 (但是,我不是静态链接我正在使用的每个库。)
即使考虑到这一点,可执行文件似乎异常大。我使用了objdump -h
,它告诉我在.dynstr
中使用的空间远远超出预期。我使用-Os
编译并运行strip
,但是当我运行
$ readelf -p .dynstr slamshift
我收到很多像
这样的条目 [ 13588] _ZN3yuu6windowC2Ev
[ 1359b] _ZTSN3yuu7gfx_ctxE
[ 135ae] _ZN4YAML7Scanner11ScanFlowEndEv
[ 135ce] __glewVertexFormatNV
我已静态链接的库中的符号(我自己的库,yaml-cpp和GLEW)。
为什么这些符号出现在我的可执行文件中?如果我已经静态链接了所涉及的库,那么符号名称不应该是不必要的吗?
我正在使用Ubuntu 12.04,GCC 4.6.3和CMake及其默认设置来构建,如果这些是相关的。
答案 0 :(得分:4)
为什么这些符号出现在我的可执行文件中?
从可执行文件导出这些符号只有两个原因,并显示在动态符号表中。
--export-dynamic
(又名-E
)链接器标记或如果您正在做#1,答案很简单:不要这样做。
如果您输入了因#2而导出的符号,那么您确实希望导出符号,否则代码可能会在其他地方失败。
答案 1 :(得分:1)
一个鲜为人知的事实是,使用dl_open和朋友可以将ELF可执行文件作为动态对象打开。要使它工作,他们需要有符号导出。我认为这就是这里发生的事情。
您可以尝试使用--exclude-libs ALL
向链接器执行最终程序链接。它在gcc命令行上看起来像-Wl,--exclude-libs ALL
更新:这会导致符号仍然存在,但会标记为隐藏。
您也可以尝试-Wl,--exclude-all-symbols
更新:我错了。它仅适用于PE目标。
我试过这个并且它起作用了:
gcc -static -Wl,-s export-test.c