Files
rust/tests/run-make/linker-warning/rmake.rs
Fabian Grünbichler 68c0e97cc6 re-order normalizations in run-make linker-warning test
otherwise a buildroot containing `libpanic_abort` would be mangled before being
replaced by the build root placeholder value..

e.g., running `./x.py test --verbose tests/run-make/linker-warning` with rustc
checked out in ~/ext/rustc-libpanic_abort will result in (output slightly shortened):

```
running 1 tests
test [run-make] tests/run-make/linker-warning ... FAILED

failures:

---- [run-make] tests/run-make/linker-warning stdout ----

------rustc stdout------------------------------

------rustc stderr------------------------------

------------------------------------------

error: rmake recipe failed to complete
status: exit status: 101
command: cd "/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/test/run-make/linker-warning/rmake_out" && env -u RUSTFLAGS -u __RUSTC_DEBUG_ASSERTIONS_ENABLED -u __STD_DEBUG_ASSERTIONS_ENABLED AR="ar" BUILD_ROOT="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu" CC="cc" CC_DEFAULT_FLAGS="-ffunction-sections -fdata-sections -fPIC -m64" CXX="c++" CXX_DEFAULT_FLAGS="-ffunction-sections -fdata-sections -fPIC -m64" HOST_RUSTC_DYLIB_PATH="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/stage1/lib" LD_LIBRARY_PATH="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib" LD_LIB_PATH_ENVVAR="LD_LIBRARY_PATH" LLVM_BIN_DIR="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/ci-llvm/bin" LLVM_COMPONENTS="<...>" LLVM_FILECHECK="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/ci-llvm/bin/FileCheck" NODE="/usr/bin/node" PYTHON="/usr/bin/python3" RUSTC="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" RUSTDOC="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/stage1/bin/rustdoc" SOURCE_ROOT="/home/user/ext/rustc-libpanic_abort" TARGET="x86_64-unknown-linux-gnu" TARGET_EXE_DYLIB_PATH="/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/user/ext/rustc-libpanic_abort/build/x86_64-unknown-linux-gnu/test/run-make/linker-warning/rmake"
stdout: none
--- stderr -------------------------------

thread 'main' panicked at /home/user/ext/rustc-libpanic_abort/tests/run-make/linker-warning/rmake.rs:74:14:
test failed: `short-error.txt` is different from `(linker error)`

--- short-error.txt
+++ (linker error)
@@ -1,6 +1,6 @@
 error: linking with `./fake-linker` failed: exit status: 1
   |
-  = note:  "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/build-root/test/run-make/linker-warning/rmake_out/{libfoo,libbar}.rlib" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,libcfg_if-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,liblibc-*,librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
+  = note:  "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/home/user/ext/rustc-libpanic_unwind/build/x86_64-unknown-linux-gnu/test/run-make/linker-warning/rmake_out/{libfoo,libbar}.rlib" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,libcfg_if-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,liblibc-*,librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/home/user/ext/rustc-libpanic_unwind/build/x86_64-unknown-linux-gnu/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
   = note: some arguments are omitted. use `--verbose` to show all linker arguments
   = note: error: baz

[..]
```

without this fix.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2025-09-26 08:14:25 +02:00

109 lines
4.2 KiB
Rust

//@ ignore-cross-compile (need to run fake linker)
use run_make_support::{Rustc, diff, regex, rustc};
fn run_rustc() -> Rustc {
let mut rustc = rustc();
rustc
.arg("main.rs")
// NOTE: `link-self-contained` can vary depending on bootstrap.toml.
// Make sure we use a consistent value.
.arg("-Clink-self-contained=-linker")
.arg("-Zunstable-options")
.arg("-Wlinker-messages")
.args(["--extern", "foo", "--extern", "bar"])
.output("main")
.linker("./fake-linker");
if run_make_support::target() == "x86_64-unknown-linux-gnu" {
// The value of `rust.lld` is different between CI and locally. Override it explicitly.
rustc.arg("-Clinker-flavor=gnu-cc");
}
rustc
}
fn main() {
// first, compile our linker and our dependencies
rustc().arg("fake-linker.rs").output("fake-linker").run();
rustc().arg("foo.rs").crate_type("rlib").run();
rustc().arg("bar.rs").crate_type("rlib").run();
// Run rustc with our fake linker, and make sure it shows warnings
let warnings = run_rustc().link_arg("run_make_warn").run();
warnings.assert_stderr_contains("warning: linker stderr: bar");
// Make sure it shows stdout
run_rustc()
.link_arg("run_make_info")
.run()
.assert_stderr_contains("warning: linker stdout: foo");
// Make sure we short-circuit this new path if the linker exits with an error
// (so the diagnostic is less verbose)
run_rustc().link_arg("run_make_error").run_fail().assert_stderr_contains("note: error: baz");
// Make sure we don't show the linker args unless `--verbose` is passed
let out = run_rustc().link_arg("run_make_error").verbose().run_fail();
out.assert_stderr_contains_regex("fake-linker.*run_make_error")
.assert_stderr_not_contains("object files omitted")
.assert_stderr_contains(r".rcgu.o")
.assert_stderr_contains_regex(r"lib(/|\\\\)libstd");
let out = run_rustc().link_arg("run_make_error").run_fail();
out.assert_stderr_contains("fake-linker")
.assert_stderr_contains("object files omitted")
.assert_stderr_contains("/{libfoo,libbar}.rlib\"")
.assert_stderr_contains("-*}.rlib\"")
.assert_stderr_not_contains(r".rcgu.o")
.assert_stderr_not_contains_regex(r"lib(/|\\\\)libstd");
// FIXME: we should have a version of this for mac and windows
if run_make_support::target() == "x86_64-unknown-linux-gnu" {
diff()
.expected_file("short-error.txt")
.actual_text("(linker error)", out.stderr())
.normalize(
regex::escape(
run_make_support::build_root().canonicalize().unwrap().to_str().unwrap(),
),
"/build-root",
)
.normalize("libpanic_abort", "libpanic_unwind")
.normalize(r#""[^"]*\/symbols.o""#, "\"/symbols.o\"")
.normalize(r#""[^"]*\/raw-dylibs""#, "\"/raw-dylibs\"")
.run();
}
// Make sure a single dependency doesn't use brace expansion.
let out1 = run_rustc().cfg("only_foo").link_arg("run_make_error").run_fail();
out1.assert_stderr_contains("fake-linker").assert_stderr_contains("/libfoo.rlib\"");
// Make sure we show linker warnings even across `-Z no-link`
rustc()
.arg("-Zno-link")
.input("-")
.stdin_buf("#![deny(linker_messages)] \n fn main() {}")
.run()
.assert_stderr_equals("");
rustc()
.arg("-Zlink-only")
.arg("rust_out.rlink")
.linker("./fake-linker")
.link_arg("run_make_warn")
.run_fail()
// NOTE: the error message here is quite bad (we don't have a source
// span, but still try to print the lint source). But `-Z link-only` is
// unstable and this still shows the linker warning itself so this is
// probably good enough.
.assert_stderr_contains("linker stderr: bar");
// Same thing, but with json output.
rustc()
.error_format("json")
.arg("-Zlink-only")
.arg("rust_out.rlink")
.linker("./fake-linker")
.link_arg("run_make_warn")
.run_fail()
.assert_stderr_contains(r#""$message_type":"diagnostic""#);
}