Skip to content

Commit

Permalink
feat(sandbox): custom build script runner and target platform
Browse files Browse the repository at this point in the history
Add support for `[sandbox]` to specify a target platform
and a custom build script runner.

To help the external runner finds and executes the executable produced
by a build script, it is assumed that only one executable was produced.
  • Loading branch information
weihanglo committed Oct 19, 2024
1 parent 20723a9 commit e0889df
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 12 deletions.
10 changes: 10 additions & 0 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,16 @@ impl<'gctx> RustcTargetData<'gctx> {
res.merge_compile_kind(kind)?;
}

// TODO: Although `-Zsandbox need this target platform to exist,
// if there is no build script involved in the entire dependency tree,
// there is no need for doing this target pre-fetch.
if ws.gctx().cli_unstable().sandbox {
if let Some(target) = gctx.sandbox_config()?.target.as_ref() {
let kind = CompileKind::Target(CompileTarget::new(target)?);
res.merge_compile_kind(kind)?;
}
}

Ok(res)
}

Expand Down
24 changes: 17 additions & 7 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,23 @@ impl<'gctx> Compilation<'gctx> {
cmd: T,
pkg: &Package,
) -> CargoResult<ProcessBuilder> {
self.fill_env(
ProcessBuilder::new(cmd),
pkg,
None,
CompileKind::Host,
ToolKind::HostProcess,
)
let builder = if self.gctx.cli_unstable().sandbox {
let sandbox = self.gctx.sandbox_config()?;
match &sandbox.runner {
Some(runner) => {
let program = runner.path.resolve_program(self.gctx);
let mut builder = ProcessBuilder::new(program);
builder.args(&runner.args);
builder.arg(cmd);
builder
}
None => ProcessBuilder::new(cmd),
}
} else {
ProcessBuilder::new(cmd)
};

self.fill_env(builder, pkg, None, CompileKind::Host, ToolKind::HostProcess)
}

pub fn target_runner(&self, kind: CompileKind) -> Option<&(PathBuf, Vec<String>)> {
Expand Down
17 changes: 14 additions & 3 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
//! [instructions]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
use super::{fingerprint, BuildRunner, Job, Unit, Work};
use crate::core::compiler::artifact;
use crate::core::compiler::build_runner::Metadata;
use crate::core::compiler::fingerprint::DirtyReason;
use crate::core::compiler::job_queue::JobState;
use crate::core::compiler::{artifact, FileFlavor};
use crate::core::{profiles::ProfileRoot, PackageId, Target};
use crate::util::errors::CargoResult;
use crate::util::internal;
Expand Down Expand Up @@ -265,7 +265,19 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
}

// Building the command to execute
let to_exec = script_dir.join(unit.target.name());
let to_exec = if build_runner.bcx.gctx.cli_unstable().sandbox {
// XXX: is the `expect` statement here really the truth?
let outputs = build_runner.outputs(build_script_unit)?;
let outputs = outputs
.iter()
.filter(|output| output.flavor == FileFlavor::Normal);
let (Some(output), None) = (outputs.next(), outputs.next()) else {
panic!("a build script to produce the one and only executable");
};
output.bin_dst().as_os_str().to_os_string()
} else {
script_dir.join(unit.target.name()).into_os_string()
};

// Start preparing the process to execute, starting out with some
// environment variables. Note that the profile-related environment
Expand All @@ -274,7 +286,6 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
// NOTE: if you add any profile flags, be sure to update
// `Profiles::get_profile_run_custom_build` so that those flags get
// carried over.
let to_exec = to_exec.into_os_string();
let mut cmd = build_runner.compilation.host_process(to_exec, &unit.pkg)?;
let debug = unit.profile.debuginfo.is_turned_on();
cmd.env("OUT_DIR", &script_out_dir)
Expand Down
12 changes: 10 additions & 2 deletions src/cargo/core/compiler/unit_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,16 @@ fn compute_deps_custom_build(
&unit.pkg,
&unit.target,
script_unit_for,
// Build scripts always compiled for the host.
CompileKind::Host,
// Build scripts always compiled for the host,
// unless `sandbox.target` is set.
if state.gctx.cli_unstable().sandbox {
match state.gctx.sandbox_config()?.target.as_ref() {
Some(target) => CompileKind::Target(super::CompileTarget::new(target)?),
None => CompileKind::Host,
}
} else {
CompileKind::Host
},
CompileMode::Build,
IS_NO_ARTIFACT_DEP,
)?;
Expand Down

0 comments on commit e0889df

Please sign in to comment.