Skip to content

Commit fe8408f

Browse files
committed
Added more thorough documentation.
1 parent ac5395c commit fe8408f

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

dynamic_instrumentation/src/main.rs

+31-7
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use std::{
2424
env,
2525
ffi::{OsStr, OsString},
2626
path::{Path, PathBuf},
27-
process::{self, Command, ExitStatus},
27+
process::{self, Command, ExitStatus}, iter,
2828
};
2929

3030
use rustc_ast::ast::{Item, ItemKind, Visibility, VisibilityKind};
@@ -119,7 +119,7 @@ fn resolve_sysroot() -> anyhow::Result<PathBuf> {
119119
Ok(path)
120120
}
121121

122-
/// Insert the feature flags as the first arguments following the `cargo` subcommand.
122+
/// Insert feature flags as the first arguments following the `cargo` subcommand.
123123
///
124124
/// We can't insert them at the end because they could come after a `--` and thus be ignored.
125125
/// And we can't insert them at the beginning before the `cargo` subcommand argument,
@@ -129,13 +129,12 @@ fn resolve_sysroot() -> anyhow::Result<PathBuf> {
129129
/// * it would panic on splicing/insertion
130130
/// * we don't want to add the feature flags anyways, as `cargo` without arguments is already an error
131131
/// * we don't want to obfuscate that error with an error about unexpected feature flags
132-
fn add_runtime_feature(cargo_args: &mut Vec<OsString>) {
132+
fn add_feature(cargo_args: &mut Vec<OsString>, features: &[&str]) {
133133
let insertion_point = 1;
134134
if cargo_args.len() >= insertion_point {
135135
cargo_args.splice(
136136
insertion_point..insertion_point,
137-
["--features", "c2rust-analysis-rt"]
138-
.iter()
137+
iter::once(&"--features").chain(features)
139138
.map(|s| s.into()),
140139
);
141140
}
@@ -181,16 +180,24 @@ const RUSTC_WRAPPER_VAR: &str = "RUSTC_WRAPPER";
181180
const RUST_SYSROOT_VAR: &str = "RUST_SYSROOT";
182181
const METADATA_VAR: &str = "C2RUST_INSTRUMENT_METADATA_PATH";
183182

183+
/// Read a [`PathBuf`] from the [`mod@env`]ironment that should've been set by the [`cargo_wrapper`].
184184
fn env_path_from_wrapper(var: &str) -> anyhow::Result<PathBuf> {
185185
let path = env::var_os(var)
186186
.ok_or_else(|| anyhow!("the `cargo` wrapper should've `${var}` for the `rustc` wrapper"))?;
187187
Ok(path.into())
188188
}
189189

190+
/// Check if the current [`rustc_wrapper`] invocation is for the primary `cargo` package,
191+
/// as determined by `$CARGO_PRIMARY_PACKAGE`.
190192
fn is_primary_package() -> bool {
191193
env::var("CARGO_PRIMARY_PACKAGE").is_ok()
192194
}
193195

196+
/// Check if the current [`rustc_wrapper`] invocation is a binary crate,
197+
/// i.e., if `--crate-type bin` was specified.
198+
///
199+
/// This uses the [`rustc_driver`] and [`rustc_session`] APIs
200+
/// to check this exactly as `rustc` would.
194201
fn is_bin_crate(at_args: &[String]) -> anyhow::Result<bool> {
195202
let args = rustc_driver::args::arg_expand_all(at_args);
196203
let matches = rustc_driver::handle_options(&args)
@@ -200,11 +207,16 @@ fn is_bin_crate(at_args: &[String]) -> anyhow::Result<bool> {
200207
Ok(is_bin)
201208
}
202209

210+
/// Read the name of the current binary crate being compiled, if it is a binary crate ([`is_bin_crate`]).
211+
///
212+
/// Note that despite setting `--crate-type bin` and [`is_bin_crate`] being true,
213+
/// there is no name set for build scripts.
214+
/// That's how we can detect them.
203215
fn bin_crate_name() -> Option<PathBuf> {
204216
env::var_os("CARGO_BIN_NAME").map(PathBuf::from)
205217
}
206218

207-
/// Detect if the `rustc` invocation is for compiling a build script.
219+
/// Detect if the current [`rustc_wrapper`] is for compiling a build script.
208220
///
209221
/// `c2rust-analysis-rt` is not yet built for the build script,
210222
/// so trying to compile it will fail.
@@ -240,6 +252,7 @@ fn is_build_script(at_args: &[String]) -> anyhow::Result<bool> {
240252
Ok(bin_crate_name().is_none() && is_bin_crate(at_args)?)
241253
}
242254

255+
/// Run as a `rustc` wrapper (a la `$RUSTC_WRAPPER`/[`RUSTC_WRAPPER_VAR`]).
243256
fn rustc_wrapper() -> anyhow::Result<()> {
244257
let mut at_args = env::args().skip(1).collect::<Vec<_>>();
245258
// We also want to avoid proc-macro crates,
@@ -268,14 +281,18 @@ fn rustc_wrapper() -> anyhow::Result<()> {
268281
Ok(())
269282
}
270283

284+
/// Run as a `cargo` wrapper/plugin, the default invocation.
271285
fn cargo_wrapper(rustc_wrapper: &Path) -> anyhow::Result<()> {
272286
let Args {
273287
metadata,
274288
mut cargo_args,
275289
} = Args::parse();
276290

291+
// Ensure we use a toolchain compatible with the `rustc` private crates we linked to.
277292
env::set_var("RUSTUP_TOOLCHAIN", include_str!("../rust-toolchain").trim());
278293

294+
// Resolve the sysroot once in the [`cargo_wrapper`]
295+
// so that we don't need all of the [`rustc_wrapper`]s to have to do it.
279296
let sysroot = resolve_sysroot()?;
280297

281298
let cargo = Cargo::new();
@@ -286,11 +303,18 @@ fn cargo_wrapper(rustc_wrapper: &Path) -> anyhow::Result<()> {
286303
.ok_or_else(|| anyhow!("no root package found by `cargo`"))?;
287304

288305
cargo.run(|cmd| {
306+
// Clean the primary package so that we always rebuild it
307+
// and get up-to-date, complete instrumentation [`Metadata`].
308+
// Incremental instrumentation is very tricky,
309+
// so don't try that yet,
310+
// and if we only need to rebuild the primary package,
311+
// it usually isn't that slow.
289312
cmd.args(&["clean", "--package", root_package.name.as_str()]);
290313
})?;
291314

292315
cargo.run(|cmd| {
293-
add_runtime_feature(&mut cargo_args);
316+
// Enable the runtime dependency.
317+
add_feature(&mut cargo_args, &["c2rust-analysis-rt"]);
294318
cmd.args(cargo_args)
295319
.env(RUSTC_WRAPPER_VAR, rustc_wrapper)
296320
.env(RUST_SYSROOT_VAR, &sysroot)

0 commit comments

Comments
 (0)