From 0ab8455b5a6d6783d309014dd30dcfb06fdbb4a3 Mon Sep 17 00:00:00 2001 From: Marc Nijweide Date: Fri, 26 Jun 2026 10:19:09 +0200 Subject: [PATCH 1/7] Add configurable default settings for opt-level --- rust/private/opt_level.bzl | 26 ++++++ rust/private/toolchain.bzl | 27 ++++--- rust/settings/BUILD.bazel | 3 + rust/settings/settings.bzl | 35 ++++++++ test/unit/opt_level/opt_level_test_suite.bzl | 85 ++++++++++++++++++++ 5 files changed, 165 insertions(+), 11 deletions(-) create mode 100644 rust/private/opt_level.bzl diff --git a/rust/private/opt_level.bzl b/rust/private/opt_level.bzl new file mode 100644 index 0000000000..10a3859de0 --- /dev/null +++ b/rust/private/opt_level.bzl @@ -0,0 +1,26 @@ +"""A module defining Rust opt-level rules""" + +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") + +RustOptLevelInfo = provider( + doc = "A provider describing the opt-level settings per compilation mode.", + fields = { + "levels": "dict[str, str]: Mapping of compilation mode to opt-level string.", + }, +) + +def _rust_opt_level_flag_impl(ctx): + levels = {} + for mode in ("dbg", "fastbuild", "opt"): + levels[mode] = getattr(ctx.attr, mode)[BuildSettingInfo].value + return [RustOptLevelInfo(levels = levels)] + +rust_opt_level_flag = rule( + doc = "Aggregates the three per-mode opt-level flags into a single RustOptLevelInfo provider. Valid values are defined by rustc: https://doc.rust-lang.org/rustc/codegen-options/index.html#opt-level", + implementation = _rust_opt_level_flag_impl, + attrs = { + "dbg": attr.label(default = "//rust/settings:opt_level_dbg"), + "fastbuild": attr.label(default = "//rust/settings:opt_level_fastbuild"), + "opt": attr.label(default = "//rust/settings:opt_level_opt"), + }, +) \ No newline at end of file diff --git a/rust/private/toolchain.bzl b/rust/private/toolchain.bzl index 8effcbca4e..e2294e54d3 100644 --- a/rust/private/toolchain.bzl +++ b/rust/private/toolchain.bzl @@ -9,6 +9,7 @@ load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//rust/platform:triple.bzl", "triple") load("//rust/private:common.bzl", "rust_common") load("//rust/private:lto.bzl", "RustLtoInfo") +load("//rust/private:opt_level.bzl", "RustOptLevelInfo") load( "//rust/private:rust_allocator_libraries.bzl", "make_libstd_and_allocator_ccinfo", @@ -393,16 +394,19 @@ def _rust_toolchain_impl(ctx): Returns: list: A list containing the target's toolchain Provider info """ + effective_opt_levels = dict(ctx.attr._opt_level[RustOptLevelInfo].levels) + effective_opt_levels.update(ctx.attr.opt_level) + compilation_mode_opts = {} - for k, opt_level in ctx.attr.opt_level.items(): + for k, opt_level in effective_opt_levels.items(): if not k in ctx.attr.debug_info: - fail("Compilation mode {} is not defined in debug_info but is defined opt_level".format(k)) + fail("Compilation mode {} is not defined in debug_info but is defined in opt_level".format(k)) if not k in ctx.attr.strip_level: - fail("Compilation mode {} is not defined in strip_level but is defined opt_level".format(k)) + fail("Compilation mode {} is not defined in strip_level but is defined in opt_level".format(k)) compilation_mode_opts[k] = struct(debug_info = ctx.attr.debug_info[k], opt_level = opt_level, strip_level = ctx.attr.strip_level[k]) for k in ctx.attr.debug_info.keys(): - if not k in ctx.attr.opt_level: - fail("Compilation mode {} is not defined in opt_level but is defined debug_info".format(k)) + if not k in effective_opt_levels: + fail("Compilation mode {} is not defined in opt_level but is defined in debug_info".format(k)) rename_first_party_crates = ctx.attr._rename_first_party_crates[BuildSettingInfo].value third_party_dir = ctx.attr._third_party_dir[BuildSettingInfo].value @@ -796,12 +800,13 @@ rust_toolchain = rule( doc = "Label to an LTO setting whether which can enable custom LTO settings", ), "opt_level": attr.string_dict( - doc = "Rustc optimization levels.", - default = { - "dbg": "0", - "fastbuild": "0", - "opt": "3", - }, + doc = "Per-toolchain opt-level overrides per compilation mode. Any mode set here takes precedence over the global `//rust/settings:opt_level_*` flags. Omit a mode (or leave empty) to use the global flag value.", + default = {}, + ), + "_opt_level": attr.label( + default = Label("//rust/settings:opt_level"), + providers = [RustOptLevelInfo], + doc = "Global opt-level defaults, read from the `//rust/settings:opt_level_*` int flags.", ), "per_crate_rustc_flags": attr.string_list( doc = "Extra flags to pass to rustc in non-exec configuration", diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index 375ea537ee..e71ba120b1 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -31,6 +31,7 @@ load( "incompatible_do_not_include_transitive_data_in_compile_inputs", "lto", "no_std", + "opt_level", "pipelined_compilation", "rename_first_party_crates", "require_explicit_unstable_features", @@ -121,6 +122,8 @@ lto() no_std() +opt_level() + pipelined_compilation() rename_first_party_crates() diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index b6d3494264..ddbd114944 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -17,6 +17,7 @@ load( _clippy_output_diagnostics = "clippy_output_diagnostics", ) load("//rust/private:lto.bzl", "rust_lto_flag") +load("//rust/private:opt_level.bzl", "rust_opt_level_flag") load( "//rust/private:rustc.bzl", _always_enable_metadata_output_groups = "always_enable_metadata_output_groups", @@ -67,6 +68,40 @@ def lto(): build_setting_default = "unspecified", ) +# buildifier: disable=unnamed-macro +def opt_level(): + """Build settings to control the rustc optimization level per compilation mode. + + Each flag sets the default opt-level for all toolchains that do not explicitly + override it viathe `opt_level` attribute. + + Defaults match Bazel's conventional compilation modes: `dbg` and `fastbuild` + use level 0 (no optimization), `opt` uses level 3 (full optimization). + + Override from the command line: + + ``` + build --@rules_rust//rust/settings:opt_level_dbg=1 + build --@rules_rust//rust/settings:opt_level_opt=2 + build --@rules_rust//rust/settings:opt_level_fastbuild=1 + ``` + """ + string_flag( + name = "opt_level_dbg", + build_setting_default = "0", + ) + string_flag( + name = "opt_level_opt", + build_setting_default = "3", + ) + string_flag( + name = "opt_level_fastbuild", + build_setting_default = "0", + ) + rust_opt_level_flag( + name = "opt_level", + ) + def rename_first_party_crates(): """A flag controlling whether to rename first-party crates such that their names \ encode the Bazel package and target name, instead of just the target name. diff --git a/test/unit/opt_level/opt_level_test_suite.bzl b/test/unit/opt_level/opt_level_test_suite.bzl index 9003a67200..1a0ae80613 100644 --- a/test/unit/opt_level/opt_level_test_suite.bzl +++ b/test/unit/opt_level/opt_level_test_suite.bzl @@ -49,6 +49,61 @@ _opt_level_for_opt_test = analysistest.make( }, ) +def _opt_level_dbg_setting_test_impl(ctx): + return _opt_level_test_impl(ctx, "1") + +_opt_level_dbg_setting_test = analysistest.make( + _opt_level_dbg_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "dbg", + str(Label("//rust/settings:opt_level_dbg")): "1", + }, +) + +def _opt_level_opt_setting_test_impl(ctx): + return _opt_level_test_impl(ctx, "2") + +_opt_level_opt_setting_test = analysistest.make( + _opt_level_opt_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "opt", + str(Label("//rust/settings:opt_level_opt")): "2", + }, +) + +def _opt_level_fastbuild_setting_test_impl(ctx): + return _opt_level_test_impl(ctx, "1") + +_opt_level_fastbuild_setting_test = analysistest.make( + _opt_level_fastbuild_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "fastbuild", + str(Label("//rust/settings:opt_level_fastbuild")): "1", + }, +) + +def _opt_level_size_setting_test_impl(ctx): + return _opt_level_test_impl(ctx, "s") + +_opt_level_size_setting_test = analysistest.make( + _opt_level_size_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "opt", + str(Label("//rust/settings:opt_level_opt")): "s", + }, +) + +def _opt_level_minsize_setting_test_impl(ctx): + return _opt_level_test_impl(ctx, "z") + +_opt_level_minsize_setting_test = analysistest.make( + _opt_level_minsize_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "opt", + str(Label("//rust/settings:opt_level_opt")): "z", + }, +) + def opt_level_test_suite(name): """Entry-point macro called from the BUILD file. @@ -85,11 +140,41 @@ def opt_level_test_suite(name): target_under_test = ":bin", ) + _opt_level_dbg_setting_test( + name = "opt_level_dbg_setting_test", + target_under_test = ":bin", + ) + + _opt_level_opt_setting_test( + name = "opt_level_opt_setting_test", + target_under_test = ":bin", + ) + + _opt_level_fastbuild_setting_test( + name = "opt_level_fastbuild_setting_test", + target_under_test = ":bin", + ) + + _opt_level_size_setting_test( + name = "opt_level_size_setting_test", + target_under_test = ":bin", + ) + + _opt_level_minsize_setting_test( + name = "opt_level_minsize_setting_test", + target_under_test = ":bin", + ) + native.test_suite( name = name, tests = [ ":opt_level_for_dbg_test", ":opt_level_for_fastbuild_test", ":opt_level_for_opt_test", + ":opt_level_dbg_setting_test", + ":opt_level_opt_setting_test", + ":opt_level_fastbuild_setting_test", + ":opt_level_size_setting_test", + ":opt_level_minsize_setting_test", ], ) From ca78d9f1cd341195601893219c24c806caa730bc Mon Sep 17 00:00:00 2001 From: Marc Nijweide Date: Fri, 26 Jun 2026 10:22:35 +0200 Subject: [PATCH 2/7] Add configurable default settings for debuginfo --- rust/private/debug_info.bzl | 26 ++++ rust/private/toolchain.bzl | 23 ++-- rust/settings/BUILD.bazel | 3 + rust/settings/settings.bzl | 36 +++++ .../debug_info/debug_info_analysis_test.bzl | 128 ++++++++++++++++++ 5 files changed, 207 insertions(+), 9 deletions(-) create mode 100644 rust/private/debug_info.bzl diff --git a/rust/private/debug_info.bzl b/rust/private/debug_info.bzl new file mode 100644 index 0000000000..b2fd91d3e4 --- /dev/null +++ b/rust/private/debug_info.bzl @@ -0,0 +1,26 @@ +"""A module defining Rust debug-info rules""" + +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") + +RustDebugInfoInfo = provider( + doc = "A provider describing the debug-info settings per compilation mode.", + fields = { + "levels": "dict[str, str]: Mapping of compilation mode to debug-info string.", + }, +) + +def _rust_debug_info_flag_impl(ctx): + levels = {} + for mode in ("dbg", "fastbuild", "opt"): + levels[mode] = getattr(ctx.attr, mode)[BuildSettingInfo].value + return [RustDebugInfoInfo(levels = levels)] + +rust_debug_info_flag = rule( + doc = "Aggregates the three per-mode debug-info flags into a single RustDebugInfoInfo provider. Valid values are defined by rustc: https://doc.rust-lang.org/rustc/codegen-options/index.html#debuginfo.", + implementation = _rust_debug_info_flag_impl, + attrs = { + "dbg": attr.label(default = "//rust/settings:debug_info_dbg"), + "fastbuild": attr.label(default = "//rust/settings:debug_info_fastbuild"), + "opt": attr.label(default = "//rust/settings:debug_info_opt"), + }, +) \ No newline at end of file diff --git a/rust/private/toolchain.bzl b/rust/private/toolchain.bzl index e2294e54d3..353b041fba 100644 --- a/rust/private/toolchain.bzl +++ b/rust/private/toolchain.bzl @@ -8,6 +8,7 @@ load("@rules_cc//cc/common:cc_common.bzl", "cc_common") load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//rust/platform:triple.bzl", "triple") load("//rust/private:common.bzl", "rust_common") +load("//rust/private:debug_info.bzl", "RustDebugInfoInfo") load("//rust/private:lto.bzl", "RustLtoInfo") load("//rust/private:opt_level.bzl", "RustOptLevelInfo") load( @@ -397,14 +398,17 @@ def _rust_toolchain_impl(ctx): effective_opt_levels = dict(ctx.attr._opt_level[RustOptLevelInfo].levels) effective_opt_levels.update(ctx.attr.opt_level) + effective_debug_info = dict(ctx.attr._debug_info[RustDebugInfoInfo].levels) + effective_debug_info.update(ctx.attr.debug_info) + compilation_mode_opts = {} for k, opt_level in effective_opt_levels.items(): - if not k in ctx.attr.debug_info: + if not k in effective_debug_info: fail("Compilation mode {} is not defined in debug_info but is defined in opt_level".format(k)) if not k in ctx.attr.strip_level: fail("Compilation mode {} is not defined in strip_level but is defined in opt_level".format(k)) - compilation_mode_opts[k] = struct(debug_info = ctx.attr.debug_info[k], opt_level = opt_level, strip_level = ctx.attr.strip_level[k]) - for k in ctx.attr.debug_info.keys(): + compilation_mode_opts[k] = struct(debug_info = effective_debug_info[k], opt_level = opt_level, strip_level = ctx.attr.strip_level[k]) + for k in effective_debug_info.keys(): if not k in effective_opt_levels: fail("Compilation mode {} is not defined in opt_level but is defined in debug_info".format(k)) @@ -697,12 +701,13 @@ rust_toolchain = rule( cfg = "exec", ), "debug_info": attr.string_dict( - doc = "Rustc debug info levels per opt level", - default = { - "dbg": "2", - "fastbuild": "0", - "opt": "0", - }, + doc = "Per-toolchain debug-info overrides per compilation mode. Any mode set here takes precedence over the global `//rust/settings:debug_info_*` flags. Omit a mode (or leave empty) to use the global flag value.", + default = {}, + ), + "_debug_info": attr.label( + default = Label("//rust/settings:debug_info"), + providers = [RustDebugInfoInfo], + doc = "Global debug-info defaults, read from the `//rust/settings:debug_info_*` flags.", ), "default_edition": attr.string( doc = ( diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index e71ba120b1..bea0816fbe 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -29,6 +29,7 @@ load( "incompatible_change_clippy_error_format", "incompatible_do_not_include_data_in_compile_data", "incompatible_do_not_include_transitive_data_in_compile_inputs", + "debug_info", "lto", "no_std", "opt_level", @@ -118,6 +119,8 @@ incompatible_do_not_include_data_in_compile_data() incompatible_do_not_include_transitive_data_in_compile_inputs() +debug_info() + lto() no_std() diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index ddbd114944..e68868ee42 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -16,6 +16,7 @@ load( _clippy_flags = "clippy_flags", _clippy_output_diagnostics = "clippy_output_diagnostics", ) +load("//rust/private:debug_info.bzl", "rust_debug_info_flag") load("//rust/private:lto.bzl", "rust_lto_flag") load("//rust/private:opt_level.bzl", "rust_opt_level_flag") load( @@ -102,6 +103,41 @@ def opt_level(): name = "opt_level", ) +# buildifier: disable=unnamed-macro +def debug_info(): + """Build settings to control the rustc debug info level per compilation mode. + + Each flag accepts one of `"0"`, `"1"`, or `"2"` and sets the default + debug-info level for all toolchains that do not explicitly override it via + the `debug_info` attribute. + + Defaults match Bazel's conventional compilation modes: `dbg` uses level 2 + (full debug info), `fastbuild` and `opt` use level 0 (no debug info). + + Override from the command line: + + ``` + build --@rules_rust//rust/settings:debug_info_dbg=1 + build --@rules_rust//rust/settings:debug_info_opt=1 + build --@rules_rust//rust/settings:debug_info_fastbuild=1 + ``` + """ + string_flag( + name = "debug_info_dbg", + build_setting_default = "2", + ) + string_flag( + name = "debug_info_opt", + build_setting_default = "0", + ) + string_flag( + name = "debug_info_fastbuild", + build_setting_default = "0", + ) + rust_debug_info_flag( + name = "debug_info", + ) + def rename_first_party_crates(): """A flag controlling whether to rename first-party crates such that their names \ encode the Bazel package and target name, instead of just the target name. diff --git a/test/unit/debug_info/debug_info_analysis_test.bzl b/test/unit/debug_info/debug_info_analysis_test.bzl index ad5bbf6b36..6aa925507b 100644 --- a/test/unit/debug_info/debug_info_analysis_test.bzl +++ b/test/unit/debug_info/debug_info_analysis_test.bzl @@ -1,7 +1,13 @@ """Analysis tests for debug info in cdylib and bin targets.""" load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary", "rust_shared_library", "rust_test") +load( + "//test/unit:common.bzl", + "assert_action_mnemonic", + "assert_argv_contains", +) def _pdb_file_test_impl(ctx, expect_pdb_file): env = analysistest.begin(ctx) @@ -70,6 +76,77 @@ def _dsym_folder_test_impl(ctx): dsym_folder_test = analysistest.make(_dsym_folder_test_impl) +def _debug_info_flag_test_impl(ctx, expected_level): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + action = target.actions[0] + assert_action_mnemonic(env, action, "Rustc") + assert_argv_contains(env, action, "--codegen=debuginfo={}".format(expected_level)) + return analysistest.end(env) + +def _debug_info_for_dbg_test_impl(ctx): + return _debug_info_flag_test_impl(ctx, "2") + +_debug_info_for_dbg_test = analysistest.make( + _debug_info_for_dbg_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "dbg", + }, +) + +def _debug_info_for_fastbuild_test_impl(ctx): + return _debug_info_flag_test_impl(ctx, "0") + +_debug_info_for_fastbuild_test = analysistest.make( + _debug_info_for_fastbuild_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "fastbuild", + }, +) + +def _debug_info_for_opt_test_impl(ctx): + return _debug_info_flag_test_impl(ctx, "0") + +_debug_info_for_opt_test = analysistest.make( + _debug_info_for_opt_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "opt", + }, +) + +def _debug_info_dbg_setting_test_impl(ctx): + return _debug_info_flag_test_impl(ctx, "1") + +_debug_info_dbg_setting_test = analysistest.make( + _debug_info_dbg_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "dbg", + str(Label("//rust/settings:debug_info_dbg")): "1", + }, +) + +def _debug_info_opt_setting_test_impl(ctx): + return _debug_info_flag_test_impl(ctx, "1") + +_debug_info_opt_setting_test = analysistest.make( + _debug_info_opt_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "opt", + str(Label("//rust/settings:debug_info_opt")): "1", + }, +) + +def _debug_info_fastbuild_setting_test_impl(ctx): + return _debug_info_flag_test_impl(ctx, "2") + +_debug_info_fastbuild_setting_test = analysistest.make( + _debug_info_fastbuild_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "fastbuild", + str(Label("//rust/settings:debug_info_fastbuild")): "2", + }, +) + def debug_info_analysis_test_suite(name): """Analysis tests for debug info in cdylib and bin targets. @@ -171,12 +248,63 @@ def debug_info_analysis_test_suite(name): target_compatible_with = ["@platforms//os:macos"], ) + write_file( + name = "flag_bin_main", + out = "flag_main.rs", + content = [ + "fn main() {}", + "", + ], + ) + + rust_binary( + name = "flag_bin", + srcs = [":flag_main.rs"], + edition = "2021", + ) + + _debug_info_for_dbg_test( + name = "debug_info_for_dbg_test", + target_under_test = ":flag_bin", + ) + + _debug_info_for_fastbuild_test( + name = "debug_info_for_fastbuild_test", + target_under_test = ":flag_bin", + ) + + _debug_info_for_opt_test( + name = "debug_info_for_opt_test", + target_under_test = ":flag_bin", + ) + + _debug_info_dbg_setting_test( + name = "debug_info_dbg_setting_test", + target_under_test = ":flag_bin", + ) + + _debug_info_opt_setting_test( + name = "debug_info_opt_setting_test", + target_under_test = ":flag_bin", + ) + + _debug_info_fastbuild_setting_test( + name = "debug_info_fastbuild_setting_test", + target_under_test = ":flag_bin", + ) + native.test_suite( name = name, tests = [ ":lib_dsym_test", ":bin_dsym_test", ":test_dsym_test", + ":debug_info_for_dbg_test", + ":debug_info_for_fastbuild_test", + ":debug_info_for_opt_test", + ":debug_info_dbg_setting_test", + ":debug_info_opt_setting_test", + ":debug_info_fastbuild_setting_test", ] + [ ":lib_pdb_test_{}".format(compilation_mode) for compilation_mode in pdb_file_tests From 779d33999d72fd84edc8ef8f9059cbca3f9f2e3e Mon Sep 17 00:00:00 2001 From: Marc Nijweide Date: Fri, 26 Jun 2026 10:29:05 +0200 Subject: [PATCH 3/7] Add configurable default settings for strip --- rust/private/strip_level.bzl | 26 ++++++++++ rust/private/toolchain.bzl | 24 +++++---- rust/settings/BUILD.bazel | 3 ++ rust/settings/settings.bzl | 36 +++++++++++++ .../strip_level/strip_level_test_suite.bzl | 51 +++++++++++++++++++ 5 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 rust/private/strip_level.bzl diff --git a/rust/private/strip_level.bzl b/rust/private/strip_level.bzl new file mode 100644 index 0000000000..3ec9a92aec --- /dev/null +++ b/rust/private/strip_level.bzl @@ -0,0 +1,26 @@ +"""A module defining Rust strip-level rules""" + +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") + +RustStripLevelInfo = provider( + doc = "A provider describing the strip-level settings per compilation mode.", + fields = { + "levels": "dict[str, str]: Mapping of compilation mode to strip-level string.", + }, +) + +def _rust_strip_level_flag_impl(ctx): + levels = {} + for mode in ("dbg", "fastbuild", "opt"): + levels[mode] = getattr(ctx.attr, mode)[BuildSettingInfo].value + return [RustStripLevelInfo(levels = levels)] + +rust_strip_level_flag = rule( + doc = "Aggregates the three per-mode strip-level flags into a single RustStripLevelInfo provider. Valid values are defined by rustc: https://doc.rust-lang.org/rustc/codegen-options/index.html#strip", + implementation = _rust_strip_level_flag_impl, + attrs = { + "dbg": attr.label(default = "//rust/settings:strip_level_dbg"), + "fastbuild": attr.label(default = "//rust/settings:strip_level_fastbuild"), + "opt": attr.label(default = "//rust/settings:strip_level_opt"), + }, +) \ No newline at end of file diff --git a/rust/private/toolchain.bzl b/rust/private/toolchain.bzl index 353b041fba..72da30af96 100644 --- a/rust/private/toolchain.bzl +++ b/rust/private/toolchain.bzl @@ -11,6 +11,7 @@ load("//rust/private:common.bzl", "rust_common") load("//rust/private:debug_info.bzl", "RustDebugInfoInfo") load("//rust/private:lto.bzl", "RustLtoInfo") load("//rust/private:opt_level.bzl", "RustOptLevelInfo") +load("//rust/private:strip_level.bzl", "RustStripLevelInfo") load( "//rust/private:rust_allocator_libraries.bzl", "make_libstd_and_allocator_ccinfo", @@ -401,13 +402,16 @@ def _rust_toolchain_impl(ctx): effective_debug_info = dict(ctx.attr._debug_info[RustDebugInfoInfo].levels) effective_debug_info.update(ctx.attr.debug_info) + effective_strip_level = dict(ctx.attr._strip_level[RustStripLevelInfo].levels) + effective_strip_level.update(ctx.attr.strip_level) + compilation_mode_opts = {} for k, opt_level in effective_opt_levels.items(): if not k in effective_debug_info: fail("Compilation mode {} is not defined in debug_info but is defined in opt_level".format(k)) - if not k in ctx.attr.strip_level: + if not k in effective_strip_level: fail("Compilation mode {} is not defined in strip_level but is defined in opt_level".format(k)) - compilation_mode_opts[k] = struct(debug_info = effective_debug_info[k], opt_level = opt_level, strip_level = ctx.attr.strip_level[k]) + compilation_mode_opts[k] = struct(debug_info = effective_debug_info[k], opt_level = opt_level, strip_level = effective_strip_level[k]) for k in effective_debug_info.keys(): if not k in effective_opt_levels: fail("Compilation mode {} is not defined in opt_level but is defined in debug_info".format(k)) @@ -867,15 +871,13 @@ rust_toolchain = rule( mandatory = True, ), "strip_level": attr.string_dict( - doc = ( - "Rustc strip levels. For all potential options, see " + - "https://doc.rust-lang.org/rustc/codegen-options/index.html#strip" - ), - default = { - "dbg": "none", - "fastbuild": "none", - "opt": "debuginfo", - }, + doc = "Per-toolchain strip-level overrides per compilation mode. Any mode set here takes precedence over the global `//rust/settings:strip_level_*` flags. Omit a mode (or leave empty) to use the global flag value.", + default = {}, + ), + "_strip_level": attr.label( + default = Label("//rust/settings:strip_level"), + providers = [RustStripLevelInfo], + doc = "Global strip-level defaults, read from the `//rust/settings:strip_level_*` flags.", ), "target_json": attr.string( doc = ("Override the target_triple with a custom target specification. " + diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index bea0816fbe..4409738a0d 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -38,6 +38,7 @@ load( "require_explicit_unstable_features", "rustc_output_diagnostics", "rustfmt_toml", + "strip_level", "third_party_dir", "toolchain_generated_sysroot", "toolchain_linker_preference", @@ -137,6 +138,8 @@ rustc_output_diagnostics() rustfmt_toml() +strip_level() + third_party_dir() toolchain_generated_sysroot() diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index e68868ee42..86d371a363 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -19,6 +19,7 @@ load( load("//rust/private:debug_info.bzl", "rust_debug_info_flag") load("//rust/private:lto.bzl", "rust_lto_flag") load("//rust/private:opt_level.bzl", "rust_opt_level_flag") +load("//rust/private:strip_level.bzl", "rust_strip_level_flag") load( "//rust/private:rustc.bzl", _always_enable_metadata_output_groups = "always_enable_metadata_output_groups", @@ -138,6 +139,41 @@ def debug_info(): name = "debug_info", ) +# buildifier: disable=unnamed-macro +def strip_level(): + """Build settings to control the rustc strip level per compilation mode. + + Each flag accepts one of `"none"`, `"debuginfo"`, or `"symbols"` and sets + the default strip level for all toolchains that do not explicitly override + it via the `strip_level` attribute. + + Defaults match Bazel's conventional compilation modes: `dbg` and `fastbuild` + use `none` (no stripping), `opt` uses `debuginfo` (strip debug info). + + Override from the command line: + + ``` + build --@rules_rust//rust/settings:strip_level_dbg=debuginfo + build --@rules_rust//rust/settings:strip_level_opt=symbols + build --@rules_rust//rust/settings:strip_level_fastbuild=debuginfo + ``` + """ + string_flag( + name = "strip_level_dbg", + build_setting_default = "none", + ) + string_flag( + name = "strip_level_opt", + build_setting_default = "debuginfo", + ) + string_flag( + name = "strip_level_fastbuild", + build_setting_default = "none", + ) + rust_strip_level_flag( + name = "strip_level", + ) + def rename_first_party_crates(): """A flag controlling whether to rename first-party crates such that their names \ encode the Bazel package and target name, instead of just the target name. diff --git a/test/unit/strip_level/strip_level_test_suite.bzl b/test/unit/strip_level/strip_level_test_suite.bzl index a4b6b30171..233be6d3bf 100644 --- a/test/unit/strip_level/strip_level_test_suite.bzl +++ b/test/unit/strip_level/strip_level_test_suite.bzl @@ -49,6 +49,39 @@ _strip_level_for_opt_test = analysistest.make( }, ) +def _strip_level_dbg_setting_test_impl(ctx): + return _strip_level_test_impl(ctx, "symbols") + +_strip_level_dbg_setting_test = analysistest.make( + _strip_level_dbg_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "dbg", + str(Label("//rust/settings:strip_level_dbg")): "symbols", + }, +) + +def _strip_level_opt_setting_test_impl(ctx): + return _strip_level_test_impl(ctx, "symbols") + +_strip_level_opt_setting_test = analysistest.make( + _strip_level_opt_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "opt", + str(Label("//rust/settings:strip_level_opt")): "symbols", + }, +) + +def _strip_level_fastbuild_setting_test_impl(ctx): + return _strip_level_test_impl(ctx, "debuginfo") + +_strip_level_fastbuild_setting_test = analysistest.make( + _strip_level_fastbuild_setting_test_impl, + config_settings = { + "//command_line_option:compilation_mode": "fastbuild", + str(Label("//rust/settings:strip_level_fastbuild")): "debuginfo", + }, +) + def strip_level_test_suite(name): """Entry-point macro called from the BUILD file. @@ -85,11 +118,29 @@ def strip_level_test_suite(name): target_under_test = ":bin", ) + _strip_level_dbg_setting_test( + name = "strip_level_dbg_setting_test", + target_under_test = ":bin", + ) + + _strip_level_opt_setting_test( + name = "strip_level_opt_setting_test", + target_under_test = ":bin", + ) + + _strip_level_fastbuild_setting_test( + name = "strip_level_fastbuild_setting_test", + target_under_test = ":bin", + ) + native.test_suite( name = name, tests = [ ":strip_level_for_dbg_test", ":strip_level_for_fastbuild_test", ":strip_level_for_opt_test", + ":strip_level_dbg_setting_test", + ":strip_level_opt_setting_test", + ":strip_level_fastbuild_setting_test", ], ) From 485afca9a328d6738a0fab5de39f6187b2f43f60 Mon Sep 17 00:00:00 2001 From: Marc Nijweide Date: Fri, 26 Jun 2026 10:29:38 +0200 Subject: [PATCH 4/7] Replace runtime checks with unit tests since defaults are hardcoded. --- rust/private/toolchain.bzl | 7 ---- .../debug_info/debug_info_analysis_test.bzl | 32 +++++++++++++++++ test/unit/opt_level/opt_level_test_suite.bzl | 34 ++++++++++++++++++- .../strip_level/strip_level_test_suite.bzl | 34 ++++++++++++++++++- 4 files changed, 98 insertions(+), 9 deletions(-) diff --git a/rust/private/toolchain.bzl b/rust/private/toolchain.bzl index 72da30af96..c645a5376d 100644 --- a/rust/private/toolchain.bzl +++ b/rust/private/toolchain.bzl @@ -407,14 +407,7 @@ def _rust_toolchain_impl(ctx): compilation_mode_opts = {} for k, opt_level in effective_opt_levels.items(): - if not k in effective_debug_info: - fail("Compilation mode {} is not defined in debug_info but is defined in opt_level".format(k)) - if not k in effective_strip_level: - fail("Compilation mode {} is not defined in strip_level but is defined in opt_level".format(k)) compilation_mode_opts[k] = struct(debug_info = effective_debug_info[k], opt_level = opt_level, strip_level = effective_strip_level[k]) - for k in effective_debug_info.keys(): - if not k in effective_opt_levels: - fail("Compilation mode {} is not defined in opt_level but is defined in debug_info".format(k)) rename_first_party_crates = ctx.attr._rename_first_party_crates[BuildSettingInfo].value third_party_dir = ctx.attr._third_party_dir[BuildSettingInfo].value diff --git a/test/unit/debug_info/debug_info_analysis_test.bzl b/test/unit/debug_info/debug_info_analysis_test.bzl index 6aa925507b..e5b50d24c8 100644 --- a/test/unit/debug_info/debug_info_analysis_test.bzl +++ b/test/unit/debug_info/debug_info_analysis_test.bzl @@ -3,12 +3,38 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary", "rust_shared_library", "rust_test") +load("//rust/private:debug_info.bzl", "RustDebugInfoInfo") +load("//rust/private:opt_level.bzl", "RustOptLevelInfo") +load("//rust/private:strip_level.bzl", "RustStripLevelInfo") load( "//test/unit:common.bzl", "assert_action_mnemonic", "assert_argv_contains", ) +def _debug_info_modes_match_test_impl(ctx): + env = analysistest.begin(ctx) + debug_modes = sorted(analysistest.target_under_test(env)[RustDebugInfoInfo].levels.keys()) + opt_modes = sorted(ctx.attr._opt_level[RustOptLevelInfo].levels.keys()) + strip_modes = sorted(ctx.attr._strip_level[RustStripLevelInfo].levels.keys()) + asserts.equals(env, debug_modes, opt_modes, "debug_info and opt_level compilation modes must match") + asserts.equals(env, debug_modes, strip_modes, "debug_info and strip_level compilation modes must match") + return analysistest.end(env) + +_debug_info_modes_match_test = analysistest.make( + _debug_info_modes_match_test_impl, + attrs = { + "_opt_level": attr.label( + default = "//rust/settings:opt_level", + providers = [RustOptLevelInfo], + ), + "_strip_level": attr.label( + default = "//rust/settings:strip_level", + providers = [RustStripLevelInfo], + ), + }, +) + def _pdb_file_test_impl(ctx, expect_pdb_file): env = analysistest.begin(ctx) target = analysistest.target_under_test(env) @@ -248,6 +274,11 @@ def debug_info_analysis_test_suite(name): target_compatible_with = ["@platforms//os:macos"], ) + _debug_info_modes_match_test( + name = "debug_info_modes_match_test", + target_under_test = "//rust/settings:debug_info", + ) + write_file( name = "flag_bin_main", out = "flag_main.rs", @@ -299,6 +330,7 @@ def debug_info_analysis_test_suite(name): ":lib_dsym_test", ":bin_dsym_test", ":test_dsym_test", + ":debug_info_modes_match_test", ":debug_info_for_dbg_test", ":debug_info_for_fastbuild_test", ":debug_info_for_opt_test", diff --git a/test/unit/opt_level/opt_level_test_suite.bzl b/test/unit/opt_level/opt_level_test_suite.bzl index 1a0ae80613..be06d0a6dd 100644 --- a/test/unit/opt_level/opt_level_test_suite.bzl +++ b/test/unit/opt_level/opt_level_test_suite.bzl @@ -1,8 +1,11 @@ """Starlark tests for `rust_toolchain.opt_level`""" -load("@bazel_skylib//lib:unittest.bzl", "analysistest") +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary") +load("//rust/private:debug_info.bzl", "RustDebugInfoInfo") +load("//rust/private:opt_level.bzl", "RustOptLevelInfo") +load("//rust/private:strip_level.bzl", "RustStripLevelInfo") load( "//test/unit:common.bzl", "assert_action_mnemonic", @@ -104,6 +107,29 @@ _opt_level_minsize_setting_test = analysistest.make( }, ) +def _opt_level_modes_match_test_impl(ctx): + env = analysistest.begin(ctx) + opt_modes = sorted(analysistest.target_under_test(env)[RustOptLevelInfo].levels.keys()) + debug_modes = sorted(ctx.attr._debug_info[RustDebugInfoInfo].levels.keys()) + strip_modes = sorted(ctx.attr._strip_level[RustStripLevelInfo].levels.keys()) + asserts.equals(env, opt_modes, debug_modes, "opt_level and debug_info compilation modes must match") + asserts.equals(env, opt_modes, strip_modes, "opt_level and strip_level compilation modes must match") + return analysistest.end(env) + +_opt_level_modes_match_test = analysistest.make( + _opt_level_modes_match_test_impl, + attrs = { + "_debug_info": attr.label( + default = "//rust/settings:debug_info", + providers = [RustDebugInfoInfo], + ), + "_strip_level": attr.label( + default = "//rust/settings:strip_level", + providers = [RustStripLevelInfo], + ), + }, +) + def opt_level_test_suite(name): """Entry-point macro called from the BUILD file. @@ -165,6 +191,11 @@ def opt_level_test_suite(name): target_under_test = ":bin", ) + _opt_level_modes_match_test( + name = "opt_level_modes_match_test", + target_under_test = "//rust/settings:opt_level", + ) + native.test_suite( name = name, tests = [ @@ -176,5 +207,6 @@ def opt_level_test_suite(name): ":opt_level_fastbuild_setting_test", ":opt_level_size_setting_test", ":opt_level_minsize_setting_test", + ":opt_level_modes_match_test", ], ) diff --git a/test/unit/strip_level/strip_level_test_suite.bzl b/test/unit/strip_level/strip_level_test_suite.bzl index 233be6d3bf..2dcb5048f2 100644 --- a/test/unit/strip_level/strip_level_test_suite.bzl +++ b/test/unit/strip_level/strip_level_test_suite.bzl @@ -1,8 +1,11 @@ """Starlark tests for `rust_toolchain.strip_level`""" -load("@bazel_skylib//lib:unittest.bzl", "analysistest") +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//rust:defs.bzl", "rust_binary") +load("//rust/private:debug_info.bzl", "RustDebugInfoInfo") +load("//rust/private:opt_level.bzl", "RustOptLevelInfo") +load("//rust/private:strip_level.bzl", "RustStripLevelInfo") load( "//test/unit:common.bzl", "assert_action_mnemonic", @@ -49,6 +52,29 @@ _strip_level_for_opt_test = analysistest.make( }, ) +def _strip_level_modes_match_test_impl(ctx): + env = analysistest.begin(ctx) + strip_modes = sorted(analysistest.target_under_test(env)[RustStripLevelInfo].levels.keys()) + opt_modes = sorted(ctx.attr._opt_level[RustOptLevelInfo].levels.keys()) + debug_modes = sorted(ctx.attr._debug_info[RustDebugInfoInfo].levels.keys()) + asserts.equals(env, strip_modes, opt_modes, "strip_level and opt_level compilation modes must match") + asserts.equals(env, strip_modes, debug_modes, "strip_level and debug_info compilation modes must match") + return analysistest.end(env) + +_strip_level_modes_match_test = analysistest.make( + _strip_level_modes_match_test_impl, + attrs = { + "_opt_level": attr.label( + default = "//rust/settings:opt_level", + providers = [RustOptLevelInfo], + ), + "_debug_info": attr.label( + default = "//rust/settings:debug_info", + providers = [RustDebugInfoInfo], + ), + }, +) + def _strip_level_dbg_setting_test_impl(ctx): return _strip_level_test_impl(ctx, "symbols") @@ -103,6 +129,11 @@ def strip_level_test_suite(name): edition = "2021", ) + _strip_level_modes_match_test( + name = "strip_level_modes_match_test", + target_under_test = "//rust/settings:strip_level", + ) + _strip_level_for_dbg_test( name = "strip_level_for_dbg_test", target_under_test = ":bin", @@ -136,6 +167,7 @@ def strip_level_test_suite(name): native.test_suite( name = name, tests = [ + ":strip_level_modes_match_test", ":strip_level_for_dbg_test", ":strip_level_for_fastbuild_test", ":strip_level_for_opt_test", From a4a8931c82cdce755a777b0f07b1bc1516daf54f Mon Sep 17 00:00:00 2001 From: Marc Nijweide Date: Fri, 26 Jun 2026 10:39:09 +0200 Subject: [PATCH 5/7] Updated documentation --- rust/settings/settings.bzl | 60 +++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index 86d371a363..3bfeca028b 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -74,17 +74,23 @@ def lto(): def opt_level(): """Build settings to control the rustc optimization level per compilation mode. - Each flag sets the default opt-level for all toolchains that do not explicitly - override it viathe `opt_level` attribute. + Three flags are defined, one per Bazel compilation mode. Accepted values are + documented at https://doc.rust-lang.org/rustc/codegen-options/index.html#opt-level. + The value sets the default for all toolchains that do not explicitly override + it via the `opt_level` attribute on `rust_toolchain`. - Defaults match Bazel's conventional compilation modes: `dbg` and `fastbuild` - use level 0 (no optimization), `opt` uses level 3 (full optimization). + | Flag | Compilation mode | Default | + |---------------------------------------------------|------------------|---------| + | `@rules_rust//rust/settings:opt_level_dbg` | `dbg` | `"0"` | + | `@rules_rust//rust/settings:opt_level_fastbuild` | `fastbuild` | `"0"` | + | `@rules_rust//rust/settings:opt_level_opt` | `opt` | `"3"` | - Override from the command line: + Example: + + Enable size optimization in `opt` mode and light optimization in `fastbuild`: ``` - build --@rules_rust//rust/settings:opt_level_dbg=1 - build --@rules_rust//rust/settings:opt_level_opt=2 + build --@rules_rust//rust/settings:opt_level_opt=s build --@rules_rust//rust/settings:opt_level_fastbuild=1 ``` """ @@ -108,18 +114,22 @@ def opt_level(): def debug_info(): """Build settings to control the rustc debug info level per compilation mode. - Each flag accepts one of `"0"`, `"1"`, or `"2"` and sets the default - debug-info level for all toolchains that do not explicitly override it via - the `debug_info` attribute. + Three flags are defined, one per Bazel compilation mode. Accepted values are + documented at https://doc.rust-lang.org/rustc/codegen-options/index.html#debuginfo. + The value sets the default for all toolchains that do not explicitly override + it via the `debug_info` attribute on `rust_toolchain`. + + | Flag | Compilation mode | Default | + |-----------------------------------------------------|------------------|---------| + | `@rules_rust//rust/settings:debug_info_dbg` | `dbg` | `"2"` | + | `@rules_rust//rust/settings:debug_info_fastbuild` | `fastbuild` | `"0"` | + | `@rules_rust//rust/settings:debug_info_opt` | `opt` | `"0"` | - Defaults match Bazel's conventional compilation modes: `dbg` uses level 2 - (full debug info), `fastbuild` and `opt` use level 0 (no debug info). + Example: - Override from the command line: + Emit line tables in `fastbuild` mode for profiling without full debug info: ``` - build --@rules_rust//rust/settings:debug_info_dbg=1 - build --@rules_rust//rust/settings:debug_info_opt=1 build --@rules_rust//rust/settings:debug_info_fastbuild=1 ``` """ @@ -143,19 +153,23 @@ def debug_info(): def strip_level(): """Build settings to control the rustc strip level per compilation mode. - Each flag accepts one of `"none"`, `"debuginfo"`, or `"symbols"` and sets - the default strip level for all toolchains that do not explicitly override - it via the `strip_level` attribute. + Three flags are defined, one per Bazel compilation mode. Accepted values are + documented at https://doc.rust-lang.org/rustc/codegen-options/index.html#strip. + The value sets the default for all toolchains that do not explicitly override + it via the `strip_level` attribute on `rust_toolchain`. + + | Flag | Compilation mode | Default | + |-----------------------------------------------------|------------------|----------------| + | `@rules_rust//rust/settings:strip_level_dbg` | `dbg` | `"none"` | + | `@rules_rust//rust/settings:strip_level_fastbuild` | `fastbuild` | `"none"` | + | `@rules_rust//rust/settings:strip_level_opt` | `opt` | `"debuginfo"` | - Defaults match Bazel's conventional compilation modes: `dbg` and `fastbuild` - use `none` (no stripping), `opt` uses `debuginfo` (strip debug info). + Example: - Override from the command line: + Strip all symbols in `opt` mode to minimize binary size: ``` - build --@rules_rust//rust/settings:strip_level_dbg=debuginfo build --@rules_rust//rust/settings:strip_level_opt=symbols - build --@rules_rust//rust/settings:strip_level_fastbuild=debuginfo ``` """ string_flag( From ed5b52ccd400544debaa9c3319cdf60f6ba3c121 Mon Sep 17 00:00:00 2001 From: Marc Nijweide Date: Fri, 26 Jun 2026 11:18:21 +0200 Subject: [PATCH 6/7] Updated consistency so debug_info now flows through the rust_register_toolchains to rust_toolchain in the same way as opt_level and strip_level. --- rust/private/debug_info.bzl | 4 ++-- rust/private/opt_level.bzl | 4 ++-- rust/private/repositories.bzl | 13 +++++++++++++ rust/private/repository_utils.bzl | 4 ++++ rust/private/strip_level.bzl | 4 ++-- rust/private/toolchain.bzl | 2 +- test/unit/debug_info/debug_info_analysis_test.bzl | 2 +- 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/rust/private/debug_info.bzl b/rust/private/debug_info.bzl index b2fd91d3e4..72c2f745bc 100644 --- a/rust/private/debug_info.bzl +++ b/rust/private/debug_info.bzl @@ -19,8 +19,8 @@ rust_debug_info_flag = rule( doc = "Aggregates the three per-mode debug-info flags into a single RustDebugInfoInfo provider. Valid values are defined by rustc: https://doc.rust-lang.org/rustc/codegen-options/index.html#debuginfo.", implementation = _rust_debug_info_flag_impl, attrs = { - "dbg": attr.label(default = "//rust/settings:debug_info_dbg"), + "dbg": attr.label(default = "//rust/settings:debug_info_dbg"), "fastbuild": attr.label(default = "//rust/settings:debug_info_fastbuild"), - "opt": attr.label(default = "//rust/settings:debug_info_opt"), + "opt": attr.label(default = "//rust/settings:debug_info_opt"), }, ) \ No newline at end of file diff --git a/rust/private/opt_level.bzl b/rust/private/opt_level.bzl index 10a3859de0..701d8506db 100644 --- a/rust/private/opt_level.bzl +++ b/rust/private/opt_level.bzl @@ -19,8 +19,8 @@ rust_opt_level_flag = rule( doc = "Aggregates the three per-mode opt-level flags into a single RustOptLevelInfo provider. Valid values are defined by rustc: https://doc.rust-lang.org/rustc/codegen-options/index.html#opt-level", implementation = _rust_opt_level_flag_impl, attrs = { - "dbg": attr.label(default = "//rust/settings:opt_level_dbg"), + "dbg": attr.label(default = "//rust/settings:opt_level_dbg"), "fastbuild": attr.label(default = "//rust/settings:opt_level_fastbuild"), - "opt": attr.label(default = "//rust/settings:opt_level_opt"), + "opt": attr.label(default = "//rust/settings:opt_level_opt"), }, ) \ No newline at end of file diff --git a/rust/private/repositories.bzl b/rust/private/repositories.bzl index cc463eb40a..a38eea45e3 100644 --- a/rust/private/repositories.bzl +++ b/rust/private/repositories.bzl @@ -64,6 +64,7 @@ def rust_register_toolchains( extra_rustc_flags = None, extra_exec_rustc_flags = None, opt_level = None, + debug_info = None, strip_level = None, urls = DEFAULT_STATIC_RUST_URL_TEMPLATES, versions = _RUST_TOOLCHAIN_VERSIONS, @@ -103,6 +104,7 @@ def rust_register_toolchains( extra_rustc_flags (dict, list, optional): Dictionary of target triples to list of extra flags to pass to rustc in non-exec configuration. extra_exec_rustc_flags (dict, list, optional): Dictionary of target triples to list of extra flags to pass to rustc in exec configuration. opt_level (dict, optional): Rustc optimization levels. For more details see the documentation for `rust_toolchain.opt_level`. + debug_info (dict, optional): Dictionary of target triples to debug info config. strip_level (dict, dict, optional): Dictionary of target triples to strip config. urls (list, optional): A list of mirror urls containing the tools from the Rust-lang static file server. These must contain the '{}' used to substitute the tool being fetched (using .format). versions (list, optional): A list of toolchain versions to download. This parameter only accepts one versions @@ -187,6 +189,7 @@ def rust_register_toolchains( extra_rustc_flags = extra_rustc_flags, extra_exec_rustc_flags = extra_exec_rustc_flags, opt_level = opt_level_by_triple, + debug_info = debug_info, strip_level = strip_level, sha256s = sha256s, urls = urls, @@ -275,6 +278,9 @@ _RUST_TOOLCHAIN_REPOSITORY_ATTRS = { "auth_patterns": attr.string_list( doc = "A list of patterns to match against urls for which the auth object should be used.", ), + "debug_info": attr.string_dict( + doc = "Rustc debug info levels. For more details see the documentation for `rust_toolchain.debug_info`.", + ), "dev_components": attr.bool( doc = "Whether to download the rustc-dev components (defaults to False). Requires version to be \"nightly\".", default = False, @@ -483,6 +489,7 @@ def _rust_toolchain_tools_repository_impl(ctx): extra_rustc_flags = ctx.attr.extra_rustc_flags, extra_exec_rustc_flags = ctx.attr.extra_exec_rustc_flags, opt_level = ctx.attr.opt_level if ctx.attr.opt_level else None, + debug_info = ctx.attr.debug_info if ctx.attr.debug_info else None, strip_level = ctx.attr.strip_level if ctx.attr.strip_level else None, version = toolchain_version, channel = channel, @@ -595,6 +602,7 @@ def rust_toolchain_repository( extra_rustc_flags = None, extra_exec_rustc_flags = None, opt_level = None, + debug_info = None, strip_level = None, sha256s = None, urls = DEFAULT_STATIC_RUST_URL_TEMPLATES, @@ -627,6 +635,7 @@ def rust_toolchain_repository( Subject to Make variable expansion with respect to RUST_SYSROOT, RUST_SYSROOT_SHORT, RUSTC, etc. opt_level (dict, optional): Optimization level config for this toolchain. + debug_info (dict, optional): Debug info level config for this toolchain. strip_level (dict, optional): Strip level config for this toolchain. sha256s (str, optional): A dict associating tool subdirectories to sha256 hashes. See [rust_register_toolchains](#rust_register_toolchains) for more details. @@ -660,6 +669,7 @@ def rust_toolchain_repository( extra_rustc_flags = extra_rustc_flags, extra_exec_rustc_flags = extra_exec_rustc_flags, opt_level = opt_level, + debug_info = debug_info, strip_level = strip_level, sha256s = sha256s, urls = urls, @@ -993,6 +1003,7 @@ def rust_repository_set( extra_rustc_flags = None, extra_exec_rustc_flags = None, opt_level = None, + debug_info = None, strip_level = None, sha256s = None, urls = DEFAULT_STATIC_RUST_URL_TEMPLATES, @@ -1026,6 +1037,7 @@ def rust_repository_set( extra_rustc_flags (dict, list, optional): Dictionary of target triples to list of extra flags to pass to rustc in non-exec configuration. extra_exec_rustc_flags (dict, list, optional): Dictionary of target triples to list of extra flags to pass to rustc in exec configuration. opt_level (dict, dict, optional): Dictionary of target triples to optimization config. + debug_info (dict, dict, optional): Dictionary of target triples to debug info config. strip_level (dict, dict, optional): Dictionary of target triples to strip config. sha256s (str, optional): A dict associating tool subdirectories to sha256 hashes. See [rust_register_toolchains](#rust_register_toolchains) for more details. @@ -1083,6 +1095,7 @@ def rust_repository_set( extra_rustc_flags = toolchain_extra_rustc_flags, extra_exec_rustc_flags = toolchain_extra_exec_rustc_flags, opt_level = opt_level.get(toolchain.target_triple) if opt_level != None else None, + debug_info = debug_info.get(toolchain.target_triple) if debug_info != None else None, strip_level = strip_level.get(toolchain.target_triple) if strip_level != None else None, sha256s = sha256s, urls = urls, diff --git a/rust/private/repository_utils.bzl b/rust/private/repository_utils.bzl index c1084bf60d..306ba3f120 100644 --- a/rust/private/repository_utils.bzl +++ b/rust/private/repository_utils.bzl @@ -367,6 +367,7 @@ rust_toolchain( extra_rustc_flags = {extra_rustc_flags}, extra_exec_rustc_flags = {extra_exec_rustc_flags}, opt_level = {opt_level}, + debug_info = {debug_info}, strip_level = {strip_level}, version = "{version}", channel = "{channel}", @@ -393,6 +394,7 @@ def BUILD_for_rust_toolchain( extra_rustc_flags = None, extra_exec_rustc_flags = None, opt_level = None, + debug_info = None, strip_level = None): """Emits a toolchain declaration to match an existing compiler and stdlib. @@ -418,6 +420,7 @@ def BUILD_for_rust_toolchain( extra_rustc_flags (list, optional): Extra flags to pass to rustc in non-exec configuration. extra_exec_rustc_flags (list, optional): Extra flags to pass to rustc in exec configuration. opt_level (dict, optional): Optimization level config for this toolchain. + debug_info (dict, optional): Debug info level config for this toolchain. strip_level (dict, optional): Strip level config for this toolchain. Returns: @@ -480,6 +483,7 @@ def BUILD_for_rust_toolchain( extra_rustc_flags = extra_rustc_flags, extra_exec_rustc_flags = extra_exec_rustc_flags, opt_level = opt_level, + debug_info = debug_info, strip_level = strip_level, version = version, channel = channel, diff --git a/rust/private/strip_level.bzl b/rust/private/strip_level.bzl index 3ec9a92aec..a404d11c5e 100644 --- a/rust/private/strip_level.bzl +++ b/rust/private/strip_level.bzl @@ -19,8 +19,8 @@ rust_strip_level_flag = rule( doc = "Aggregates the three per-mode strip-level flags into a single RustStripLevelInfo provider. Valid values are defined by rustc: https://doc.rust-lang.org/rustc/codegen-options/index.html#strip", implementation = _rust_strip_level_flag_impl, attrs = { - "dbg": attr.label(default = "//rust/settings:strip_level_dbg"), + "dbg": attr.label(default = "//rust/settings:strip_level_dbg"), "fastbuild": attr.label(default = "//rust/settings:strip_level_fastbuild"), - "opt": attr.label(default = "//rust/settings:strip_level_opt"), + "opt": attr.label(default = "//rust/settings:strip_level_opt"), }, ) \ No newline at end of file diff --git a/rust/private/toolchain.bzl b/rust/private/toolchain.bzl index c645a5376d..6eec84b082 100644 --- a/rust/private/toolchain.bzl +++ b/rust/private/toolchain.bzl @@ -808,7 +808,7 @@ rust_toolchain = rule( "_opt_level": attr.label( default = Label("//rust/settings:opt_level"), providers = [RustOptLevelInfo], - doc = "Global opt-level defaults, read from the `//rust/settings:opt_level_*` int flags.", + doc = "Global opt-level defaults, read from the `//rust/settings:opt_level_*` flags.", ), "per_crate_rustc_flags": attr.string_list( doc = "Extra flags to pass to rustc in non-exec configuration", diff --git a/test/unit/debug_info/debug_info_analysis_test.bzl b/test/unit/debug_info/debug_info_analysis_test.bzl index e5b50d24c8..ae9338620b 100644 --- a/test/unit/debug_info/debug_info_analysis_test.bzl +++ b/test/unit/debug_info/debug_info_analysis_test.bzl @@ -1,4 +1,4 @@ -"""Analysis tests for debug info in cdylib and bin targets.""" +"""Analysis tests for debug info: output files (PDB, dSYM) and global flag defaults.""" load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@bazel_skylib//rules:write_file.bzl", "write_file") From 441b90a46e59c7666e566d8b1aa9dc17ac74d022 Mon Sep 17 00:00:00 2001 From: Marc Nijweide Date: Fri, 26 Jun 2026 11:35:41 +0200 Subject: [PATCH 7/7] Updated formatting --- rust/private/debug_info.bzl | 2 +- rust/private/opt_level.bzl | 2 +- rust/private/strip_level.bzl | 2 +- rust/private/toolchain.bzl | 2 +- rust/settings/BUILD.bazel | 2 +- rust/settings/settings.bzl | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rust/private/debug_info.bzl b/rust/private/debug_info.bzl index 72c2f745bc..cb9e8234bc 100644 --- a/rust/private/debug_info.bzl +++ b/rust/private/debug_info.bzl @@ -23,4 +23,4 @@ rust_debug_info_flag = rule( "fastbuild": attr.label(default = "//rust/settings:debug_info_fastbuild"), "opt": attr.label(default = "//rust/settings:debug_info_opt"), }, -) \ No newline at end of file +) diff --git a/rust/private/opt_level.bzl b/rust/private/opt_level.bzl index 701d8506db..c32b07f13f 100644 --- a/rust/private/opt_level.bzl +++ b/rust/private/opt_level.bzl @@ -23,4 +23,4 @@ rust_opt_level_flag = rule( "fastbuild": attr.label(default = "//rust/settings:opt_level_fastbuild"), "opt": attr.label(default = "//rust/settings:opt_level_opt"), }, -) \ No newline at end of file +) diff --git a/rust/private/strip_level.bzl b/rust/private/strip_level.bzl index a404d11c5e..56b1647659 100644 --- a/rust/private/strip_level.bzl +++ b/rust/private/strip_level.bzl @@ -23,4 +23,4 @@ rust_strip_level_flag = rule( "fastbuild": attr.label(default = "//rust/settings:strip_level_fastbuild"), "opt": attr.label(default = "//rust/settings:strip_level_opt"), }, -) \ No newline at end of file +) diff --git a/rust/private/toolchain.bzl b/rust/private/toolchain.bzl index 6eec84b082..f325763ab4 100644 --- a/rust/private/toolchain.bzl +++ b/rust/private/toolchain.bzl @@ -11,12 +11,12 @@ load("//rust/private:common.bzl", "rust_common") load("//rust/private:debug_info.bzl", "RustDebugInfoInfo") load("//rust/private:lto.bzl", "RustLtoInfo") load("//rust/private:opt_level.bzl", "RustOptLevelInfo") -load("//rust/private:strip_level.bzl", "RustStripLevelInfo") load( "//rust/private:rust_allocator_libraries.bzl", "make_libstd_and_allocator_ccinfo", ) load("//rust/private:semver.bzl", "semver") +load("//rust/private:strip_level.bzl", "RustStripLevelInfo") load( "//rust/private:utils.bzl", "deduplicate", diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index 4409738a0d..f3a8ad344e 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -10,6 +10,7 @@ load( "clippy_toml", "codegen_units", "collect_cfgs", + "debug_info", "default_allocator_library", "error_format", "experimental_compile_rustdoc_tests", @@ -29,7 +30,6 @@ load( "incompatible_change_clippy_error_format", "incompatible_do_not_include_data_in_compile_data", "incompatible_do_not_include_transitive_data_in_compile_inputs", - "debug_info", "lto", "no_std", "opt_level", diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index 3bfeca028b..8f740d483a 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -19,7 +19,6 @@ load( load("//rust/private:debug_info.bzl", "rust_debug_info_flag") load("//rust/private:lto.bzl", "rust_lto_flag") load("//rust/private:opt_level.bzl", "rust_opt_level_flag") -load("//rust/private:strip_level.bzl", "rust_strip_level_flag") load( "//rust/private:rustc.bzl", _always_enable_metadata_output_groups = "always_enable_metadata_output_groups", @@ -35,6 +34,7 @@ load( _rustc_output_diagnostics = "rustc_output_diagnostics", _zself_profile_events = "zself_profile_events", ) +load("//rust/private:strip_level.bzl", "rust_strip_level_flag") load("//rust/private:unpretty.bzl", "UNPRETTY_MODES", "rust_unpretty_flag") load(":incompatible.bzl", "incompatible_flag")