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

如何强制Bazel构建可合并多个cc_library的单归档产物目标

Bazel合并多个静态库为单个归档的解决方案

问题原因

原生cc_library规则不会将依赖的其他静态库合并到自身的归档产物中,你声明在srcs中的:lib1、:lib2只会作为传递链接标识存在:

  • 单独构建release-lib时,Bazel仅会完成依赖检查,不会生成对应的静态库文件
  • 只有当上层cc_binary依赖release-lib时,Bazel才会将lib1、lib2的归档传递给链接器参与二进制生成

解决方案

你可以通过genrule手动调用ar工具实现多静态库合并,BUILD配置示例如下:

cc_library(
    name = "lib1",
    srcs = ["src1.c"]
)

cc_library(
    name = "lib2",
    srcs = ["src2.c"]
)

genrule(
    name = "release-lib",
    # 填入所有需要合并的静态库目标
    srcs = [
        ":lib1",
        ":lib2",
    ],
    # 声明输出的合并归档文件名
    outs = ["librelease.a"],
    cmd = """
        # 创建临时目录避免不同库的同名.o文件冲突
        temp_dir=$$(mktemp -d)
        for lib in $(SRCS); do
            lib_name=$$(basename $$lib .a)
            mkdir -p $$temp_dir/$$lib_name
            # 提取单个库的所有目标文件
            cd $$temp_dir/$$lib_name && $$(dirname $(AR))/ar x $$(realpath $$lib) && cd -
        done
        # 将所有提取出的目标文件打包为新的静态库
        $(AR) rcs $@ $$temp_dir/*/*.o
        # 清理临时文件
        rm -rf $$temp_dir
    """,
    # 依赖C++工具链的ar命令
    tools = ["@bazel_tools//tools/cpp:current_cc_toolchain"],
    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
    visibility = ["//visibility:public"],
)

执行构建命令后就可以在bazel-out目录下找到生成的librelease.a:
bazel build //:release-lib

补充说明

如果你需要对外暴露合并库的头文件,可以额外新增一个cc_library统一管理导出头文件:

cc_library(
    name = "release-lib-headers",
    # 填入所有需要对外暴露的头文件路径
    hdrs = glob([
        "lib1/include/**/*.h",
        "lib2/include/**/*.h",
    ]),
    visibility = ["//visibility:public"],
)

其他目标需要依赖该合并库时,同时依赖release-lib和release-lib-headers即可正常编译链接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:27:07