You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过版本脚本让ld剥离本地符号,避免单独执行strip?

问题:使用GCC编译共享库时,如何通过ld直接剥离本地符号(无需单独strip)

我用GCC编译共享ELF库时,添加了-Wl,--version-script=version.script参数,版本脚本内容如下:

MYLIB_1.0 {
    global:
        the_only_symbol_i_want;
    local:
        *;
};

该配置已达到预期效果:仅the_only_symbol_i_want被导出为全局符号,其余所有符号均为本地符号。

但我还希望直接剥离这些本地符号。查阅ld手册得知可使用-Wl,--discard-all参数,尽管该参数命名不够准确,文档说明它实际是丢弃所有本地符号而非全部符号,但将其与--version-script配合使用时,完全没有效果。

单独执行strip --discard-all mylib.so可以实现需求,但我希望避免单独运行strip命令。请问是否有办法让ld直接实现该需求?版本脚本是否支持discard:选项?


解决方案

1. 版本脚本的discard:选项可直接实现需求

你可以在版本脚本中添加discard:段来丢弃不需要的符号,无需额外的--discard-all参数。修改后的版本脚本如下:

MYLIB_1.0 {
    global:
        the_only_symbol_i_want;
    local:
        *;
};

discard {
    *;
};

这个脚本会先将除指定全局符号外的所有符号标记为本地,再直接丢弃所有剩余的本地符号。编译时只需保留-Wl,--version-script=version.script参数即可,无需添加--discard-all。

2. 解释--discard-all与版本脚本配合无效的原因

当你通过版本脚本将符号标记为local:后,这些符号会被归类为本地符号,但ld的--discard-all仅会丢弃未被引用的本地符号,而非所有本地符号。如果你的本地符号之间存在相互引用,ld就不会丢弃它们,这就是为何看起来没有效果。而strip --discard-all是直接移除所有本地符号,无论是否被引用,这与ld的--discard-all行为存在本质区别。

3. 验证方法

编译完成后,可通过readelf -s mylib.so查看符号表,确认仅the_only_symbol_i_want存在,其余本地符号已被丢弃。

内容的提问来源于stack exchange,提问作者Timmmm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:37:07