在 bazel 规则中使用当前工具链
Use of current toolchain in bazel rule
我使用下面的 bazel 规则通过 bazel 构建静态库:
def _cc_static_library_impl(ctx):
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(
inputs = libraries,
outputs = [ctx.outputs.out],
executable = "/usr/bin/ar",
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"},
)
如何从当前工具链中提取要使用的命令,而不是使用硬编码 /usr/bin/ar
?我的规则基于我在互联网上找到的内容,对此我的了解非常有限。这个例子似乎做了一些相关的事情:
https://github.com/bazelbuild/rules_cc/blob/main/examples/my_c_archive/my_c_archive.bzl
这是my_c_archive
的相关部分:
archiver_path = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME,
)
这为您提供了路径,然后您需要将 cc_toolchain.all_files
添加到您的 ctx.actions.run
调用中,因此它最终看起来像这样:
ctx.actions.run(
inputs = depset(
direct = [libraries],
transitive = [
cc_toolchain.all_files,
],
),
outputs = [ctx.outputs.out],
executable = archiver_path,
arguments = args,
)
但是,您还会注意到 my_c_archive
构建了一个命令行和环境变量来调用归档程序。一个简单的工具链不会有任何东西可以传递给其中任何一个,但是如果不添加它们(例如,传递 -m32
或设置 PATH
),一个更复杂的工具链可能无法正常工作。
_create_archive_action
in cc_import.bzl 中 cc_import
的部分 starlark 实现是处理所有复杂问题的良好起点。它创建一个动作,从一组目标文件生成一个静态库,可以灵活地与许多工具链一起工作。
我使用下面的 bazel 规则通过 bazel 构建静态库:
def _cc_static_library_impl(ctx):
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(
inputs = libraries,
outputs = [ctx.outputs.out],
executable = "/usr/bin/ar",
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"},
)
如何从当前工具链中提取要使用的命令,而不是使用硬编码 /usr/bin/ar
?我的规则基于我在互联网上找到的内容,对此我的了解非常有限。这个例子似乎做了一些相关的事情:
https://github.com/bazelbuild/rules_cc/blob/main/examples/my_c_archive/my_c_archive.bzl
这是my_c_archive
的相关部分:
archiver_path = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME,
)
这为您提供了路径,然后您需要将 cc_toolchain.all_files
添加到您的 ctx.actions.run
调用中,因此它最终看起来像这样:
ctx.actions.run(
inputs = depset(
direct = [libraries],
transitive = [
cc_toolchain.all_files,
],
),
outputs = [ctx.outputs.out],
executable = archiver_path,
arguments = args,
)
但是,您还会注意到 my_c_archive
构建了一个命令行和环境变量来调用归档程序。一个简单的工具链不会有任何东西可以传递给其中任何一个,但是如果不添加它们(例如,传递 -m32
或设置 PATH
),一个更复杂的工具链可能无法正常工作。
_create_archive_action
in cc_import.bzl 中 cc_import
的部分 starlark 实现是处理所有复杂问题的良好起点。它创建一个动作,从一组目标文件生成一个静态库,可以灵活地与许多工具链一起工作。