Skip to content

Commit 52e3ba4

Browse files
authored
Support passing arbitrary extra flags to rustc (#566)
* Support passing arbitrary extra codegen args to rustc * Update defs.bzl * buildifier fixes * Add doc string * Regenerate documentation * fix lint * PR feedback * Regenerate documentation * Fix link for codegen * Regenerate documentation * Rename to extra_rustc_flags * Regenerate documentation * buildifier * Better method to exclude from the exec configuration * Regenerate documentation * Refactor is_exec_configuration utility function * buildifier * Regenerate documentation * Add test * Revert extraneous changes * Regenerate documentation
1 parent 5beb773 commit 52e3ba4

File tree

14 files changed

+203
-4
lines changed

14 files changed

+203
-4
lines changed

BUILD.bazel

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2-
load("//rust:rust.bzl", "error_format")
2+
load("//rust:rust.bzl", "error_format", "extra_rustc_flags")
33

44
exports_files(["LICENSE"])
55

@@ -18,6 +18,15 @@ error_format(
1818
visibility = ["//visibility:public"],
1919
)
2020

21+
# This setting may be used to pass extra options to rustc from the command line.
22+
# It applies across all targets whereas the rustc_flags option on targets applies only
23+
# to that target. This can be useful for passing build-wide options such as LTO.
24+
extra_rustc_flags(
25+
name = "extra_rustc_flags",
26+
build_setting_default = [],
27+
visibility = ["//visibility:public"],
28+
)
29+
2130
# This setting is used by the clippy rules. See https://bazelbuild.github.io/rules_rust/rust_clippy.html
2231
label_flag(
2332
name = "clippy.toml",

docs/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ PAGES = dict([
5959
"rust_benchmark",
6060
"rust_test",
6161
"rust_test_suite",
62+
"extra_rustc_flags",
6263
],
6364
),
6465
page(

docs/defs.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@
99
* [rust_benchmark](#rust_benchmark)
1010
* [rust_test](#rust_test)
1111
* [rust_test_suite](#rust_test_suite)
12+
* [extra_rustc_flags](#extra_rustc_flags)
13+
14+
<a id="#extra_rustc_flags"></a>
15+
16+
## extra_rustc_flags
17+
18+
<pre>
19+
extra_rustc_flags(<a href="#extra_rustc_flags-name">name</a>)
20+
</pre>
21+
22+
Add additional rustc_flags from the command line with `--@rules_rust//:extra_rustc_flags`. This flag should only be used for flags that need to be applied across the entire build. For options that apply to individual crates, use the rustc_flags attribute on the individual crate's rule instead. NOTE: These flags are currently excluded from the exec configuration (proc-macros, cargo_build_script, etc).
23+
24+
**ATTRIBUTES**
25+
26+
27+
| Name | Description | Type | Mandatory | Default |
28+
| :------------- | :------------- | :------------- | :------------- | :------------- |
29+
| <a id="extra_rustc_flags-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
30+
1231

1332
<a id="#rust_benchmark"></a>
1433

docs/flatten.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* [cargo_build_script](#cargo_build_script)
88
* [crate](#crate)
99
* [crate_universe](#crate_universe)
10+
* [extra_rustc_flags](#extra_rustc_flags)
1011
* [fail_when_enabled](#fail_when_enabled)
1112
* [incompatible_flag](#incompatible_flag)
1213
* [rust_analyzer](#rust_analyzer)
@@ -117,6 +118,24 @@ Environment Variables:
117118
| <a id="crate_universe-version"></a>version | The version of cargo the resolver should use | String | optional | "1.54.0" |
118119

119120

121+
<a id="#extra_rustc_flags"></a>
122+
123+
## extra_rustc_flags
124+
125+
<pre>
126+
extra_rustc_flags(<a href="#extra_rustc_flags-name">name</a>)
127+
</pre>
128+
129+
Add additional rustc_flags from the command line with `--@rules_rust//:extra_rustc_flags`. This flag should only be used for flags that need to be applied across the entire build. For options that apply to individual crates, use the rustc_flags attribute on the individual crate's rule instead. NOTE: These flags are currently excluded from the exec configuration (proc-macros, cargo_build_script, etc).
130+
131+
**ATTRIBUTES**
132+
133+
134+
| Name | Description | Type | Mandatory | Default |
135+
| :------------- | :------------- | :------------- | :------------- | :------------- |
136+
| <a id="extra_rustc_flags-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
137+
138+
120139
<a id="#fail_when_enabled"></a>
121140

122141
## fail_when_enabled

docs/symbols.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ load(
4141
)
4242
load(
4343
"@rules_rust//rust:defs.bzl",
44+
_extra_rustc_flags = "extra_rustc_flags",
4445
_rust_analyzer = "rust_analyzer",
4546
_rust_analyzer_aspect = "rust_analyzer_aspect",
4647
_rust_benchmark = "rust_benchmark",
@@ -141,6 +142,7 @@ crate = _crate
141142
rustfmt_aspect = _rustfmt_aspect
142143
rustfmt_test = _rustfmt_test
143144

145+
extra_rustc_flags = _extra_rustc_flags
144146
incompatible_flag = _incompatible_flag
145147
fail_when_enabled = _fail_when_enabled
146148

rust/defs.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ load(
4343
load(
4444
"//rust/private:rustc.bzl",
4545
_error_format = "error_format",
46+
_extra_rustc_flags = "extra_rustc_flags",
4647
)
4748
load(
4849
"//rust/private:rustdoc.bzl",
@@ -97,6 +98,9 @@ rust_clippy = _rust_clippy
9798
error_format = _error_format
9899
# See @rules_rust//rust/private:rustc.bzl for a complete description.
99100

101+
extra_rustc_flags = _extra_rustc_flags
102+
# See @rules_rust//rust/private:rustc.bzl for a complete description.
103+
100104
rust_common = _rust_common
101105
# See @rules_rust//rust/private:common.bzl for a complete description.
102106

rust/private/clippy.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ rust_clippy_aspect = aspect(
162162
doc = "The desired `--error-format` flags for clippy",
163163
default = "//:error_format",
164164
),
165+
"_extra_rustc_flags": attr.label(default = "//:extra_rustc_flags"),
165166
"_process_wrapper": attr.label(
166167
doc = "A process wrapper for running clippy on all platforms",
167168
default = Label("//util/process_wrapper"),

rust/private/rust.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ _common_attrs = {
663663
default = "@bazel_tools//tools/cpp:current_cc_toolchain",
664664
),
665665
"_error_format": attr.label(default = "//:error_format"),
666+
"_extra_rustc_flags": attr.label(default = "//:extra_rustc_flags"),
666667
"_process_wrapper": attr.label(
667668
default = Label("//util/process_wrapper"),
668669
executable = True,

rust/private/rustc.bzl

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ load(
2727
"find_cc_toolchain",
2828
"get_lib_name",
2929
"get_preferred_artifact",
30+
"is_exec_configuration",
3031
"make_static_lib_symlink",
3132
"relativize",
3233
)
@@ -57,6 +58,11 @@ ErrorFormatInfo = provider(
5758
fields = {"error_format": "(string) [" + ", ".join(_error_format_values) + "]"},
5859
)
5960

61+
ExtraRustcFlagsInfo = provider(
62+
doc = "Pass each value as an additional flag to rustc invocations",
63+
fields = {"extra_rustc_flags": "List[string] Extra flags to pass to rustc"},
64+
)
65+
6066
def _get_rustc_env(attr, toolchain):
6167
"""Gathers rustc environment variables
6268
@@ -519,6 +525,10 @@ def construct_arguments(
519525
# Set the SYSROOT to the directory of the rust_lib files passed to the toolchain
520526
env["SYSROOT"] = paths.dirname(toolchain.rust_lib.files.to_list()[0].short_path)
521527

528+
# extra_rustc_flags apply to the target configuration, not the exec configuration.
529+
if hasattr(ctx.attr, "_extra_rustc_flags") and is_exec_configuration(ctx):
530+
rustc_flags.add_all(ctx.attr._extra_rustc_flags[ExtraRustcFlagsInfo].extra_rustc_flags)
531+
522532
# Create a struct which keeps the arguments separate so each may be tuned or
523533
# replaced where necessary
524534
args = struct(
@@ -1015,10 +1025,23 @@ def _error_format_impl(ctx):
10151025

10161026
error_format = rule(
10171027
doc = (
1018-
"A helper rule for controlling the rustc " +
1019-
"[--error-format](https://doc.rust-lang.org/rustc/command-line-arguments.html#option-error-format) " +
1020-
"flag."
1028+
"Change the [--error-format](https://doc.rust-lang.org/rustc/command-line-arguments.html#option-error-format) " +
1029+
"flag from the command line with `--@rules_rust//:error_format`. See rustc documentation for valid values."
10211030
),
10221031
implementation = _error_format_impl,
10231032
build_setting = config.string(flag = True),
10241033
)
1034+
1035+
def _extra_rustc_flags_impl(ctx):
1036+
return ExtraRustcFlagsInfo(extra_rustc_flags = ctx.build_setting_value)
1037+
1038+
extra_rustc_flags = rule(
1039+
doc = (
1040+
"Add additional rustc_flags from the command line with `--@rules_rust//:extra_rustc_flags`. " +
1041+
"This flag should only be used for flags that need to be applied across the entire build. For options that " +
1042+
"apply to individual crates, use the rustc_flags attribute on the individual crate's rule instead. NOTE: " +
1043+
"These flags are currently excluded from the exec configuration (proc-macros, cargo_build_script, etc)."
1044+
),
1045+
implementation = _extra_rustc_flags_impl,
1046+
build_setting = config.string_list(flag = True),
1047+
)

rust/private/utils.bzl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,19 @@ def make_static_lib_symlink(actions, rlib_file):
323323
dot_a = actions.declare_file(basename + ".a", sibling = rlib_file)
324324
actions.symlink(output = dot_a, target_file = rlib_file)
325325
return dot_a
326+
327+
def is_exec_configuration(ctx):
328+
"""Determine if a context is building for the exec configuration.
329+
330+
This is helpful when processing command line flags that should apply
331+
to the target configuration but not the exec configuration.
332+
333+
Args:
334+
ctx (ctx): The ctx object for the current target.
335+
336+
Returns:
337+
True if the exec configuration is detected, False otherwise.
338+
"""
339+
340+
# TODO(djmarcin): Is there any better way to determine cfg=exec?
341+
return ctx.genfiles_dir.path.find("-exec-") == -1

0 commit comments

Comments
 (0)