Bazel自定义cc_static_library规则如何从工具链获取ar命令替代硬编码
解决方法
你需要给自定义规则绑定C++工具链,直接从当前生效的工具链实例中读取ar程序路径即可替换硬编码路径,修改后的完整规则如下:
load("@rules_cc//cc:defs.bzl", "CcInfo") def _cc_static_library_impl(ctx): # 获取当前配置的C++工具链实例 cc_toolchain = ctx.toolchains["@rules_cc//cc:toolchain_type"].cc_toolchain cc_deps = [dep[CcInfo] for dep in ctx.attr.deps] libraries = [] for cc_dep in cc_deps: for link_input in cc_dep.linking_context.linker_inputs.to_list(): for library in link_input.libraries: libraries += library.pic_objects args = ["r", ctx.outputs.out.path] + [f.path for f in libraries] ctx.actions.run( # 把ar程序的运行依赖加入输入,避免沙箱环境找不到执行文件 inputs = libraries + cc_toolchain.all_files.to_list(), outputs = [ctx.outputs.out], # 替换硬编码路径,使用工具链提供的ar程序 executable = cc_toolchain.ar_executable, arguments = args, ) return [DefaultInfo()] cc_static_library = rule( implementation = _cc_static_library_impl, attrs = { "deps": attr.label_list(providers = [CcInfo]), }, outputs = {"out": "lib%{name}.a"}, # 声明规则依赖C++工具链,Bazel会自动匹配当前平台配置的工具链 toolchains = ["@rules_cc//cc:toolchain_type"], )
核心修改逻辑说明:
- 给rule定义新增
toolchains字段,声明该规则需要依赖C++工具链,构建时Bazel会自动根据当前平台、编译配置选择适配的工具链 - 实现函数中直接从工具链实例读取
ar_executable字段,就是当前工具链配置的归档程序路径,不需要手动硬编码 - 新增工具链依赖文件到动作输入列表,保证沙箱环境可以正常调用ar程序
修改后规则会自动适配不同平台的工具链,跨平台编译、切换自定义工具链时都不需要再修改规则本身。
内容的提问来源于stack exchange,提问作者user2672165
相关产品推荐
相关产品推荐

