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>
109 lines
4.2 KiB
Rust
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""#);
|
|
}
|