Skip to content

Commit cc91a3a

Browse files
committed
rustc: add support for split debuginfo (aka fission)
This requires some helper logic in the process wrapper so we can move dwo files to predictable output locations, but otherwise it's mostly straightforward. This requires a bazel built after d2c79821cd45b30eeaec2efc3bd5fbd26f37d3c2, but that's old enough it landed in bazel 8.
1 parent 5e90483 commit cc91a3a

File tree

3 files changed

+57
-9
lines changed

3 files changed

+57
-9
lines changed

rust/private/rustc.bzl

+30-9
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,13 @@ def rustc_compile_action(
12241224
if experimental_use_cc_common_link:
12251225
emit = ["obj"]
12261226

1227+
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()
1228+
if use_split_debuginfo:
1229+
rust_flags = rust_flags + [
1230+
"--codegen=split-debuginfo=unpacked",
1231+
"--codegen=debuginfo=full",
1232+
]
1233+
12271234
args, env_from_args = construct_arguments(
12281235
ctx = ctx,
12291236
attr = attr,
@@ -1324,6 +1331,13 @@ def rustc_compile_action(
13241331
elif toolchain.target_os == "darwin":
13251332
dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM", sibling = crate_info.output)
13261333
action_outputs.append(dsym_folder)
1334+
if use_split_debuginfo:
1335+
fission_directory = crate_info.name + "_fission"
1336+
if output_hash:
1337+
fission_directory = fission_directory + output_hash
1338+
dwo_outputs = ctx.actions.declare_directory(fission_directory, sibling = crate_info.output)
1339+
args.process_wrapper_flags.add("--kludge-move-dwo-to", dwo_outputs.path)
1340+
action_outputs.append(dwo_outputs)
13271341

13281342
if ctx.executable._process_wrapper:
13291343
# Run as normal
@@ -1382,15 +1396,19 @@ def rustc_compile_action(
13821396
else:
13831397
fail("No process wrapper was defined for {}".format(ctx.label))
13841398

1399+
cco_args = {}
13851400
if experimental_use_cc_common_link:
13861401
# Wrap the main `.o` file into a compilation output suitable for
13871402
# cc_common.link. The main `.o` file is useful in both PIC and non-PIC
13881403
# modes.
1389-
compilation_outputs = cc_common.create_compilation_outputs(
1390-
objects = depset([output_o]),
1391-
pic_objects = depset([output_o]),
1392-
)
1393-
1404+
cco_args["objects"] = depset([output_o])
1405+
cco_args["pic_objects"] = depset([output_o])
1406+
if use_split_debuginfo:
1407+
cco_args["dwo_objects"] = depset([dwo_outputs]) # buildifier: disable=uninitialized
1408+
cco_args["pic_dwo_objects"] = depset([dwo_outputs]) # buildifier: disable=uninitialized
1409+
compilation_outputs = cc_common.create_compilation_outputs(**cco_args)
1410+
debug_context = cc_common.create_debug_context(compilation_outputs)
1411+
if experimental_use_cc_common_link:
13941412
malloc_library = ctx.attr._custom_malloc or ctx.attr.malloc
13951413

13961414
# Collect the linking contexts of the standard library and dependencies.
@@ -1535,7 +1553,7 @@ def rustc_compile_action(
15351553
else:
15361554
providers.extend([crate_info, dep_info])
15371555

1538-
providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library)
1556+
providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library, debug_context)
15391557

15401558
output_group_info = {}
15411559

@@ -1617,7 +1635,7 @@ def _add_codegen_units_flags(toolchain, args):
16171635

16181636
args.add("-Ccodegen-units={}".format(toolchain._codegen_units))
16191637

1620-
def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library):
1638+
def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library, debug_context = None):
16211639
"""If the produced crate is suitable yield a CcInfo to allow for interop with cc rules
16221640
16231641
Args:
@@ -1628,7 +1646,7 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co
16281646
cc_toolchain (CcToolchainInfo): The current `CcToolchainInfo`
16291647
feature_configuration (FeatureConfiguration): Feature configuration to be queried.
16301648
interface_library (File): Optional interface library for cdylib crates on Windows.
1631-
1649+
debug_context (DebugContext): Optional debug context.
16321650
Returns:
16331651
list: A list containing the CcInfo provider
16341652
"""
@@ -1694,7 +1712,10 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co
16941712
)
16951713

16961714
cc_infos = [
1697-
CcInfo(linking_context = linking_context),
1715+
CcInfo(
1716+
linking_context = linking_context,
1717+
debug_context = debug_context,
1718+
),
16981719
toolchain.stdlib_linkflags,
16991720
]
17001721

util/process_wrapper/main.rs

+18
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,24 @@ fn main() -> Result<(), ProcessWrapperError> {
184184
))
185185
})?;
186186
}
187+
if let Some(dwp_destination) = opts.kludge_move_dwo_to {
188+
// find all .dwo files in our out_dir (how do we get that? --out-dir?)
189+
// move them all to dwp_destination
190+
let dest = std::path::Path::new(&dwp_destination);
191+
// Unwrap is okay because we know that --kludge-move-dwo-two will be a child of
192+
// rustc's --out-dir.
193+
let out_dir = dest.parent().unwrap();
194+
let paths = std::fs::read_dir(out_dir).unwrap();
195+
for p in paths {
196+
let p = p.unwrap();
197+
let fn_ = p.file_name();
198+
let basename = fn_.to_string_lossy();
199+
if basename.ends_with(".dwo") {
200+
let tgt = dest.join(fn_);
201+
std::fs::rename(p.path(), tgt).map_err(|e| ProcessWrapperError(format!("failed to rename dwo output: {}", e)))?;
202+
}
203+
}
204+
}
187205
}
188206

189207
exit(code)

util/process_wrapper/options.rs

+9
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ pub(crate) struct Options {
4949
pub(crate) rustc_quit_on_rmeta: bool,
5050
// This controls the output format of rustc messages.
5151
pub(crate) rustc_output_format: Option<rustc::ErrorFormat>,
52+
// If set, move any produced .dwo files into the named directory.
53+
pub(crate) kludge_move_dwo_to: Option<String>,
5254
}
5355

5456
pub(crate) fn options() -> Result<Options, OptionError> {
@@ -67,6 +69,7 @@ pub(crate) fn options() -> Result<Options, OptionError> {
6769
let mut rustc_quit_on_rmeta_raw = None;
6870
let mut rustc_output_format_raw = None;
6971
let mut flags = Flags::new();
72+
let mut kludge_move_dwo_to = None;
7073
flags.define_repeated_flag("--subst", "", &mut subst_mapping_raw);
7174
flags.define_flag("--stable-status-file", "", &mut stable_status_file_raw);
7275
flags.define_flag("--volatile-status-file", "", &mut volatile_status_file_raw);
@@ -114,6 +117,11 @@ pub(crate) fn options() -> Result<Options, OptionError> {
114117
Default: `rendered`",
115118
&mut rustc_output_format_raw,
116119
);
120+
flags.define_flag(
121+
"--kludge-move-dwo-to",
122+
"If set, move all produced .dwo files to the specified directory.",
123+
&mut kludge_move_dwo_to,
124+
);
117125

118126
let mut child_args = match flags
119127
.parse(env::args().collect())
@@ -212,6 +220,7 @@ pub(crate) fn options() -> Result<Options, OptionError> {
212220
output_file,
213221
rustc_quit_on_rmeta,
214222
rustc_output_format,
223+
kludge_move_dwo_to,
215224
})
216225
}
217226

0 commit comments

Comments
 (0)