使用cc_common API的自定义C ++规则

时间:2018-10-11 22:39:19

标签: bazel

我正在尝试编写一个自定义规则,以使用cc_common API编译C ++代码。这是我当前的实现尝试:

load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")   
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "C_COMPILE_ACTION_NAME") 

def _impl(ctx):
    cc_toolchain = find_cpp_toolchain(ctx)
    feature_configuration = cc_common.configure_features(
        cc_toolchain = cc_toolchain,
        unsupported_features = ctx.disabled_features,
    )
    compiler = cc_common.get_tool_for_action(
        feature_configuration=feature_configuration,
        action_name=C_COMPILE_ACTION_NAME
    )
    compile_variables = cc_common.create_compile_variables(
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
    )
    compiler_options = cc_common.get_memory_inefficient_command_line(
        feature_configuration = feature_configuration,
        action_name = C_COMPILE_ACTION_NAME,
        variables = compile_variables,
    )

    outfile = ctx.actions.declare_file("test.o")
    args = ctx.actions.args()
    args.add_all(compiler_options)
    ctx.actions.run(
        outputs = [outfile],
        inputs = ctx.files.srcs,
        executable = compiler,
        arguments = [args],
    )

    return [DefaultInfo(files = depset([outfile]))]

但是,此操作失败,并显示错误"execvp(external/local_config_cc/wrapped_clang, ...)": No such file or directory。我认为这是因为get_tool_for_action返回表示路径的字符串,而不是File对象,因此Bazel不会将wrapped_clang添加到沙箱。在禁用沙箱的情况下执行规则似乎可以确认这一点,因为它已成功完成。

是否可以在不禁用沙箱的情况下实现此自定义规则?

2 个答案:

答案 0 :(得分:0)

如果使用ctx.actions.run_shell,则可以将与工具链关联的文件添加到输入(ctx.attr._cc_toolchain.files)中。另外,您将要添加编译器环境变量。例如

srcs = depset(ctx.files.srcs)
tools = ctx.attr._cc_toolchain.files
...
compiler_env = cc_common.get_environment_variables(
   feature_configuration = feature_configuration,
   action_name = C_COMPILE_ACTION_NAME,
   variables = compiler_variables,
)
...
args = ctx.actions.args()
args.add_all(compiler_options)
ctx.actions.run_shell(
    outputs = [outfile],
    inputs = depset(transitive = [srcs, tools]), # Merge src and tools depsets
    command = "{compiler} $*".format(compiler = compiler),
    arguments = [args],
    env = compiler_env,
)

答案 1 :(得分:0)

Bazel不会自动将文件添加为动作输入,您必须像在第二种方法(ctx.attr._cc_toolchain.files中那样,显式地添加文件。这样,ctx.actions.run应该可以正常工作。