如何使用Bazel从仅头文件代码构建含有效符号的.so共享库
问题根本原因
核心是Bazel cc_binary 规则的默认链接逻辑和你要打独立共享库的场景不匹配:
cc_binary(linkshared=1)的设计初衷是给当前规则srcs内源文件编译出的目标代码打共享库,只有srcs直接生成的.pic.o文件会被强制链接进最终so;所有deps里的依赖目标,Bazel默认会用--start-lib/--end-lib参数包裹传给链接器——这对参数的作用是:仅当包裹内的目标文件能解决当前链接阶段已存在的未定义符号时,才会把对应目标文件的代码段加入最终产物,否则直接丢弃。- 你的
srcs里只列了头文件,Bazel不会为.h头文件单独生成编译单元和目标文件,整个链接阶段没有任何来自当前规则的未定义符号,所有依赖里的.pic.o文件全被链接器丢弃,最终生成的.so自然是空壳,没有任何有效符号和代码。 - 之前加
linkstatic参数无效是正常的:这个参数仅控制依赖库优先用静态还是动态链接方式,不会改变「依赖目标默认按需链接、无未定义符号就丢弃」的逻辑。 - 你观察到的gcc命令参数不是gcc本身的问题,就是Bazel给
cc_binary默认拼接的链接参数,专门做可执行文件的按需链接优化,只是不适合你要把所有依赖全打包进一个独立so的场景。
这个规则是Bazel后续版本专门为产出可独立分发、供非Bazel项目依赖的共享库设计的,就是为了补上之前cc_binary(linkshared=1)的各种功能短板,不会出现依赖代码被意外丢弃的问题。
具体配置步骤
- 第一步:先建一个聚合用的
cc_library规则,把所有要打包进so的公共头文件、框架依赖都收拢到这个规则下:
cc_library( name = "dp_lib_aggregate", srcs = [ # 新建一个export.c文件放在同目录,内容仅为#include所有你要对外暴露的公共头文件即可,不需要写额外逻辑 # 这个文件用来确保头文件里的inline函数、模板实现都被正确编译生成目标代码,不会被编译器优化丢弃 "export.c", ], hdrs = [ # 列所有你要对外暴露的框架公共头文件,比如你之前提到的header1.h、header2.h ], deps = [ # 列所有Google差分隐私框架的依赖项,就是你之前写在cc_binary deps里的内容 "//framwork:dependency1", # ... 其他依赖 ], # 关键配置:强制该库及所有传递依赖的目标文件都参与链接,不被按需逻辑丢弃 alwayslink = True, visibility = ["//visibility:private"], )
- 第二步:基于上面的聚合库,配置
cc_shared_library规则生成最终so:
cc_shared_library( name = "differential_privacy", # 把聚合库设为root,root包含的所有代码、传递依赖都会被正确打包进so roots = [":dp_lib_aggregate"], # 首次构建建议开这个参数,强制导出库内所有符号,避免你要调用的接口被链接器优化掉 # 后续如果要裁剪so体积,可以换成自定义的符号导出过滤规则 export_all_symbols = True, visibility = ["//visibility:public"], )
注意name字段不用手动加lib前缀和.so后缀,Bazel会根据当前操作系统自动补全正确的共享库命名,Linux下会自动生成libdifferential_privacy.so,macOS下会自动生成libdifferential_privacy.dylib,跨平台兼容不用手动改。
- 配置完成后直接执行构建命令即可:
bazel build //path/to/your/build:differential_privacy,生成的共享库在bazel-bin对应目录下,所有依赖的代码都会被正确打包进去,可以直接给非Bazel项目链接使用。
如果暂时因为版本限制用不了cc_shared_library,可以在原来的cc_binary规则里做两个修改:
- 在
srcs里加一个export.c文件,把所有要对外暴露的头文件都include进去,给链接阶段提供基础编译单元。 - 在
linkopts里加整库链接参数:linkopts = ["-Wl,--whole-archive"],强制所有依赖的目标文件都被链接进so,不被--start-lib/--end-lib丢弃。
这个方案容易踩链接顺序、系统库重复链接的坑,只适合临时验证用,长期使用还是推荐cc_shared_library方案。
内容的提问来源于stack exchange,提问作者LRE
相关产品推荐
相关产品推荐

