使用Bazel构建共享库时未包含全部依赖符号的问题问询
问题根因
你遇到的符号缺失是两个常见原因共同导致的:
- 链接器默认会剔除未被当前共享库代码直接引用的依赖符号,你的
cc_binary没有任何自有源文件,没有代码引用MyClass,链接器默认直接丢弃该类相关符号 - 你构建命令里添加的
--linkopt="-s"参数会执行strip操作,删除所有符号表内容,也会导致你无法通过nm命令查找到对应符号
解决方案
按优先级推荐以下几种方案:
方案1:给依赖库添加alwayslink属性(最便捷)
直接修改依赖的cc_library配置,添加alwayslink = 1参数,强制链接器保留该库的所有符号,无需修改其他配置:
cc_library( name = "dependency", srcs = ["file.cc"], hdrs = ["file.h"], alwayslink = 1, # 新增此行 )
方案2:显式指定链接时保留全部依赖符号
如果不想修改依赖库配置,可以在共享库的构建配置中通过链接参数强制保留符号:
cc_binary( name = "library.so", deps = ["//project:dependency"], linkshared = 1, linkopts = [ "-Wl,--whole-archive", "-l:libdependency.a", "-Wl,--no-whole-archive", "-fvisibility=default", # 强制符号默认可见 ], )
方案3:通过版本脚本按需导出符号
如果只需要导出特定符号(比如仅MyClass相关符号),可以编写符号导出脚本减少库体积:
- 新建
export_symbols.map文件,内容如下:
{ global: MyClass*; local: *; };
- 修改共享库构建配置引用该脚本:
cc_binary( name = "library.so", deps = ["//project:dependency"], linkshared = 1, linkopts = ["-Wl,--version-script=$(location :export_symbols.map)"], data = [":export_symbols.map"], )
验证注意事项
测试符号是否存在时,先去掉构建命令中的--linkopt="-s"参数,避免strip操作删除符号表,验证通过后如果需要裁剪库体积再加回该参数。
内容的提问来源于stack exchange,提问作者user654628
相关产品推荐
相关产品推荐

