Custom C++ rule with the cc_common API
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I'm trying to write a custom rule to compile C++ code using the cc_common API. Here's my current attempt at an implementation:
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]))]
However, this fails with the error "execvp(external/local_config_cc/wrapped_clang, ...)": No such file or directory
. I assume this is because get_tool_for_action
returns a string representing a path, not a File object, so Bazel doesn't add wrapped_clang
to the sandbox. Executing the rule with sandboxing disabled seems to confirm this, as it completes successfully.
Is there a way to implement this custom rule without disabling the sandbox?
bazel
add a comment |
I'm trying to write a custom rule to compile C++ code using the cc_common API. Here's my current attempt at an implementation:
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]))]
However, this fails with the error "execvp(external/local_config_cc/wrapped_clang, ...)": No such file or directory
. I assume this is because get_tool_for_action
returns a string representing a path, not a File object, so Bazel doesn't add wrapped_clang
to the sandbox. Executing the rule with sandboxing disabled seems to confirm this, as it completes successfully.
Is there a way to implement this custom rule without disabling the sandbox?
bazel
add a comment |
I'm trying to write a custom rule to compile C++ code using the cc_common API. Here's my current attempt at an implementation:
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]))]
However, this fails with the error "execvp(external/local_config_cc/wrapped_clang, ...)": No such file or directory
. I assume this is because get_tool_for_action
returns a string representing a path, not a File object, so Bazel doesn't add wrapped_clang
to the sandbox. Executing the rule with sandboxing disabled seems to confirm this, as it completes successfully.
Is there a way to implement this custom rule without disabling the sandbox?
bazel
I'm trying to write a custom rule to compile C++ code using the cc_common API. Here's my current attempt at an implementation:
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]))]
However, this fails with the error "execvp(external/local_config_cc/wrapped_clang, ...)": No such file or directory
. I assume this is because get_tool_for_action
returns a string representing a path, not a File object, so Bazel doesn't add wrapped_clang
to the sandbox. Executing the rule with sandboxing disabled seems to confirm this, as it completes successfully.
Is there a way to implement this custom rule without disabling the sandbox?
bazel
bazel
asked Oct 11 '18 at 22:39
Kevin K.Kevin K.
62
62
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
If you use ctx.actions.run_shell
you can add the files associated with the toolchain to the input (ctx.attr._cc_toolchain.files
). Also, you'll want to add the compiler environment variables. E.g.
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,
)
add a comment |
Bazel doesn't add files as action inputs automatically, you have to do it explicitly, as you did in your second approach (ctx.attr._cc_toolchain.files
). With that, ctx.actions.run
should work just fine.
This issue was that I wasn't sure how to get from the string returned bycc_common.get_tool_for_action
to the actual files associated with the tool (actually, I'm still not sure how to do that - usingctx.attr._cc_toolchain.files
seems like a hack.) I understand that the files aren't added automatically.
– Kevin K.
Nov 30 '18 at 21:48
ctx.attr._cc_toolchain.files is the principled way to get FilesToBuildProvider from your implicit dependencies. So no need to fear that. There is (rather unfortunate) separation between files to build from cc_toolchain and paths to those files. Ideally get_tool_for_action would return an Artifact, and a collection of related deps. We're not there now, get_tool_for_action returns a string, and actual action inputs are taken from cc_toolchain.files.
– hlopko
Dec 4 '18 at 14:36
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52769846%2fcustom-c-rule-with-the-cc-common-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you use ctx.actions.run_shell
you can add the files associated with the toolchain to the input (ctx.attr._cc_toolchain.files
). Also, you'll want to add the compiler environment variables. E.g.
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,
)
add a comment |
If you use ctx.actions.run_shell
you can add the files associated with the toolchain to the input (ctx.attr._cc_toolchain.files
). Also, you'll want to add the compiler environment variables. E.g.
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,
)
add a comment |
If you use ctx.actions.run_shell
you can add the files associated with the toolchain to the input (ctx.attr._cc_toolchain.files
). Also, you'll want to add the compiler environment variables. E.g.
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,
)
If you use ctx.actions.run_shell
you can add the files associated with the toolchain to the input (ctx.attr._cc_toolchain.files
). Also, you'll want to add the compiler environment variables. E.g.
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,
)
answered Oct 22 '18 at 18:20
Kevin K.Kevin K.
62
62
add a comment |
add a comment |
Bazel doesn't add files as action inputs automatically, you have to do it explicitly, as you did in your second approach (ctx.attr._cc_toolchain.files
). With that, ctx.actions.run
should work just fine.
This issue was that I wasn't sure how to get from the string returned bycc_common.get_tool_for_action
to the actual files associated with the tool (actually, I'm still not sure how to do that - usingctx.attr._cc_toolchain.files
seems like a hack.) I understand that the files aren't added automatically.
– Kevin K.
Nov 30 '18 at 21:48
ctx.attr._cc_toolchain.files is the principled way to get FilesToBuildProvider from your implicit dependencies. So no need to fear that. There is (rather unfortunate) separation between files to build from cc_toolchain and paths to those files. Ideally get_tool_for_action would return an Artifact, and a collection of related deps. We're not there now, get_tool_for_action returns a string, and actual action inputs are taken from cc_toolchain.files.
– hlopko
Dec 4 '18 at 14:36
add a comment |
Bazel doesn't add files as action inputs automatically, you have to do it explicitly, as you did in your second approach (ctx.attr._cc_toolchain.files
). With that, ctx.actions.run
should work just fine.
This issue was that I wasn't sure how to get from the string returned bycc_common.get_tool_for_action
to the actual files associated with the tool (actually, I'm still not sure how to do that - usingctx.attr._cc_toolchain.files
seems like a hack.) I understand that the files aren't added automatically.
– Kevin K.
Nov 30 '18 at 21:48
ctx.attr._cc_toolchain.files is the principled way to get FilesToBuildProvider from your implicit dependencies. So no need to fear that. There is (rather unfortunate) separation between files to build from cc_toolchain and paths to those files. Ideally get_tool_for_action would return an Artifact, and a collection of related deps. We're not there now, get_tool_for_action returns a string, and actual action inputs are taken from cc_toolchain.files.
– hlopko
Dec 4 '18 at 14:36
add a comment |
Bazel doesn't add files as action inputs automatically, you have to do it explicitly, as you did in your second approach (ctx.attr._cc_toolchain.files
). With that, ctx.actions.run
should work just fine.
Bazel doesn't add files as action inputs automatically, you have to do it explicitly, as you did in your second approach (ctx.attr._cc_toolchain.files
). With that, ctx.actions.run
should work just fine.
answered Nov 29 '18 at 6:17
hlopkohlopko
1,9131322
1,9131322
This issue was that I wasn't sure how to get from the string returned bycc_common.get_tool_for_action
to the actual files associated with the tool (actually, I'm still not sure how to do that - usingctx.attr._cc_toolchain.files
seems like a hack.) I understand that the files aren't added automatically.
– Kevin K.
Nov 30 '18 at 21:48
ctx.attr._cc_toolchain.files is the principled way to get FilesToBuildProvider from your implicit dependencies. So no need to fear that. There is (rather unfortunate) separation between files to build from cc_toolchain and paths to those files. Ideally get_tool_for_action would return an Artifact, and a collection of related deps. We're not there now, get_tool_for_action returns a string, and actual action inputs are taken from cc_toolchain.files.
– hlopko
Dec 4 '18 at 14:36
add a comment |
This issue was that I wasn't sure how to get from the string returned bycc_common.get_tool_for_action
to the actual files associated with the tool (actually, I'm still not sure how to do that - usingctx.attr._cc_toolchain.files
seems like a hack.) I understand that the files aren't added automatically.
– Kevin K.
Nov 30 '18 at 21:48
ctx.attr._cc_toolchain.files is the principled way to get FilesToBuildProvider from your implicit dependencies. So no need to fear that. There is (rather unfortunate) separation between files to build from cc_toolchain and paths to those files. Ideally get_tool_for_action would return an Artifact, and a collection of related deps. We're not there now, get_tool_for_action returns a string, and actual action inputs are taken from cc_toolchain.files.
– hlopko
Dec 4 '18 at 14:36
This issue was that I wasn't sure how to get from the string returned by
cc_common.get_tool_for_action
to the actual files associated with the tool (actually, I'm still not sure how to do that - using ctx.attr._cc_toolchain.files
seems like a hack.) I understand that the files aren't added automatically.– Kevin K.
Nov 30 '18 at 21:48
This issue was that I wasn't sure how to get from the string returned by
cc_common.get_tool_for_action
to the actual files associated with the tool (actually, I'm still not sure how to do that - using ctx.attr._cc_toolchain.files
seems like a hack.) I understand that the files aren't added automatically.– Kevin K.
Nov 30 '18 at 21:48
ctx.attr._cc_toolchain.files is the principled way to get FilesToBuildProvider from your implicit dependencies. So no need to fear that. There is (rather unfortunate) separation between files to build from cc_toolchain and paths to those files. Ideally get_tool_for_action would return an Artifact, and a collection of related deps. We're not there now, get_tool_for_action returns a string, and actual action inputs are taken from cc_toolchain.files.
– hlopko
Dec 4 '18 at 14:36
ctx.attr._cc_toolchain.files is the principled way to get FilesToBuildProvider from your implicit dependencies. So no need to fear that. There is (rather unfortunate) separation between files to build from cc_toolchain and paths to those files. Ideally get_tool_for_action would return an Artifact, and a collection of related deps. We're not there now, get_tool_for_action returns a string, and actual action inputs are taken from cc_toolchain.files.
– hlopko
Dec 4 '18 at 14:36
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52769846%2fcustom-c-rule-with-the-cc-common-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown