Skip to content

Commit 6fdce6d

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 c3d71ed commit 6fdce6d

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
@@ -1218,6 +1218,13 @@ def rustc_compile_action(
12181218
if experimental_use_cc_common_link:
12191219
emit = ["obj"]
12201220

1221+
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()
1222+
if use_split_debuginfo:
1223+
rust_flags = rust_flags + [
1224+
"--codegen=split-debuginfo=unpacked",
1225+
"--codegen=debuginfo=full",
1226+
]
1227+
12211228
args, env_from_args = construct_arguments(
12221229
ctx = ctx,
12231230
attr = attr,
@@ -1318,6 +1325,13 @@ def rustc_compile_action(
13181325
elif toolchain.target_os == "darwin":
13191326
dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM", sibling = crate_info.output)
13201327
action_outputs.append(dsym_folder)
1328+
if use_split_debuginfo:
1329+
fission_directory = crate_info.name + "_fission"
1330+
if output_hash:
1331+
fission_directory = fission_directory + output_hash
1332+
dwo_outputs = ctx.actions.declare_directory(fission_directory, sibling = crate_info.output)
1333+
args.process_wrapper_flags.add("--kludge-move-dwo-to", dwo_outputs.path)
1334+
action_outputs.append(dwo_outputs)
13211335

13221336
if ctx.executable._process_wrapper:
13231337
# Run as normal
@@ -1374,15 +1388,19 @@ def rustc_compile_action(
13741388
else:
13751389
fail("No process wrapper was defined for {}".format(ctx.label))
13761390

1391+
cco_args = {}
13771392
if experimental_use_cc_common_link:
13781393
# Wrap the main `.o` file into a compilation output suitable for
13791394
# cc_common.link. The main `.o` file is useful in both PIC and non-PIC
13801395
# modes.
1381-
compilation_outputs = cc_common.create_compilation_outputs(
1382-
objects = depset([output_o]),
1383-
pic_objects = depset([output_o]),
1384-
)
1385-
1396+
cco_args["objects"] = depset([output_o])
1397+
cco_args["pic_objects"] = depset([output_o])
1398+
if use_split_debuginfo:
1399+
cco_args["dwo_objects"] = depset([dwo_outputs]) # buildifier: disable=uninitialized
1400+
cco_args["pic_dwo_objects"] = depset([dwo_outputs]) # buildifier: disable=uninitialized
1401+
compilation_outputs = cc_common.create_compilation_outputs(**cco_args)
1402+
debug_context = cc_common.create_debug_context(compilation_outputs)
1403+
if experimental_use_cc_common_link:
13861404
malloc_library = ctx.attr._custom_malloc or ctx.attr.malloc
13871405

13881406
# Collect the linking contexts of the standard library and dependencies.
@@ -1527,7 +1545,7 @@ def rustc_compile_action(
15271545
else:
15281546
providers.extend([crate_info, dep_info])
15291547

1530-
providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library)
1548+
providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library, debug_context)
15311549

15321550
output_group_info = {}
15331551

@@ -1583,7 +1601,7 @@ def _collect_nonstatic_linker_inputs(cc_info):
15831601
))
15841602
return shared_linker_inputs
15851603

1586-
def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library):
1604+
def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library, debug_context = None):
15871605
"""If the produced crate is suitable yield a CcInfo to allow for interop with cc rules
15881606
15891607
Args:
@@ -1594,7 +1612,7 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co
15941612
cc_toolchain (CcToolchainInfo): The current `CcToolchainInfo`
15951613
feature_configuration (FeatureConfiguration): Feature configuration to be queried.
15961614
interface_library (File): Optional interface library for cdylib crates on Windows.
1597-
1615+
debug_context (DebugContext): Optional debug context.
15981616
Returns:
15991617
list: A list containing the CcInfo provider
16001618
"""
@@ -1660,7 +1678,10 @@ def establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_co
16601678
)
16611679

16621680
cc_infos = [
1663-
CcInfo(linking_context = linking_context),
1681+
CcInfo(
1682+
linking_context = linking_context,
1683+
debug_context = debug_context,
1684+
),
16641685
toolchain.stdlib_linkflags,
16651686
]
16661687

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);
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)