diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index ef902f7e17..4b5c60258d 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1778,11 +1778,22 @@ def rustc_compile_action( elif ctx.attr.require_explicit_unstable_features == -1: require_explicit_unstable_features = toolchain.require_explicit_unstable_features - use_split_debuginfo = ( + use_split_debuginfo = False + if ( feature_configuration and cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "per_object_debug_info") and ctx.fragments.cpp.fission_active_for_current_compilation_mode() - ) + ): + if toolchain._skip_fission_for_rust: + use_split_debuginfo = False + elif toolchain.channel == "nightly": + use_split_debuginfo = True + else: + fail( + "Split debug info (fission) was requested, but `-Zsplit-dwarf-out-dir` requires a nightly Rust toolchain " + + "(current toolchain channel is \"{}\"). ".format(toolchain.channel) + + "To skip fission for Rust objects and suppress this error, set `--@rules_rust//rust/settings:skip_fission_for_rust`.", + ) if use_split_debuginfo: rust_flags = rust_flags + [ "--codegen=split-debuginfo=unpacked", diff --git a/rust/private/toolchain.bzl b/rust/private/toolchain.bzl index 8effcbca4e..7637b618df 100644 --- a/rust/private/toolchain.bzl +++ b/rust/private/toolchain.bzl @@ -647,6 +647,7 @@ def _rust_toolchain_impl(ctx): _experimental_use_cc_common_link = _experimental_use_cc_common_link(ctx), _experimental_use_global_allocator = experimental_use_global_allocator, _experimental_compile_rustdoc_tests = ctx.attr._experimental_compile_rustdoc_tests[BuildSettingInfo].value, + _skip_fission_for_rust = ctx.attr._skip_fission_for_rust[BuildSettingInfo].value, _experimental_use_coverage_metadata_files = ctx.attr._experimental_use_coverage_metadata_files[BuildSettingInfo].value, _toolchain_generated_sysroot = ctx.attr._toolchain_generated_sysroot[BuildSettingInfo].value, _incompatible_do_not_include_data_in_compile_data = ctx.attr._incompatible_do_not_include_data_in_compile_data[IncompatibleFlagInfo].enabled, @@ -925,6 +926,9 @@ rust_toolchain = rule( "_rename_first_party_crates": attr.label( default = Label("//rust/settings:rename_first_party_crates"), ), + "_skip_fission_for_rust": attr.label( + default = Label("//rust/settings:skip_fission_for_rust"), + ), "_third_party_dir": attr.label( default = Label("//rust/settings:third_party_dir"), ), diff --git a/rust/settings/BUILD.bazel b/rust/settings/BUILD.bazel index 375ea537ee..f84e8b519c 100644 --- a/rust/settings/BUILD.bazel +++ b/rust/settings/BUILD.bazel @@ -36,6 +36,7 @@ load( "require_explicit_unstable_features", "rustc_output_diagnostics", "rustfmt_toml", + "skip_fission_for_rust", "third_party_dir", "toolchain_generated_sysroot", "toolchain_linker_preference", @@ -140,3 +141,5 @@ toolchain_linker_preference() unpretty() zself_profile_events() + +skip_fission_for_rust() diff --git a/rust/settings/settings.bzl b/rust/settings/settings.bzl index b6d3494264..90260f13ce 100644 --- a/rust/settings/settings.bzl +++ b/rust/settings/settings.bzl @@ -584,3 +584,11 @@ def zself_profile_events(name = "zself_profile_events"): name = name, build_setting_default = [], ) + +def skip_fission_for_rust(): + """A flag to skip split debug info (Fission) for Rust objects when using a non-nightly toolchain. + """ + bool_flag( + name = "skip_fission_for_rust", + build_setting_default = False, + ) diff --git a/test/unit/debug_info/debug_info_analysis_test.bzl b/test/unit/debug_info/debug_info_analysis_test.bzl index d9fb89c5b1..a79cbb1298 100644 --- a/test/unit/debug_info/debug_info_analysis_test.bzl +++ b/test/unit/debug_info/debug_info_analysis_test.bzl @@ -184,6 +184,37 @@ _FISSION_COMPATIBILITY = ["@platforms//os:linux"] + select({ "//conditions:default": ["@platforms//:incompatible"], }) +# `-Zsplit-dwarf-out-dir` requires nightly. When testing split debug info, +# `skip_fission_for_rust` skips fission on both nightly and non-nightly toolchains. +skip_fission_test = analysistest.make( + _no_fission_test_impl, + config_settings = { + "//command_line_option:features": ["per_object_debug_info"], + "//command_line_option:fission": ["yes"], + str(Label("//rust/settings:skip_fission_for_rust")): True, + }, +) + +def _not_nightly_fission_error_test_impl(ctx): + env = analysistest.begin(ctx) + asserts.expect_failure(env, "skip_fission_for_rust") + return analysistest.end(env) + +not_nightly_fission_error_test = analysistest.make( + _not_nightly_fission_error_test_impl, + expect_failure = True, + config_settings = { + "//command_line_option:features": ["per_object_debug_info"], + "//command_line_option:fission": ["yes"], + }, +) + +_NOT_NIGHTLY_COMPATIBILITY = ["@platforms//os:linux"] + select({ + "//rust/toolchain/channel:beta": [], + "//rust/toolchain/channel:stable": [], + "//conditions:default": ["@platforms//:incompatible"], +}) + def debug_info_analysis_test_suite(name): """Analysis tests for debug info in cdylib and bin targets. @@ -295,6 +326,21 @@ def debug_info_analysis_test_suite(name): name = "lib_no_fission_test", target_under_test = ":mylib", ) + skip_fission_test( + name = "lib_skip_fission_test", + target_under_test = ":mylib", + target_compatible_with = _NOT_NIGHTLY_COMPATIBILITY, + ) + skip_fission_test( + name = "lib_skip_fission_nightly_test", + target_under_test = ":mylib", + target_compatible_with = _FISSION_COMPATIBILITY, + ) + not_nightly_fission_error_test( + name = "lib_not_nightly_fission_error_test", + target_under_test = ":mylib", + target_compatible_with = _NOT_NIGHTLY_COMPATIBILITY, + ) fission_test( name = "bin_fission_test", @@ -305,6 +351,21 @@ def debug_info_analysis_test_suite(name): name = "bin_no_fission_test", target_under_test = ":myrustbin", ) + skip_fission_test( + name = "bin_skip_fission_test", + target_under_test = ":myrustbin", + target_compatible_with = _NOT_NIGHTLY_COMPATIBILITY, + ) + skip_fission_test( + name = "bin_skip_fission_nightly_test", + target_under_test = ":myrustbin", + target_compatible_with = _FISSION_COMPATIBILITY, + ) + not_nightly_fission_error_test( + name = "bin_not_nightly_fission_error_test", + target_under_test = ":myrustbin", + target_compatible_with = _NOT_NIGHTLY_COMPATIBILITY, + ) fission_test( name = "test_fission_test", @@ -315,6 +376,21 @@ def debug_info_analysis_test_suite(name): name = "test_no_fission_test", target_under_test = ":myrusttest", ) + skip_fission_test( + name = "test_skip_fission_test", + target_under_test = ":myrusttest", + target_compatible_with = _NOT_NIGHTLY_COMPATIBILITY, + ) + skip_fission_test( + name = "test_skip_fission_nightly_test", + target_under_test = ":myrusttest", + target_compatible_with = _FISSION_COMPATIBILITY, + ) + not_nightly_fission_error_test( + name = "test_not_nightly_fission_error_test", + target_under_test = ":myrusttest", + target_compatible_with = _NOT_NIGHTLY_COMPATIBILITY, + ) native.test_suite( name = name, @@ -324,10 +400,19 @@ def debug_info_analysis_test_suite(name): ":test_dsym_test", ":lib_fission_test", ":lib_no_fission_test", + ":lib_skip_fission_test", + ":lib_skip_fission_nightly_test", + ":lib_not_nightly_fission_error_test", ":bin_fission_test", ":bin_no_fission_test", + ":bin_skip_fission_test", + ":bin_skip_fission_nightly_test", + ":bin_not_nightly_fission_error_test", ":test_fission_test", ":test_no_fission_test", + ":test_skip_fission_test", + ":test_skip_fission_nightly_test", + ":test_not_nightly_fission_error_test", ] + [ ":lib_pdb_test_{}".format(compilation_mode) for compilation_mode in pdb_file_tests