Skip to content

Commit 786e9b0

Browse files
committed
experiment: wrap build.rs runs
Signed-off-by: Pierre Fenoll <[email protected]>
1 parent 75d598b commit 786e9b0

File tree

5 files changed

+241
-12
lines changed

5 files changed

+241
-12
lines changed

cargo-green/src/logging.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,6 @@ fn unique_krate_types() {
6464

6565
let all: HashSet<_> = ALL_CRATE_TYPES.iter().map(|ty| crate_type_for_logging(ty)).collect();
6666
assert_eq!(ALL_CRATE_TYPES.len(), all.len());
67-
assert!(!all.contains(&'X')); // for build scripts
67+
assert!(!all.contains(&'X')); // for building build scripts
68+
assert!(!all.contains(&'Z')); // for executing build scripts
6869
}

cargo-green/src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,21 @@ async fn main() -> Result<()> {
7272
const ENV_ROOT_PACKAGE_SETTINGS: &str = "CARGOGREEN_ROOT_PACKAGE_SETTINGS_";
7373

7474
if let Ok(wrapper) = env::var("RUSTC_WRAPPER") {
75+
// Now running as a subprocess
7576
if PathBuf::from(&wrapper).file_name() != Some(OsStr::new(PKG)) {
7677
bail!("A $RUSTC_WRAPPER other than `{PKG}` is already set: {wrapper}")
7778
}
78-
// Now running as a subprocess
7979

8080
let green = env::var(ENV_ROOT_PACKAGE_SETTINGS)
8181
.map_err(|_| anyhow!("BUG: ${ENV_ROOT_PACKAGE_SETTINGS} is unset"))?;
8282
let green = serde_json::from_str(&green)
8383
.map_err(|e| anyhow!("BUG: ${ENV_ROOT_PACKAGE_SETTINGS} is unreadable: {e}"))?;
8484

85+
// Dance to wrap build script execution: we patched the build.rs to call us back through here.
86+
if let Ok(exe) = env::var(rustc_wrapper::ENV_EXECUTE_BUILDRS) {
87+
return rustc_wrapper::exec_buildrs(green, exe.into()).await;
88+
}
89+
8590
let arg0 = env::args().nth(1);
8691
let args = env::args().skip(1).collect();
8792
let vars = env::vars().collect();

cargo-green/src/md.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
};
1717

1818
#[cfg_attr(test, derive(Default))]
19-
#[derive(Clone, Deserialize, Serialize)]
19+
#[derive(Debug, Clone, Deserialize, Serialize)]
2020
#[serde(deny_unknown_fields)]
2121
pub(crate) struct Md {
2222
pub(crate) this: String,

cargo-green/src/rustc_wrapper.rs

Lines changed: 228 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ use crate::{
2525
tmp, PKG, VSN,
2626
};
2727

28+
pub(crate) const ENV_EXECUTE_BUILDRS: &str = "CARGOGREEN_EXECUTE_BUILDRS_";
29+
const WRAP_BUILDRS: bool = true; // FIXME: finish experiment
30+
2831
// NOTE: this RUSTC_WRAPPER program only ever gets called by `cargo`, so we save
2932
// ourselves some trouble and assume std::path::{Path, PathBuf} are UTF-8.
3033

@@ -112,6 +115,188 @@ async fn call_rustc(rustc: &str, args: Vec<String>) -> Result<()> {
112115
Ok(())
113116
}
114117

118+
pub(crate) async fn exec_buildrs(green: Green, exe: Utf8PathBuf) -> Result<()> {
119+
assert!(env::var_os(ENV).is_none(), "It's turtles all the way down!");
120+
env::set_var(ENV, "1");
121+
122+
let krate_name = env::var("CARGO_PKG_NAME").expect("$CARGO_PKG_NAME");
123+
124+
let krate_version = env::var("CARGO_PKG_VERSION").expect("$CARGO_PKG_VERSION");
125+
126+
// exe: /target/release/build/proc-macro2-2f938e044e3f79bf/build-script-build
127+
let Some((previous_md_path, previous_extra)) = || -> Option<_> {
128+
// name: build_script_build
129+
let name = exe.file_name()?.replace('-', "_");
130+
// target_path: /target/release/build/proc-macro2-2f938e044e3f79bf
131+
let target_path = exe.parent()?;
132+
// extra: -2f938e044e3f79bf
133+
let extra = target_path.file_name()?.trim_start_matches(&krate_name).to_owned();
134+
// target_path: /target/release
135+
let target_path = target_path.parent()?.parent()?;
136+
// /target/release/build_script_build-2f938e044e3f79bf.toml
137+
Some((target_path.join(format!("{name}{extra}.toml")), extra))
138+
}() else {
139+
bail!("BUG: malformed buildrs exe {exe:?}")
140+
};
141+
142+
// $OUT_DIR: /target/release/build/proc-macro2-b97492fdd0201a99/out
143+
let out_dir_var: Utf8PathBuf = env::var("OUT_DIR").expect("$OUT_DIR").into();
144+
let Some((md_path, extra)) = || -> Option<_> {
145+
// name: proc-macro2-b97492fdd0201a99
146+
let name = out_dir_var.parent()?.file_name()?;
147+
// extra: -b97492fdd0201a99
148+
let extra = name.trim_start_matches(&krate_name).to_owned();
149+
// /target/release/proc-macro2-b97492fdd0201a99.toml
150+
Some((previous_md_path.with_file_name(format!("{name}.toml")), extra))
151+
}() else {
152+
bail!("BUG: malformed $OUT_DIR {out_dir_var:?}")
153+
};
154+
155+
let full_krate_id = format!("Z {krate_name} {krate_version}{extra}");
156+
logging::setup(&full_krate_id);
157+
158+
info!("{PKG}@{VSN} original args: {exe:?} green={green:?}");
159+
160+
do_exec_buildrs(
161+
green,
162+
&krate_name,
163+
krate_version,
164+
full_krate_id.replace(' ', "-"),
165+
out_dir_var,
166+
exe,
167+
previous_md_path,
168+
previous_extra,
169+
md_path,
170+
extra,
171+
)
172+
.await
173+
.inspect_err(|e| error!("Error: {e}"))
174+
}
175+
176+
#[expect(clippy::too_many_arguments)]
177+
async fn do_exec_buildrs(
178+
green: Green,
179+
krate_name: &str,
180+
krate_version: String,
181+
crate_id: String,
182+
out_dir_var: Utf8PathBuf,
183+
exe: Utf8PathBuf,
184+
previous_md_path: Utf8PathBuf,
185+
previous_extra: String,
186+
md_path: Utf8PathBuf,
187+
extra: String,
188+
) -> Result<()> {
189+
let debug = maybe_log();
190+
191+
let run_stage = Stage::try_new(format!("run-{crate_id}"))?;
192+
let out_stage = Stage::try_new(format!("ran{extra}"))?;
193+
194+
let code_stage = Stage::try_new(format!("cratesio-{krate_name}-{krate_version}"))?; // FIXME
195+
let code_mount_src = "/extracted"; //FIXME
196+
let code_mount_dst = format!("/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/{krate_name}-{krate_version}"); //FIXME
197+
198+
let previous_out_stage = Stage::try_new(format!("out{previous_extra}"))?; //FIXME
199+
let previous_out_dst = {
200+
let name = exe.file_name().expect("PROOF: already ensured path has file_name");
201+
let name = name.replacen('-', "_", 2);
202+
format!("/{name}{previous_extra}")
203+
};
204+
205+
let mut md = Md::new(&extra[1..]); // Drops leading dash
206+
md.push_block(&RUST, green.image.base_image_inline.clone().unwrap());
207+
208+
let mut run_block = String::new();
209+
run_block.push_str(&format!("FROM {RST} AS {run_stage}\n"));
210+
run_block.push_str(&format!("SHELL {:?}\n", ["/bin/bash", "-eux", "-c"]));
211+
run_block.push_str(&format!("WORKDIR {out_dir_var}\n"));
212+
run_block.push_str("RUN \\\n");
213+
run_block.push_str(&format!(
214+
" --mount=from={code_stage},source={code_mount_src},dst={code_mount_dst} \\\n"
215+
));
216+
run_block.push_str(&format!(
217+
" --mount=from={previous_out_stage},source={previous_out_dst},dst={exe} \\\n"
218+
));
219+
run_block.push_str(&format!(" env CARGO={:?} \\\n", "$(which cargo)"));
220+
for (var, val) in env::vars().filter_map(|kv| fmap_env(kv, true)) {
221+
run_block.push_str(&format!(" {var}={val} \\\n"));
222+
}
223+
run_block.push_str(&format!(" {ENV}=1 \\\n"));
224+
for var in &green.set_envs {
225+
if let Ok(val) = env::var(var) {
226+
// let val = replace_target_dir_str(&val, TARGET_DIR.as_str(), VIRTUAL_TARGET_DIR);
227+
warn!("passing ${var}={val:?} env through");
228+
run_block.push_str(&format!(" {var}={val:?} \\\n"));
229+
}
230+
}
231+
run_block.push_str(&format!(" {ENV_EXECUTE_BUILDRS}= \\\n"));
232+
run_block.push_str(&format!(" {exe} \\\n"));
233+
run_block.push_str(&format!(" 1> >(sed 's/^/{MARK_STDOUT}/') \\\n"));
234+
run_block.push_str(&format!(" 2> >(sed 's/^/{MARK_STDERR}/' >&2)\n"));
235+
md.push_block(&run_stage, run_block);
236+
237+
let mut out_block = String::new();
238+
out_block.push_str(&format!("FROM scratch AS {out_stage}\n"));
239+
out_block.push_str(&format!("COPY --from={run_stage} {out_dir_var}/*{extra}* /\n"));
240+
md.push_block(&out_stage, out_block);
241+
242+
let containerfile_path = md_path.with_extension("Dockerfile");
243+
244+
let md = md; // Drop mut
245+
md.write_to(&md_path)?;
246+
drop(md_path);
247+
248+
let previous_md = Md::from_file(&previous_md_path)?;
249+
if !previous_md.deps.is_empty() {
250+
//FIXME: read/import/topolosort .deps
251+
panic!(">>> {previous_md:?}")
252+
}
253+
let blocks = md.block_along_with_predecessors(&[previous_md]);
254+
255+
let mut containerfile = green.new_containerfile();
256+
containerfile.pushln(md.rust_stage());
257+
containerfile.nl();
258+
containerfile.push(&blocks);
259+
containerfile.write_to(&containerfile_path)?;
260+
drop(containerfile);
261+
262+
fs::create_dir_all(&out_dir_var)
263+
.map_err(|e| anyhow!("Failed to `mkdir -p {out_dir_var}`: {e}"))?;
264+
265+
let fallback = async move {
266+
let mut cmd = Command::new(&exe);
267+
let cmd = cmd.kill_on_drop(true);
268+
// Do not unset ENV_EXECUTE_BUILDRS
269+
let status = cmd
270+
.spawn()
271+
.map_err(|e| anyhow!("Failed to spawn {}: {e}", cmd.show()))?
272+
.wait()
273+
.await
274+
.map_err(|e| anyhow!("Failed to wait {}: {e}", cmd.show()))?;
275+
if !status.success() {
276+
bail!("Failed in execute_buildrs")
277+
}
278+
Ok(())
279+
};
280+
281+
if green.runner == Runner::None {
282+
info!("Runner disabled, falling back...");
283+
return fallback.await;
284+
}
285+
let res = build_out(&green, &containerfile_path, out_stage, &md.contexts, &out_dir_var).await;
286+
287+
if let Err(e) = res {
288+
warn!("Falling back due to {e}");
289+
if debug.is_none() {
290+
// Bubble up actual error & outputs
291+
return fallback
292+
.await
293+
.inspect(|()| eprintln!("BUG: {PKG} should not have encountered this error: {e}"));
294+
}
295+
return Err(e);
296+
}
297+
Ok(())
298+
}
299+
115300
async fn wrap_rustc(
116301
green: Green,
117302
crate_name: &str,
@@ -364,12 +549,41 @@ async fn do_wrap_rustc(
364549
rustc_block.push_str(" { cat ./rustc-toolchain{,.toml} 2>/dev/null || true ; } && \\\n");
365550
//fixme? prefix with ::rustc-toolchain::
366551

552+
if WRAP_BUILDRS && buildrs {
553+
// TODO: {extrafn} STDIO consts
554+
// TODO: this won't work with e.g. tokio-decorated main fns (async + decorator needs duplicating)
555+
556+
rustc_block.push_str(&format!(
557+
r#" {{ \
558+
cat {input} | sed 's/fn main/fn actual{uniq}_main/' >{input}~ && mv {input}~ {input} ; \
559+
{{ \
560+
echo ; \
561+
echo 'fn main() {{' ; \
562+
echo ' use std::env::{{args_os, var_os}};' ; \
563+
echo ' if var_os("{ENV_EXECUTE_BUILDRS}").is_none() {{' ; \
564+
echo ' use std::process::{{Command, Stdio}};' ; \
565+
echo ' let mut cmd = Command::new("{PKG}");' ; \
566+
echo ' cmd.stdin(Stdio::inherit()).stdout(Stdio::inherit()).stderr(Stdio::inherit());' ; \
567+
echo ' cmd.env("{ENV_EXECUTE_BUILDRS}", args_os().next().expect("{PKG}: getting buildrs arg0"));' ; \
568+
echo ' let res = cmd.spawn().expect("{PKG}: spawning buildrs").wait().expect("{PKG}: running builds");' ; \
569+
echo ' assert!(res.success());' ; \
570+
echo ' }} else {{' ; \
571+
echo ' actual{uniq}_main()' ; \
572+
echo ' }}' ; \
573+
echo '}}' ; \
574+
}} >>{input} ; \
575+
}} && \
576+
"#,
577+
uniq = extrafn.replace('-', "_"),
578+
));
579+
}
580+
367581
rustc_block.push_str(&format!(" env CARGO={:?} \\\n", "$(which cargo)"));
368582

369583
for (var, val) in env::vars().filter_map(|kv| fmap_env(kv, buildrs)) {
370584
rustc_block.push_str(&format!(" {var}={val} \\\n"));
371585
}
372-
rustc_block.push_str(" CARGOGREEN=1 \\\n");
586+
rustc_block.push_str(&format!(" {ENV}=1 \\\n"));
373587
// => cargo upstream issue "pass env vars read/wrote by build script on call to rustc"
374588
// TODO whence https://github.com/rust-lang/cargo/issues/14444#issuecomment-2305891696
375589
for var in &green.set_envs {
@@ -586,9 +800,22 @@ fn fmap_env((var, val): (String, String), buildrs: bool) -> Option<(String, Stri
586800
debug!("env is set: {var}={val}");
587801
}
588802
let val = match var.as_str() {
803+
"CARGO_PKG_DESCRIPTION" => "FIXME".to_owned(),
589804
"CARGO_MANIFEST_DIR" | "CARGO_MANIFEST_PATH" => {
590805
rewrite_cratesio_index(Utf8Path::new(&val)).to_string()
591806
}
807+
"TERM" => return None,
808+
"RUSTC" => "rustc".to_owned(), // Rewrite host rustc so the base_image one can be used
809+
// "CARGO_TARGET_DIR" | "CARGO_BUILD_TARGET_DIR" => {
810+
// virtual_target_dir(Utf8Path::new(&val)).to_string()
811+
// }
812+
// // TODO: a constant $CARGO_TARGET_DIR possible solution is to wrap build script as it runs,
813+
// // ie. controlling all outputs. This should help: https://github.com/trailofbits/build-wrap/blob/d7f43b76e655e43755f68e28e9d729b4ed1dd115/src/wrapper.rs#L29
814+
// //(dbcc)=> Dirty typenum v1.12.0: stale, https://github.com/rust-lang/cargo/blob/7987d4bfe683267ba179b42af55891badde3ccbf/src/cargo/core/compiler/fingerprint/mod.rs#L2030
815+
// //=> /tmp/clis-dbcc_2-2-1/release/deps/typenum-32188cb0392f25b9.d
816+
// "OUT_DIR" => virtual_target_dir(Utf8Path::new(&val)).to_string(),
817+
"CARGO_TARGET_DIR" | "CARGO_BUILD_TARGET_DIR" => return None,
818+
"OUT_DIR" => val,
592819
_ => val,
593820
};
594821
return Some((var, val));

recipes/[email protected]

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ RUN \
2525
CARGO_MANIFEST_DIR="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/pico-args-0.5.0" \
2626
CARGO_MANIFEST_PATH="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/pico-args-0.5.0/Cargo.toml" \
2727
CARGO_PKG_AUTHORS="Yevhenii Reizner <[email protected]>" \
28-
CARGO_PKG_DESCRIPTION="An ultra simple CLI arguments parser." \
28+
CARGO_PKG_DESCRIPTION=FIXME \
2929
CARGO_PKG_HOMEPAGE= \
3030
CARGO_PKG_LICENSE="MIT" \
3131
CARGO_PKG_LICENSE_FILE= \
@@ -38,7 +38,6 @@ RUN \
3838
CARGO_PKG_VERSION_MINOR="5" \
3939
CARGO_PKG_VERSION_PATCH="0" \
4040
CARGO_PKG_VERSION_PRE= \
41-
TERM="xterm-256color" \
4241
CARGOGREEN=1 \
4342
rustc '--crate-name' 'pico_args' '--edition' '2018' '--error-format' 'json' '--json' 'diagnostic-rendered-ansi,artifacts,future-incompat' '--diagnostic-width' '190' '--crate-type' 'lib' '--emit' 'dep-info,metadata,link' '-C' 'opt-level=3' '-C' 'embed-bitcode=no' '--cfg' 'feature="default"' '--cfg' 'feature="eq-separator"' '--check-cfg' 'cfg(docsrs,test)' '--check-cfg' 'cfg(feature, values("combined-flags", "default", "eq-separator", "short-space-opt"))' '-C' 'metadata=9531c7e3ea64e837' '-C' 'extra-filename=-b8c41dbf50ca5479' '--out-dir' '/tmp/cargo-green--hack-caching/release/deps' '-C' 'strip=debuginfo' '-L' 'dependency=/tmp/cargo-green--hack-caching/release/deps' '--cap-lints' 'allow' /home/pete/.cargo/registry/src/index.crates.io-0000000000000000/pico-args-0.5.0/src/lib.rs \
4443
1> >(sed 's/^/::STDOUT:: /') \
@@ -67,7 +66,7 @@ RUN \
6766
CARGO_MANIFEST_DIR="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/shlex-1.3.0" \
6867
CARGO_MANIFEST_PATH="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/shlex-1.3.0/Cargo.toml" \
6968
CARGO_PKG_AUTHORS="comex <[email protected]>:Fenhl <[email protected]>:Adrian Taylor <[email protected]>:Alex Touchet <[email protected]>:Daniel Parks <[email protected]>:Garrett Berg <[email protected]>" \
70-
CARGO_PKG_DESCRIPTION="Split a string into shell words, like Python's shlex." \
69+
CARGO_PKG_DESCRIPTION=FIXME \
7170
CARGO_PKG_HOMEPAGE= \
7271
CARGO_PKG_LICENSE="MIT OR Apache-2.0" \
7372
CARGO_PKG_LICENSE_FILE= \
@@ -80,7 +79,6 @@ RUN \
8079
CARGO_PKG_VERSION_MINOR="3" \
8180
CARGO_PKG_VERSION_PATCH="0" \
8281
CARGO_PKG_VERSION_PRE= \
83-
TERM="xterm-256color" \
8482
CARGOGREEN=1 \
8583
rustc '--crate-name' 'shlex' '--edition' '2015' '--error-format' 'json' '--json' 'diagnostic-rendered-ansi,artifacts,future-incompat' '--diagnostic-width' '190' '--crate-type' 'lib' '--emit' 'dep-info,metadata,link' '-C' 'opt-level=3' '-C' 'embed-bitcode=no' '--cfg' 'feature="default"' '--cfg' 'feature="std"' '--check-cfg' 'cfg(docsrs,test)' '--check-cfg' 'cfg(feature, values("default", "std"))' '-C' 'metadata=57dc058ec0bb424e' '-C' 'extra-filename=-96a741f581f4126a' '--out-dir' '/tmp/cargo-green--hack-caching/release/deps' '-C' 'strip=debuginfo' '-L' 'dependency=/tmp/cargo-green--hack-caching/release/deps' '--cap-lints' 'allow' /home/pete/.cargo/registry/src/index.crates.io-0000000000000000/shlex-1.3.0/src/lib.rs \
8684
1> >(sed 's/^/::STDOUT:: /') \
@@ -111,7 +109,7 @@ RUN \
111109
CARGO_MANIFEST_DIR="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/buildxargs-1.4.0" \
112110
CARGO_MANIFEST_PATH="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/buildxargs-1.4.0/Cargo.toml" \
113111
CARGO_PKG_AUTHORS="Pierre Fenoll <[email protected]>" \
114-
CARGO_PKG_DESCRIPTION="xargs for BuildKit with docker buildx bake" \
112+
CARGO_PKG_DESCRIPTION=FIXME \
115113
CARGO_PKG_HOMEPAGE= \
116114
CARGO_PKG_LICENSE="MIT" \
117115
CARGO_PKG_LICENSE_FILE= \
@@ -126,7 +124,6 @@ RUN \
126124
CARGO_PKG_VERSION_PRE= \
127125
CARGO_PRIMARY_PACKAGE="1" \
128126
CARGO_SBOM_PATH= \
129-
TERM="xterm-256color" \
130127
CARGOGREEN=1 \
131128
rustc '--crate-name' 'buildxargs' '--edition' '2021' '--error-format' 'json' '--json' 'diagnostic-rendered-ansi,artifacts,future-incompat' '--diagnostic-width' '190' '--crate-type' 'lib' '--emit' 'dep-info,metadata,link' '-C' 'opt-level=3' '-C' 'embed-bitcode=no' '--check-cfg' 'cfg(docsrs,test)' '--check-cfg' 'cfg(feature, values())' '-C' 'metadata=0d0386ef92a0f4e5' '-C' 'extra-filename=-d78f4de4a17f92cd' '--out-dir' '/tmp/cargo-green--hack-caching/release/deps' '-C' 'strip=debuginfo' '-L' 'dependency=/tmp/cargo-green--hack-caching/release/deps' '--extern' 'pico_args=/tmp/cargo-green--hack-caching/release/deps/libpico_args-b8c41dbf50ca5479.rmeta' '--extern' 'shlex=/tmp/cargo-green--hack-caching/release/deps/libshlex-96a741f581f4126a.rmeta' '--cap-lints' 'allow' /home/pete/.cargo/registry/src/index.crates.io-0000000000000000/buildxargs-1.4.0/src/lib.rs \
132129
1> >(sed 's/^/::STDOUT:: /') \
@@ -150,7 +147,7 @@ RUN \
150147
CARGO_MANIFEST_DIR="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/buildxargs-1.4.0" \
151148
CARGO_MANIFEST_PATH="/home/pete/.cargo/registry/src/index.crates.io-0000000000000000/buildxargs-1.4.0/Cargo.toml" \
152149
CARGO_PKG_AUTHORS="Pierre Fenoll <[email protected]>" \
153-
CARGO_PKG_DESCRIPTION="xargs for BuildKit with docker buildx bake" \
150+
CARGO_PKG_DESCRIPTION=FIXME \
154151
CARGO_PKG_HOMEPAGE= \
155152
CARGO_PKG_LICENSE="MIT" \
156153
CARGO_PKG_LICENSE_FILE= \
@@ -165,7 +162,6 @@ RUN \
165162
CARGO_PKG_VERSION_PRE= \
166163
CARGO_PRIMARY_PACKAGE="1" \
167164
CARGO_SBOM_PATH= \
168-
TERM="xterm-256color" \
169165
CARGOGREEN=1 \
170166
rustc '--crate-name' 'buildxargs' '--edition' '2021' '--error-format' 'json' '--json' 'diagnostic-rendered-ansi,artifacts,future-incompat' '--diagnostic-width' '190' '--crate-type' 'bin' '--emit' 'dep-info,link' '-C' 'opt-level=3' '-C' 'embed-bitcode=no' '--check-cfg' 'cfg(docsrs,test)' '--check-cfg' 'cfg(feature, values())' '-C' 'metadata=afebe456ed549d51' '-C' 'extra-filename=-39127c16f4d70192' '--out-dir' '/tmp/cargo-green--hack-caching/release/deps' '-C' 'strip=debuginfo' '-L' 'dependency=/tmp/cargo-green--hack-caching/release/deps' '--extern' 'buildxargs=/tmp/cargo-green--hack-caching/release/deps/libbuildxargs-d78f4de4a17f92cd.rlib' '--extern' 'pico_args=/tmp/cargo-green--hack-caching/release/deps/libpico_args-b8c41dbf50ca5479.rlib' '--extern' 'shlex=/tmp/cargo-green--hack-caching/release/deps/libshlex-96a741f581f4126a.rlib' '--cap-lints' 'allow' /home/pete/.cargo/registry/src/index.crates.io-0000000000000000/buildxargs-1.4.0/src/main.rs \
171167
1> >(sed 's/^/::STDOUT:: /') \

0 commit comments

Comments
 (0)