Shorten linker output even more when --verbose
is not present · rust-lang/rust@c1b4ab0 (original) (raw)
11 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -3537,6 +3537,7 @@ dependencies = [ | ||
3537 | 3537 | "ar_archive_writer", |
3538 | 3538 | "arrayvec", |
3539 | 3539 | "bitflags", |
3540 | +"bstr", | |
3540 | 3541 | "cc", |
3541 | 3542 | "either", |
3542 | 3543 | "itertools", |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -8,6 +8,7 @@ edition = "2021" | ||
8 | 8 | ar_archive_writer = "0.4.2" |
9 | 9 | arrayvec = { version = "0.7", default-features = false } |
10 | 10 | bitflags = "2.4.1" |
11 | +bstr = "1.11.3" | |
11 | 12 | # Pinned so `cargo update` bumps don't cause breakage. Please also update the |
12 | 13 | # `cc` in `rustc_llvm` if you update the `cc` here. |
13 | 14 | cc = "=1.2.7" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -13,6 +13,7 @@ pub(crate) struct Command { | ||
13 | 13 | args: Vec<OsString>, |
14 | 14 | env: Vec<(OsString, OsString)>, |
15 | 15 | env_remove: Vec<OsString>, |
16 | +env_clear: bool, | |
16 | 17 | } |
17 | 18 | |
18 | 19 | #[derive(Clone)] |
@@ -36,7 +37,13 @@ impl Command { | ||
36 | 37 | } |
37 | 38 | |
38 | 39 | fn _new(program: Program) -> Command { |
39 | -Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() } | |
40 | +Command { | |
41 | + program, | |
42 | +args: Vec::new(), | |
43 | +env: Vec::new(), | |
44 | +env_remove: Vec::new(), | |
45 | +env_clear: false, | |
46 | +} | |
40 | 47 | } |
41 | 48 | |
42 | 49 | pub(crate) fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command { |
@@ -79,6 +86,11 @@ impl Command { | ||
79 | 86 | self |
80 | 87 | } |
81 | 88 | |
89 | +pub(crate) fn env_clear(&mut self) -> &mut Command { | |
90 | +self.env_clear = true; | |
91 | +self | |
92 | +} | |
93 | + | |
82 | 94 | fn _env_remove(&mut self, key: &OsStr) { |
83 | 95 | self.env_remove.push(key.to_owned()); |
84 | 96 | } |
@@ -106,6 +118,9 @@ impl Command { | ||
106 | 118 | for k in &self.env_remove { |
107 | 119 | ret.env_remove(k); |
108 | 120 | } |
121 | +if self.env_clear { | |
122 | + ret.env_clear(); | |
123 | +} | |
109 | 124 | ret |
110 | 125 | } |
111 | 126 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1007,6 +1007,7 @@ fn link_natively( | ||
1007 | 1007 | command: cmd, |
1008 | 1008 | escaped_output, |
1009 | 1009 | verbose: sess.opts.verbose, |
1010 | +sysroot_dir: sess.sysroot.clone(), | |
1010 | 1011 | }; |
1011 | 1012 | sess.dcx().emit_err(err); |
1012 | 1013 | // If MSVC's `link.exe` was expected but the return code |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -351,6 +351,7 @@ pub(crate) struct LinkingFailed<'a> { | ||
351 | 351 | pub command: Command, |
352 | 352 | pub escaped_output: String, |
353 | 353 | pub verbose: bool, |
354 | +pub sysroot_dir: PathBuf, | |
354 | 355 | } |
355 | 356 | |
356 | 357 | impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> { |
@@ -364,6 +365,8 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> { | ||
364 | 365 | if self.verbose { |
365 | 366 | diag.note(format!("{:?}", self.command)); |
366 | 367 | } else { |
368 | +self.command.env_clear(); | |
369 | + | |
367 | 370 | enum ArgGroup { |
368 | 371 | Regular(OsString), |
369 | 372 | Objects(usize), |
@@ -398,26 +401,55 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> { | ||
398 | 401 | args.push(ArgGroup::Regular(arg)); |
399 | 402 | } |
400 | 403 | } |
401 | -self.command.args(args.into_iter().map(|arg_group | |
402 | -ArgGroup::Regular(arg) => arg, | |
403 | -ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")), | |
404 | -ArgGroup::Rlibs(dir, rlibs) => { | |
405 | -let mut arg = dir.into_os_string(); | |
406 | - arg.push("/{"); | |
407 | -let mut first = true; | |
408 | -for rlib in rlibs { | |
409 | -if !first { | |
410 | - arg.push(","); | |
404 | +let crate_hash = regex::bytes::Regex::new(r"-[0-9a-f]+\.rlib$").unwrap(); | |
405 | +self.command.args(args.into_iter().map(|arg_group | |
406 | +match arg_group { | |
407 | +// SAFETY: we are only matching on ASCII, not any surrogate pairs, so any replacements we do will still be valid. | |
408 | +ArgGroup::Regular(arg) => unsafe { | |
409 | +use bstr::ByteSlice; | |
410 | +OsString::from_encoded_bytes_unchecked( | |
411 | + arg.as_encoded_bytes().replace( | |
412 | +self.sysroot_dir.as_os_str().as_encoded_bytes(), | |
413 | +b"", | |
414 | +), | |
415 | +) | |
416 | +}, | |
417 | +ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")), | |
418 | +ArgGroup::Rlibs(mut dir, rlibs) => { | |
419 | +let is_sysroot_dir = match dir.strip_prefix(&self.sysroot_dir) { | |
420 | +Ok(short) => { | |
421 | + dir = Path::new("").join(short); | |
422 | +true | |
423 | +} | |
424 | +Err(_) => false, | |
425 | +}; | |
426 | +let mut arg = dir.into_os_string(); | |
427 | + arg.push("/{"); | |
428 | +let mut first = true; | |
429 | +for mut rlib in rlibs { | |
430 | +if !first { | |
431 | + arg.push(","); | |
432 | +} | |
433 | + first = false; | |
434 | +if is_sysroot_dir { | |
435 | +// SAFETY: Regex works one byte at a type, and our regex will not match surrogate pairs (because it only matches ascii). | |
436 | + rlib = unsafe { | |
437 | +OsString::from_encoded_bytes_unchecked( | |
438 | + crate_hash | |
439 | +.replace(rlib.as_encoded_bytes(), b"-*") | |
440 | +.into_owned(), | |
441 | +) | |
442 | +}; | |
443 | +} | |
444 | + arg.push(rlib); | |
411 | 445 | } |
412 | -first = false; | |
413 | - arg.push(rlib); | |
446 | +arg.push("}.rlib"); | |
447 | + arg | |
414 | 448 | } |
415 | - arg.push("}"); | |
416 | - arg | |
417 | 449 | } |
418 | 450 | })); |
419 | 451 | |
420 | - diag.note(format!("{:?}", self.command)); | |
452 | + diag.note(format!("{:?}", self.command).trim_start_matches("env -i").to_owned()); | |
421 | 453 | diag.note("some arguments are omitted. use `--verbose` to show all linker arguments"); |
422 | 454 | } |
423 | 455 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -414,6 +414,8 @@ impl TestCx<'_> { | ||
414 | 414 | // Provide path to checkout root. This is the top-level directory containing |
415 | 415 | // rust-lang/rust checkout. |
416 | 416 | .env("SOURCE_ROOT", &source_root) |
417 | +// Path to the build directory. This is usually the same as `source_root.join("build").join("host")`. | |
418 | +.env("BUILD_ROOT", &build_root) | |
417 | 419 | // Provide path to stage-corresponding rustc. |
418 | 420 | .env("RUSTC", &self.config.rustc_path) |
419 | 421 | // Provide the directory to libraries that are needed to run the *compiler*. This is not |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -90,7 +90,7 @@ pub use artifact_names::{ | ||
90 | 90 | /// Path-related helpers. |
91 | 91 | pub use path_helpers::{ |
92 | 92 | cwd, filename_contains, filename_not_in_denylist, has_extension, has_prefix, has_suffix, |
93 | - not_contains, path, shallow_find_files, source_root, | |
93 | + not_contains, path, shallow_find_files, build_root, source_root, | |
94 | 94 | }; |
95 | 95 | |
96 | 96 | /// Helpers for scoped test execution where certain properties are attempted to be maintained. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -34,6 +34,12 @@ pub fn source_root() -> PathBuf { | ||
34 | 34 | env_var("SOURCE_ROOT").into() |
35 | 35 | } |
36 | 36 | |
37 | +/// Path to the build directory root. | |
38 | +#[must_use] | |
39 | +pub fn build_root() -> PathBuf { | |
40 | +env_var("BUILD_ROOT").into() | |
41 | +} | |
42 | + | |
37 | 43 | /// Browse the directory `path` non-recursively and return all files which respect the parameters |
38 | 44 | /// outlined by `closure`. |
39 | 45 | #[track_caller] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -253,6 +253,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ | ||
253 | 253 | "bitflags", |
254 | 254 | "blake3", |
255 | 255 | "block-buffer", |
256 | +"bstr", | |
256 | 257 | "byteorder", // via ruzstd in object in thorin-dwp |
257 | 258 | "cc", |
258 | 259 | "cfg-if", |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,19 @@ | ||
1 | -use run_make_support::{Rustc, rustc}; | |
1 | +use run_make_support::{Rustc, diff, regex, rustc}; | |
2 | 2 | |
3 | 3 | fn run_rustc() -> Rustc { |
4 | 4 | let mut rustc = rustc(); |
5 | - rustc.arg("main.rs").output("main").linker("./fake-linker"); | |
5 | + rustc | |
6 | +.arg("main.rs") | |
7 | +// NOTE: `link-self-contained` can vary depending on config.toml. | |
8 | +// Make sure we use a consistent value. | |
9 | +.arg("-Clink-self-contained=-linker") | |
10 | +.arg("-Zunstable-options") | |
11 | +.output("main") | |
12 | +.linker("./fake-linker"); | |
13 | +if run_make_support::target() == "x86_64-unknown-linux-gnu" { | |
14 | +// The value of `rust.lld` is different between CI and locally. Override it explicitly. | |
15 | + rustc.arg("-Clinker-flavor=gnu-cc"); | |
16 | +} | |
6 | 17 | rustc |
7 | 18 | } |
8 | 19 | |
@@ -25,21 +36,32 @@ fn main() { | ||
25 | 36 | run_rustc().link_arg("run_make_error").run_fail().assert_stderr_contains("note: error: baz"); |
26 | 37 | |
27 | 38 | // Make sure we don't show the linker args unless `--verbose` is passed |
28 | -run_rustc() | |
29 | -.link_arg("run_make_error") | |
30 | -.verbose() | |
31 | -.run_fail() | |
32 | -.assert_stderr_contains_regex("fake-linker.*run_make_error") | |
39 | +let out = run_rustc().link_arg("run_make_error").verbose().run_fail(); | |
40 | + out.assert_stderr_contains_regex("fake-linker.*run_make_error") | |
33 | 41 | .assert_stderr_not_contains("object files omitted") |
42 | +.assert_stderr_contains(r".rcgu.o") | |
34 | 43 | .assert_stderr_contains_regex(r"lib(/|\\\\)libstd"); |
35 | -run_rustc() | |
36 | -.link_arg("run_make_error") | |
37 | -.run_fail() | |
38 | -.assert_stderr_contains("fake-linker") | |
44 | + | |
45 | +let out = run_rustc().link_arg("run_make_error").run_fail(); | |
46 | + out.assert_stderr_contains("fake-linker") | |
39 | 47 | .assert_stderr_contains("object files omitted") |
40 | 48 | .assert_stderr_contains_regex(r"\{") |
49 | +.assert_stderr_not_contains(r".rcgu.o") | |
41 | 50 | .assert_stderr_not_contains_regex(r"lib(/|\\\\)libstd"); |
42 | 51 | |
52 | +// FIXME: we should have a version of this for mac and windows | |
53 | +if run_make_support::target() == "x86_64-unknown-linux-gnu" { | |
54 | +diff() | |
55 | +.expected_file("short-error.txt") | |
56 | +.actual_text("(linker error)", out.stderr()) | |
57 | +.normalize(r#"/rustc[^/]*/"#, "/rustc/") | |
58 | +.normalize( | |
59 | + regex::escape(run_make_support::build_root().to_str().unwrap()), | |
60 | +"/build-root", | |
61 | +) | |
62 | +.run(); | |
63 | +} | |
64 | + | |
43 | 65 | // Make sure we show linker warnings even across `-Z no-link` |
44 | 66 | rustc() |
45 | 67 | .arg("-Zno-link") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
1 | +error: linking with `./fake-linker` failed: exit status: 1 | |
2 | + | | |
3 | + = note: "./fake-linker" "-m64" "/tmp/rustc/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" | |
4 | + = note: some arguments are omitted. use `--verbose` to show all linker arguments | |
5 | + = note: error: baz | |
6 | + | |
7 | + | |
8 | +error: aborting due to 1 previous error | |
9 | + |