diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 0894d33e4c..900ef9b09b 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -1224,6 +1224,13 @@ def rustc_compile_action( if experimental_use_cc_common_link: emit = ["obj"] + use_split_debuginfo = 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 use_split_debuginfo: + rust_flags = rust_flags + [ + "--codegen=split-debuginfo=unpacked", + "--codegen=debuginfo=full", + ] + args, env_from_args = construct_arguments( ctx = ctx, attr = attr, @@ -1324,6 +1331,13 @@ def rustc_compile_action( elif toolchain.target_os == "darwin": dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM", sibling = crate_info.output) action_outputs.append(dsym_folder) + if use_split_debuginfo: + fission_directory = crate_info.name + "_fission" + if output_hash: + fission_directory = fission_directory + output_hash + dwo_outputs = ctx.actions.declare_directory(fission_directory, sibling = crate_info.output) + args.process_wrapper_flags.add("--kludge-move-dwo-to", dwo_outputs.path) + action_outputs.append(dwo_outputs) if ctx.executable._process_wrapper: # Run as normal @@ -1382,15 +1396,19 @@ def rustc_compile_action( else: fail("No process wrapper was defined for {}".format(ctx.label)) + cco_args = {} if experimental_use_cc_common_link: # Wrap the main `.o` file into a compilation output suitable for # cc_common.link. The main `.o` file is useful in both PIC and non-PIC # modes. - compilation_outputs = cc_common.create_compilation_outputs( - objects = depset([output_o]), - pic_objects = depset([output_o]), - ) - + cco_args["objects"] = depset([output_o]) + cco_args["pic_objects"] = depset([output_o]) + if use_split_debuginfo: + cco_args["dwo_objects"] = depset([dwo_outputs]) # buildifier: disable=uninitialized + cco_args["pic_dwo_objects"] = depset([dwo_outputs]) # buildifier: disable=uninitialized + compilation_outputs = cc_common.create_compilation_outputs(**cco_args) + debug_context = cc_common.create_debug_context(compilation_outputs) + if experimental_use_cc_common_link: malloc_library = ctx.attr._custom_malloc or ctx.attr.malloc # Collect the linking contexts of the standard library and dependencies. @@ -1535,7 +1553,7 @@ def rustc_compile_action( else: providers.extend([crate_info, dep_info]) - providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library) + providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library, debug_context) output_group_info = {} @@ -1617,7 +1635,7 @@ def _add_codegen_units_flags(toolchain, args): args.add("-Ccodegen-units={}".format(toolchain._codegen_units)) -def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library): +def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library, debug_context = None): """If the produced crate is suitable yield a CcInfo to allow for interop with cc rules Args: @@ -1628,7 +1646,7 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co cc_toolchain (CcToolchainInfo): The current `CcToolchainInfo` feature_configuration (FeatureConfiguration): Feature configuration to be queried. interface_library (File): Optional interface library for cdylib crates on Windows. - + debug_context (DebugContext): Optional debug context. Returns: list: A list containing the CcInfo provider """ @@ -1694,7 +1712,10 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co ) cc_infos = [ - CcInfo(linking_context = linking_context), + CcInfo( + linking_context = linking_context, + debug_context = debug_context, + ), toolchain.stdlib_linkflags, ] diff --git a/util/process_wrapper/main.rs b/util/process_wrapper/main.rs index bf6f6a1b4e..8ced091390 100644 --- a/util/process_wrapper/main.rs +++ b/util/process_wrapper/main.rs @@ -184,6 +184,24 @@ fn main() -> Result<(), ProcessWrapperError> { )) })?; } + if let Some(dwp_destination) = opts.kludge_move_dwo_to { + // find all .dwo files in our out_dir (how do we get that? --out-dir?) + // move them all to dwp_destination + let dest = std::path::Path::new(&dwp_destination); + // Unwrap is okay because we know that --kludge-move-dwo-two will be a child of + // rustc's --out-dir. + let out_dir = dest.parent().unwrap(); + let paths = std::fs::read_dir(out_dir).unwrap(); + for p in paths { + let p = p.unwrap(); + let fn_ = p.file_name(); + let basename = fn_.to_string_lossy(); + if basename.ends_with(".dwo") { + let tgt = dest.join(fn_); + std::fs::rename(p.path(), tgt).map_err(|e| ProcessWrapperError(format!("failed to rename dwo output: {}", e)))?; + } + } + } } exit(code) diff --git a/util/process_wrapper/options.rs b/util/process_wrapper/options.rs index c0f4add011..b7b99c13a5 100644 --- a/util/process_wrapper/options.rs +++ b/util/process_wrapper/options.rs @@ -49,6 +49,8 @@ pub(crate) struct Options { pub(crate) rustc_quit_on_rmeta: bool, // This controls the output format of rustc messages. pub(crate) rustc_output_format: Option, + // If set, move any produced .dwo files into the named directory. + pub(crate) kludge_move_dwo_to: Option, } pub(crate) fn options() -> Result { @@ -67,6 +69,7 @@ pub(crate) fn options() -> Result { let mut rustc_quit_on_rmeta_raw = None; let mut rustc_output_format_raw = None; let mut flags = Flags::new(); + let mut kludge_move_dwo_to = None; flags.define_repeated_flag("--subst", "", &mut subst_mapping_raw); flags.define_flag("--stable-status-file", "", &mut stable_status_file_raw); flags.define_flag("--volatile-status-file", "", &mut volatile_status_file_raw); @@ -114,6 +117,11 @@ pub(crate) fn options() -> Result { Default: `rendered`", &mut rustc_output_format_raw, ); + flags.define_flag( + "--kludge-move-dwo-to", + "If set, move all produced .dwo files to the specified directory.", + &mut kludge_move_dwo_to, + ); let mut child_args = match flags .parse(env::args().collect()) @@ -212,6 +220,7 @@ pub(crate) fn options() -> Result { output_file, rustc_quit_on_rmeta, rustc_output_format, + kludge_move_dwo_to, }) }