Skip to content

Commit

Permalink
Add per-toolchain rustc_flags (bazelbuild#1635)
Browse files Browse the repository at this point in the history
  • Loading branch information
Joseph Ryan authored Dec 1, 2022
1 parent 5623741 commit d9e752a
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 6 deletions.
8 changes: 5 additions & 3 deletions docs/flatten.md
Original file line number Diff line number Diff line change
Expand Up @@ -1131,9 +1131,9 @@ Run the test with `bazel test //hello_lib:greeting_test`.
<pre>
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>,
<a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>,
<a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>,
<a href="#rust_toolchain-target_triple">target_triple</a>)
<a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>,
<a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>,
<a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>

Declares a Rust toolchain for use.
Expand Down Expand Up @@ -1193,6 +1193,8 @@ See @rules_rust//rust:repositories.bzl for examples of defining the @rust_cpuX r
| <a id="rust_toolchain-env"></a>env | Environment variables to set in actions. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> |
| <a id="rust_toolchain-exec_triple"></a>exec_triple | The platform triple for the toolchains execution environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | required | |
| <a id="rust_toolchain-experimental_use_cc_common_link"></a>experimental_use_cc_common_link | Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>//rust/settings:experimental_use_cc_common_link</code> |
| <a id="rust_toolchain-extra_exec_rustc_flags"></a>extra_exec_rustc_flags | Extra flags to pass to rustc in exec configuration | List of strings | optional | <code>[]</code> |
| <a id="rust_toolchain-extra_rustc_flags"></a>extra_rustc_flags | Extra flags to pass to rustc in non-exec configuration | List of strings | optional | <code>[]</code> |
| <a id="rust_toolchain-llvm_cov"></a>llvm_cov | The location of the <code>llvm-cov</code> binary. Can be a direct source or a filegroup containing one item. If None, rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
| <a id="rust_toolchain-llvm_profdata"></a>llvm_profdata | The location of the <code>llvm-profdata</code> binary. Can be a direct source or a filegroup containing one item. If <code>llvm_cov</code> is None, this can be None as well and rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
| <a id="rust_toolchain-llvm_tools"></a>llvm_tools | LLVM tools that are shipped with the Rust toolchain. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
Expand Down
8 changes: 5 additions & 3 deletions docs/rust_repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ A dedicated filegroup-like rule for Rust stdlib artifacts.
<pre>
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-env">env</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-experimental_use_cc_common_link">experimental_use_cc_common_link</a>,
<a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>,
<a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>,
<a href="#rust_toolchain-target_triple">target_triple</a>)
<a href="#rust_toolchain-extra_exec_rustc_flags">extra_exec_rustc_flags</a>, <a href="#rust_toolchain-extra_rustc_flags">extra_rustc_flags</a>, <a href="#rust_toolchain-llvm_cov">llvm_cov</a>, <a href="#rust_toolchain-llvm_profdata">llvm_profdata</a>, <a href="#rust_toolchain-llvm_tools">llvm_tools</a>,
<a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_std">rust_std</a>, <a href="#rust_toolchain-rustc">rustc</a>, <a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>,
<a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>

Declares a Rust toolchain for use.
Expand Down Expand Up @@ -100,6 +100,8 @@ See @rules_rust//rust:repositories.bzl for examples of defining the @rust_cpuX r
| <a id="rust_toolchain-env"></a>env | Environment variables to set in actions. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> |
| <a id="rust_toolchain-exec_triple"></a>exec_triple | The platform triple for the toolchains execution environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | required | |
| <a id="rust_toolchain-experimental_use_cc_common_link"></a>experimental_use_cc_common_link | Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>//rust/settings:experimental_use_cc_common_link</code> |
| <a id="rust_toolchain-extra_exec_rustc_flags"></a>extra_exec_rustc_flags | Extra flags to pass to rustc in exec configuration | List of strings | optional | <code>[]</code> |
| <a id="rust_toolchain-extra_rustc_flags"></a>extra_rustc_flags | Extra flags to pass to rustc in non-exec configuration | List of strings | optional | <code>[]</code> |
| <a id="rust_toolchain-llvm_cov"></a>llvm_cov | The location of the <code>llvm-cov</code> binary. Can be a direct source or a filegroup containing one item. If None, rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
| <a id="rust_toolchain-llvm_profdata"></a>llvm_profdata | The location of the <code>llvm-profdata</code> binary. Can be a direct source or a filegroup containing one item. If <code>llvm_cov</code> is None, this can be None as well and rust code is not instrumented for coverage. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
| <a id="rust_toolchain-llvm_tools"></a>llvm_tools | LLVM tools that are shipped with the Rust toolchain. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
Expand Down
5 changes: 5 additions & 0 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,11 @@ def construct_arguments(
if toolchain._rename_first_party_crates:
env["RULES_RUST_THIRD_PARTY_DIR"] = toolchain._third_party_dir

if is_exec_configuration(ctx):
rustc_flags.add_all(toolchain.extra_exec_rustc_flags)
else:
rustc_flags.add_all(toolchain.extra_rustc_flags)

# extra_rustc_flags apply to the target configuration, not the exec configuration.
if hasattr(ctx.attr, "_extra_rustc_flags") and not is_exec_configuration(ctx):
rustc_flags.add_all(ctx.attr._extra_rustc_flags[ExtraRustcFlagsInfo].extra_rustc_flags)
Expand Down
8 changes: 8 additions & 0 deletions rust/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ def _rust_toolchain_impl(ctx):
rustfmt = sysroot.rustfmt,
staticlib_ext = ctx.attr.staticlib_ext,
stdlib_linkflags = stdlib_linkflags_cc_info,
extra_rustc_flags = ctx.attr.extra_rustc_flags,
extra_exec_rustc_flags = ctx.attr.extra_exec_rustc_flags,
sysroot = sysroot_path,
sysroot_short_path = sysroot_short_path,
target_arch = ctx.attr.target_triple.split("-")[0],
Expand Down Expand Up @@ -607,6 +609,12 @@ rust_toolchain = rule(
default = Label("//rust/settings:experimental_use_cc_common_link"),
doc = "Label to a boolean build setting that controls whether cc_common.link is used to link rust binaries.",
),
"extra_exec_rustc_flags": attr.string_list(
doc = "Extra flags to pass to rustc in exec configuration",
),
"extra_rustc_flags": attr.string_list(
doc = "Extra flags to pass to rustc in non-exec configuration",
),
"llvm_cov": attr.label(
doc = "The location of the `llvm-cov` binary. Can be a direct source or a filegroup containing one item. If None, rust code is not instrumented for coverage.",
allow_single_file = True,
Expand Down
3 changes: 3 additions & 0 deletions test/toolchain/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
load(":toolchain_test.bzl", "toolchain_test_suite")

toolchain_test_suite(name = "toolchain_test_suite")
1 change: 1 addition & 0 deletions test/toolchain/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a source of the stdlib
1 change: 1 addition & 0 deletions test/toolchain/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub fn call() {}
157 changes: 157 additions & 0 deletions test/toolchain/toolchain_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
"""End to end tests for rust toolchains."""

load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("//rust:defs.bzl", "rust_library")
load("//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain")

EXEC_TOOLCHAIN_FLAG = "missing"
TOOLCHAIN_FLAG = "before"
CONFIG_FLAG = "after"

def _toolchain_adds_rustc_flags_impl(ctx):
""" Tests adding extra_rustc_flags on the toolchain, asserts that:
- extra_rustc_flags added by the toolchain are applied BEFORE flags added by a config on the commandline
- The exec flags from the toolchain don't go on the commandline for a non-exec target
"""
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)
action = target[DepActionsInfo].actions[0]

asserts.equals(env, "Rustc", action.mnemonic)

asserts.true(
env,
action.argv[-2:] == [TOOLCHAIN_FLAG, CONFIG_FLAG],
"Unexpected rustc flags: {}\nShould have ended with: {}".format(
action.argv,
[TOOLCHAIN_FLAG, CONFIG_FLAG],
),
)

asserts.true(
env,
EXEC_TOOLCHAIN_FLAG not in action.argv,
"Found exec toolchain flag ({}) in rustc flags: {}".format(EXEC_TOOLCHAIN_FLAG, action.argv),
)

return analysistest.end(env)

toolchain_adds_rustc_flags_test = analysistest.make(
_toolchain_adds_rustc_flags_impl,
config_settings = {
"@//:extra_rustc_flags": [CONFIG_FLAG],
},
)

def _extra_toolchain_transition_impl(settings, _attr):
return {"//command_line_option:extra_toolchains": [
"@rules_rust//test/toolchain:extra_flags_toolchain",
] + settings["//command_line_option:extra_toolchains"]}

_extra_toolchain_transition = transition(
implementation = _extra_toolchain_transition_impl,
inputs = ["//command_line_option:extra_toolchains"],
outputs = ["//command_line_option:extra_toolchains"],
)

DepActionsInfo = provider(
"Contains information about dependencies actions.",
fields = {"actions": "List[Action]"},
)

def _collect_dep_actions_aspect_impl(target, ctx):
actions = []
actions.extend(target.actions)
for dep in ctx.rule.attr.deps:
actions.extend(dep[DepActionsInfo].actions)
return [DepActionsInfo(actions = actions)]

collect_dep_actions_aspect = aspect(
implementation = _collect_dep_actions_aspect_impl,
attr_aspects = ["deps"],
)

def _extra_toolchain_wrapper_impl(ctx):
return [ctx.attr.dep[DepActionsInfo]]

extra_toolchain_wrapper = rule(
implementation = _extra_toolchain_wrapper_impl,
attrs = {
"dep": attr.label(aspects = [collect_dep_actions_aspect]),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
cfg = _extra_toolchain_transition,
)

def _toolchain_test():
rust_library(
name = "lib",
srcs = ["lib.rs"],
edition = "2021",
)

native.filegroup(
name = "stdlib_srcs",
srcs = ["config.txt"],
)
rust_stdlib_filegroup(
name = "std_libs",
srcs = [":stdlib_srcs"],
)
write_file(
name = "mock_rustc",
out = "mock_rustc.exe",
content = [],
is_executable = True,
)
write_file(
name = "mock_rustdoc",
out = "mock_rustdoc.exe",
content = [],
is_executable = True,
)

rust_toolchain(
name = "rust_extra_flags_toolchain",
binary_ext = "",
dylib_ext = ".so",
exec_triple = "x86_64-unknown-none",
os = "linux",
rust_doc = ":mock_rustdoc",
rust_std = ":std_libs",
rustc = ":mock_rustc",
staticlib_ext = ".a",
stdlib_linkflags = [],
extra_rustc_flags = [TOOLCHAIN_FLAG],
extra_exec_rustc_flags = [EXEC_TOOLCHAIN_FLAG],
)

native.toolchain(
name = "extra_flags_toolchain",
toolchain = ":rust_extra_flags_toolchain",
toolchain_type = "@rules_rust//rust:toolchain",
)

extra_toolchain_wrapper(
name = "lib_with_extra_toolchain",
dep = ":lib",
)

toolchain_adds_rustc_flags_test(
name = "toolchain_adds_rustc_flags_test",
target_under_test = ":lib_with_extra_toolchain",
)

def toolchain_test_suite(name):
_toolchain_test()

native.test_suite(
name = name,
tests = [
":toolchain_adds_rustc_flags_test",
],
)

0 comments on commit d9e752a

Please sign in to comment.