diff --git a/BUILD.bazel b/BUILD.bazel index 260db43d26..ff49a9cfe6 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,5 +1,5 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load("//rust:defs.bzl", "capture_clippy_output", "clippy_flags", "error_format", "extra_exec_rustc_flags", "extra_rustc_flags") +load("//rust:defs.bzl", "capture_clippy_output", "clippy_flags", "error_format", "extra_exec_rustc_flag", "extra_exec_rustc_flags", "extra_rustc_flag", "extra_rustc_flags") exports_files(["LICENSE"]) @@ -55,6 +55,12 @@ extra_rustc_flags( visibility = ["//visibility:public"], ) +extra_rustc_flag( + name = "extra_rustc_flag", + build_setting_default = "", + visibility = ["//visibility:public"], +) + # This setting may be used to pass extra options to rustc from the command line # in exec configuration. # It applies across all targets whereas the rustc_flags option on targets applies only @@ -65,6 +71,12 @@ extra_exec_rustc_flags( visibility = ["//visibility:public"], ) +extra_exec_rustc_flag( + name = "extra_exec_rustc_flag", + build_setting_default = "", + visibility = ["//visibility:public"], +) + # This setting is used by the clippy rules. See https://bazelbuild.github.io/rules_rust/rust_clippy.html label_flag( name = "clippy.toml", diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index 3b3c30b2a5..9427b06ad9 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -54,6 +54,7 @@ PAGES = dict([ "rust_test", "rust_test_suite", "error_format", + "extra_rustc_flag", "extra_rustc_flags", "capture_clippy_output", ], diff --git a/docs/defs.md b/docs/defs.md index b1c44bc885..69189ee0cb 100644 --- a/docs/defs.md +++ b/docs/defs.md @@ -9,6 +9,7 @@ * [rust_test](#rust_test) * [rust_test_suite](#rust_test_suite) * [error_format](#error_format) +* [extra_rustc_flag](#extra_rustc_flag) * [extra_rustc_flags](#extra_rustc_flags) * [capture_clippy_output](#capture_clippy_output) @@ -48,6 +49,24 @@ Change the [--error-format](https://doc.rust-lang.org/rustc/command-line-argumen | name | A unique name for this target. | Name | required | | + + +## extra_rustc_flag + +
+extra_rustc_flag(name) ++ +Add additional rustc_flag from the command line with `--@rules_rust//:extra_rustc_flag`. Multiple uses are accumulated and appended after the extra_rustc_flags. + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | + + ## extra_rustc_flags diff --git a/docs/flatten.md b/docs/flatten.md index 34b50b6c9b..f524f26130 100644 --- a/docs/flatten.md +++ b/docs/flatten.md @@ -8,6 +8,7 @@ * [cargo_build_script](#cargo_build_script) * [cargo_env](#cargo_env) * [error_format](#error_format) +* [extra_rustc_flag](#extra_rustc_flag) * [extra_rustc_flags](#extra_rustc_flags) * [fail_when_enabled](#fail_when_enabled) * [incompatible_flag](#incompatible_flag) @@ -121,6 +122,24 @@ Change the [--error-format](https://doc.rust-lang.org/rustc/command-line-argumen | name | A unique name for this target. | Name | required | | + + +## extra_rustc_flag + +
+extra_rustc_flag(name) ++ +Add additional rustc_flag from the command line with `--@rules_rust//:extra_rustc_flag`. Multiple uses are accumulated and appended after the extra_rustc_flags. + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | + + ## extra_rustc_flags diff --git a/docs/symbols.bzl b/docs/symbols.bzl index 1a3239d001..07151d0bd0 100644 --- a/docs/symbols.bzl +++ b/docs/symbols.bzl @@ -48,6 +48,7 @@ load( "@rules_rust//rust:defs.bzl", _capture_clippy_output = "capture_clippy_output", _error_format = "error_format", + _extra_rustc_flag = "extra_rustc_flag", _extra_rustc_flags = "extra_rustc_flags", _rust_analyzer_aspect = "rust_analyzer_aspect", _rust_binary = "rust_binary", @@ -158,6 +159,7 @@ rustfmt_aspect = _rustfmt_aspect rustfmt_test = _rustfmt_test error_format = _error_format +extra_rustc_flag = _extra_rustc_flag extra_rustc_flags = _extra_rustc_flags incompatible_flag = _incompatible_flag capture_clippy_output = _capture_clippy_output diff --git a/rust/defs.bzl b/rust/defs.bzl index 4dc6779e4b..a0560b5dba 100644 --- a/rust/defs.bzl +++ b/rust/defs.bzl @@ -43,7 +43,9 @@ load( load( "//rust/private:rustc.bzl", _error_format = "error_format", + _extra_exec_rustc_flag = "extra_exec_rustc_flag", _extra_exec_rustc_flags = "extra_exec_rustc_flags", + _extra_rustc_flag = "extra_rustc_flag", _extra_rustc_flags = "extra_rustc_flags", ) load( @@ -102,9 +104,15 @@ capture_clippy_output = _capture_clippy_output error_format = _error_format # See @rules_rust//rust/private:rustc.bzl for a complete description. +extra_rustc_flag = _extra_rustc_flag +# See @rules_rust//rust/private:rustc.bzl for a complete description. + extra_rustc_flags = _extra_rustc_flags # See @rules_rust//rust/private:rustc.bzl for a complete description. +extra_exec_rustc_flag = _extra_exec_rustc_flag +# See @rules_rust//rust/private:rustc.bzl for a complete description. + extra_exec_rustc_flags = _extra_exec_rustc_flags # See @rules_rust//rust/private:rustc.bzl for a complete description. diff --git a/rust/private/clippy.bzl b/rust/private/clippy.bzl index e7953a7996..ec94ae7628 100644 --- a/rust/private/clippy.bzl +++ b/rust/private/clippy.bzl @@ -215,6 +215,7 @@ rust_clippy_aspect = aspect( doc = "The desired `--error-format` flags for clippy", default = "//:error_format", ), + "_extra_rustc_flag": attr.label(default = "//:extra_rustc_flag"), "_extra_rustc_flags": attr.label(default = "//:extra_rustc_flags"), "_process_wrapper": attr.label( doc = "A process wrapper for running clippy on all platforms", diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 9af3a3273d..ce617136a8 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -669,9 +669,15 @@ _common_attrs = { "_error_format": attr.label( default = Label("//:error_format"), ), + "_extra_exec_rustc_flag": attr.label( + default = Label("//:extra_exec_rustc_flag"), + ), "_extra_exec_rustc_flags": attr.label( default = Label("//:extra_exec_rustc_flags"), ), + "_extra_rustc_flag": attr.label( + default = Label("//:extra_rustc_flag"), + ), "_extra_rustc_flags": attr.label( default = Label("//:extra_rustc_flags"), ), diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 6cdbefeba8..7d2c1dc7e0 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -837,9 +837,15 @@ def construct_arguments( 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) + if hasattr(ctx.attr, "_extra_rustc_flag") and not is_exec_configuration(ctx): + rustc_flags.add_all(ctx.attr._extra_rustc_flag[ExtraRustcFlagsInfo].extra_rustc_flags) + if hasattr(ctx.attr, "_extra_exec_rustc_flags") and is_exec_configuration(ctx): rustc_flags.add_all(ctx.attr._extra_exec_rustc_flags[ExtraExecRustcFlagsInfo].extra_exec_rustc_flags) + if hasattr(ctx.attr, "_extra_exec_rustc_flag") and is_exec_configuration(ctx): + rustc_flags.add_all(ctx.attr._extra_exec_rustc_flag[ExtraExecRustcFlagsInfo].extra_exec_rustc_flags) + # Create a struct which keeps the arguments separate so each may be tuned or # replaced where necessary args = struct( @@ -1520,6 +1526,18 @@ extra_rustc_flags = rule( build_setting = config.string_list(flag = True), ) +def _extra_rustc_flag_impl(ctx): + return ExtraRustcFlagsInfo(extra_rustc_flags = [f for f in ctx.build_setting_value if f != ""]) + +extra_rustc_flag = rule( + doc = ( + "Add additional rustc_flag from the command line with `--@rules_rust//:extra_rustc_flag`. " + + "Multiple uses are accumulated and appended after the extra_rustc_flags." + ), + implementation = _extra_rustc_flag_impl, + build_setting = config.string(flag = True, allow_multiple = True), +) + def _extra_exec_rustc_flags_impl(ctx): return ExtraExecRustcFlagsInfo(extra_exec_rustc_flags = ctx.build_setting_value) @@ -1532,3 +1550,15 @@ extra_exec_rustc_flags = rule( implementation = _extra_exec_rustc_flags_impl, build_setting = config.string_list(flag = True), ) + +def _extra_exec_rustc_flag_impl(ctx): + return ExtraExecRustcFlagsInfo(extra_exec_rustc_flags = [f for f in ctx.build_setting_value if f != ""]) + +extra_exec_rustc_flag = rule( + doc = ( + "Add additional rustc_flags in the exec configuration from the command line with `--@rules_rust//:extra_exec_rustc_flag`. " + + "Multiple uses are accumulated and appended after the extra_exec_rustc_flags." + ), + implementation = _extra_exec_rustc_flag_impl, + build_setting = config.string(flag = True, allow_multiple = True), +) diff --git a/test/extra_exec_rustc_flags/BUILD.bazel b/test/extra_exec_rustc_flags/BUILD.bazel index d3067b04f5..7a7b6ef6de 100644 --- a/test/extra_exec_rustc_flags/BUILD.bazel +++ b/test/extra_exec_rustc_flags/BUILD.bazel @@ -21,15 +21,29 @@ rust_library( with_extra_exec_rustc_flags_cfg( name = "lib_with_exec_flags_do_not_build_directly", srcs = ["lib_do_not_build_directly"], + extra_exec_rustc_flag = [], extra_exec_rustc_flags = ["--cfg=bazel_exec"], tags = ["manual"], ) +with_extra_exec_rustc_flags_cfg( + name = "lib_with_singular_exec_flags_do_not_build_directly", + srcs = ["lib_do_not_build_directly"], + extra_exec_rustc_flag = ["--cfg=bazel_exec"], + extra_exec_rustc_flags = [], + tags = ["manual"], +) + with_exec_cfg( name = "lib", srcs = ["lib_with_exec_flags_do_not_build_directly"], ) +with_exec_cfg( + name = "lib_singular", + srcs = ["lib_with_singular_exec_flags_do_not_build_directly"], +) + # Checks that extra_exec_rustc_flags are not passed in non-exec configurations. # lib_no_exec.rs is a sample source file that fails to build if # `--cfg=bazel_exec` is present. The targets below are built in non-exec configurations, @@ -43,14 +57,24 @@ rust_library( with_extra_exec_rustc_flags_cfg( name = "lib_no_exec_with_extra_build_flags", srcs = ["lib_no_exec"], + extra_exec_rustc_flag = [], extra_exec_rustc_flags = ["--cfg=bazel_exec"], ) +with_extra_exec_rustc_flags_cfg( + name = "lib_no_exec_with_singular_extra_build_flags", + srcs = ["lib_no_exec"], + extra_exec_rustc_flag = ["--cfg=bazel_exec"], + extra_exec_rustc_flags = [], +) + build_test( name = "lib_build", targets = [ ":lib", + ":lib_singular", ":lib_no_exec", ":lib_no_exec_with_extra_build_flags", + ":lib_no_exec_with_singular_extra_build_flags", ], ) diff --git a/test/extra_exec_rustc_flags/defs.bzl b/test/extra_exec_rustc_flags/defs.bzl index 790cdc5677..e12998def1 100644 --- a/test/extra_exec_rustc_flags/defs.bzl +++ b/test/extra_exec_rustc_flags/defs.bzl @@ -2,13 +2,14 @@ def _extra_exec_rustc_flags_transition_impl(_settings, attr): return { + "//:extra_exec_rustc_flag": attr.extra_exec_rustc_flag, "//:extra_exec_rustc_flags": attr.extra_exec_rustc_flags, } _extra_exec_rustc_flags_transition = transition( implementation = _extra_exec_rustc_flags_transition_impl, inputs = [], - outputs = ["//:extra_exec_rustc_flags"], + outputs = ["//:extra_exec_rustc_flags", "//:extra_exec_rustc_flag"], ) def _with_extra_exec_rustc_flags_cfg_impl(ctx): @@ -17,6 +18,9 @@ def _with_extra_exec_rustc_flags_cfg_impl(ctx): with_extra_exec_rustc_flags_cfg = rule( implementation = _with_extra_exec_rustc_flags_cfg_impl, attrs = { + "extra_exec_rustc_flag": attr.string_list( + mandatory = True, + ), "extra_exec_rustc_flags": attr.string_list( mandatory = True, ), diff --git a/test/unit/extra_rustc_flags/extra_rustc_flags_test.bzl b/test/unit/extra_rustc_flags/extra_rustc_flags_test.bzl index 87eb3b53b1..8e24580137 100644 --- a/test/unit/extra_rustc_flags/extra_rustc_flags_test.bzl +++ b/test/unit/extra_rustc_flags/extra_rustc_flags_test.bzl @@ -58,6 +58,20 @@ extra_rustc_flags_present_test = analysistest.make( }, ) +extra_rustc_flag_present_test = analysistest.make( + _extra_rustc_flags_present_test, + attrs = { + "lib_exec": attr.label( + mandatory = True, + cfg = "exec", + ), + }, + config_settings = { + "@//:extra_rustc_flag": [EXTRA_FLAG], + "@//:extra_rustc_flags": [], + }, +) + def _define_test_targets(): rust_library( name = "lib", @@ -85,6 +99,12 @@ def extra_rustc_flags_test_suite(name): lib_exec = ":lib", ) + extra_rustc_flag_present_test( + name = "extra_rustc_flag_present_test", + target_under_test = ":lib", + lib_exec = ":lib", + ) + native.test_suite( name = name, tests = [