Auto merge of #128196 - Oneirical:poltergeist-manitestation, r=jieyouxu
Migrate `cross-lang-lto-upstream-rlibs`, `long-linker-command-lines` and `long-linker-command-lines-cmd-exe` `run-make` tests to rmake Part of #121876 and the associated [Google Summer of Code project](https://blog.rust-lang.org/2024/05/01/gsoc-2024-selected-projects.html). The `long-linker` tests are certainly doing something... interesting - they summon `rustc` calls with obscene quantities of arguments and check that this is appropriately handled. I removed the `RUSTC_ORIGINAL` magic - it's equivalent to `RUSTC` in `tools.mk`, so what is the purpose? Making it so the massive pile of flags doesn't modify rustc itself and start leaking into other tests? Tell me what you think. Please try: try-job: x86_64-msvc try-job: i686-msvc try-job: x86_64-mingw try-job: i686-mingw try-job: aarch64-apple try-job: test-various try-job: x86_64-gnu-debug try-job: x86_64-gnu-llvm-17
This commit is contained in:
commit
9bad7ba324
@ -1,6 +1,5 @@
|
||||
run-make/branch-protection-check-IBT/Makefile
|
||||
run-make/cat-and-grep-sanity-check/Makefile
|
||||
run-make/cross-lang-lto-upstream-rlibs/Makefile
|
||||
run-make/dep-info-doesnt-run-much/Makefile
|
||||
run-make/dep-info-spaces/Makefile
|
||||
run-make/dep-info/Makefile
|
||||
@ -13,8 +12,6 @@ run-make/libs-through-symlinks/Makefile
|
||||
run-make/libtest-json/Makefile
|
||||
run-make/libtest-junit/Makefile
|
||||
run-make/libtest-thread-limit/Makefile
|
||||
run-make/long-linker-command-lines-cmd-exe/Makefile
|
||||
run-make/long-linker-command-lines/Makefile
|
||||
run-make/macos-deployment-target/Makefile
|
||||
run-make/min-global-align/Makefile
|
||||
run-make/native-link-modifier-bundle/Makefile
|
||||
|
@ -1,32 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# ignore windows due to libLLVM being present in PATH and the PATH and library path being the same
|
||||
# (so fixing it is harder). See #57765 for context
|
||||
ifndef IS_WINDOWS
|
||||
|
||||
# This test makes sure that we don't loose upstream object files when compiling
|
||||
# staticlibs with -C linker-plugin-lto
|
||||
|
||||
all: staticlib.rs upstream.rs
|
||||
$(RUSTC) upstream.rs -C linker-plugin-lto -Ccodegen-units=1
|
||||
|
||||
# Check No LTO
|
||||
$(RUSTC) staticlib.rs -C linker-plugin-lto -Ccodegen-units=1 -L. -o $(TMPDIR)/staticlib.a
|
||||
(cd $(TMPDIR); "$(LLVM_BIN_DIR)"/llvm-ar x ./staticlib.a)
|
||||
# Make sure the upstream object file was included
|
||||
ls $(TMPDIR)/upstream.*.rcgu.o
|
||||
|
||||
# Cleanup
|
||||
rm $(TMPDIR)/*
|
||||
|
||||
# Check ThinLTO
|
||||
$(RUSTC) upstream.rs -C linker-plugin-lto -Ccodegen-units=1 -Clto=thin
|
||||
$(RUSTC) staticlib.rs -C linker-plugin-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a
|
||||
(cd $(TMPDIR); "$(LLVM_BIN_DIR)"/llvm-ar x ./staticlib.a)
|
||||
ls $(TMPDIR)/upstream.*.rcgu.o
|
||||
|
||||
else
|
||||
|
||||
all:
|
||||
|
||||
endif
|
57
tests/run-make/cross-lang-lto-upstream-rlibs/rmake.rs
Normal file
57
tests/run-make/cross-lang-lto-upstream-rlibs/rmake.rs
Normal file
@ -0,0 +1,57 @@
|
||||
// When using the flag -C linker-plugin-lto, static libraries could lose their upstream object
|
||||
// files during compilation. This bug was fixed in #53031, and this test compiles a staticlib
|
||||
// dependent on upstream, checking that the upstream object file still exists after no LTO and
|
||||
// thin LTO.
|
||||
// See https://github.com/rust-lang/rust/pull/53031
|
||||
|
||||
use run_make_support::{
|
||||
cwd, has_extension, has_prefix, has_suffix, llvm_ar, rfs, rustc, shallow_find_files,
|
||||
static_lib_name,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
// The test starts with no LTO enabled.
|
||||
rustc().input("upstream.rs").arg("-Clinker-plugin-lto").codegen_units(1).run();
|
||||
rustc()
|
||||
.input("staticlib.rs")
|
||||
.arg("-Clinker-plugin-lto")
|
||||
.codegen_units(1)
|
||||
.output(static_lib_name("staticlib"))
|
||||
.run();
|
||||
llvm_ar().extract().arg(static_lib_name("staticlib")).run();
|
||||
// Ensure the upstream object file was included.
|
||||
assert_eq!(
|
||||
shallow_find_files(cwd(), |path| {
|
||||
has_prefix(path, "upstream.") && has_suffix(path, ".rcgu.o")
|
||||
})
|
||||
.len(),
|
||||
1
|
||||
);
|
||||
// Remove all output files that are not source Rust code for cleanup.
|
||||
for file in shallow_find_files(cwd(), |path| !has_extension(path, "rs")) {
|
||||
rfs::remove_file(file)
|
||||
}
|
||||
|
||||
// Check it again, with Thin LTO.
|
||||
rustc()
|
||||
.input("upstream.rs")
|
||||
.arg("-Clinker-plugin-lto")
|
||||
.codegen_units(1)
|
||||
.arg("-Clto=thin")
|
||||
.run();
|
||||
rustc()
|
||||
.input("staticlib.rs")
|
||||
.arg("-Clinker-plugin-lto")
|
||||
.codegen_units(1)
|
||||
.arg("-Clto=thin")
|
||||
.output(static_lib_name("staticlib"))
|
||||
.run();
|
||||
llvm_ar().extract().arg(static_lib_name("staticlib")).run();
|
||||
assert_eq!(
|
||||
shallow_find_files(cwd(), |path| {
|
||||
has_prefix(path, "upstream.") && has_suffix(path, ".rcgu.o")
|
||||
})
|
||||
.len(),
|
||||
1
|
||||
);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
# ignore-cross-compile
|
||||
include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs -g
|
||||
cp foo.bat $(TMPDIR)/
|
||||
OUT_DIR="$(TMPDIR)" RUSTC="$(RUSTC_ORIGINAL)" $(call RUN,foo)
|
@ -1,16 +1,3 @@
|
||||
// Like the `long-linker-command-lines` test this test attempts to blow
|
||||
// a command line limit for running the linker. Unlike that test, however,
|
||||
// this test is testing `cmd.exe` specifically rather than the OS.
|
||||
//
|
||||
// Unfortunately `cmd.exe` has a 8192 limit which is relatively small
|
||||
// in the grand scheme of things and anyone sripting rustc's linker
|
||||
// is probably using a `*.bat` script and is likely to hit this limit.
|
||||
//
|
||||
// This test uses a `foo.bat` script as the linker which just simply
|
||||
// delegates back to this program. The compiler should use a lower
|
||||
// limit for arguments before passing everything via `@`, which
|
||||
// means that everything should still succeed here.
|
||||
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{BufWriter, Read, Write};
|
||||
@ -18,13 +5,8 @@
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
if !cfg!(windows) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tmpdir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
let ok = tmpdir.join("ok");
|
||||
let not_ok = tmpdir.join("not_ok");
|
||||
let ok = PathBuf::from("ok");
|
||||
let not_ok = PathBuf::from("not_ok");
|
||||
if env::var("YOU_ARE_A_LINKER").is_ok() {
|
||||
match env::args_os().find(|a| a.to_string_lossy().contains("@")) {
|
||||
Some(file) => {
|
||||
@ -45,7 +27,7 @@ fn main() {
|
||||
for i in (1..).map(|i| i * 10) {
|
||||
println!("attempt: {}", i);
|
||||
|
||||
let file = tmpdir.join("bar.rs");
|
||||
let file = PathBuf::from("bar.rs");
|
||||
let mut f = BufWriter::new(File::create(&file).unwrap());
|
||||
let mut lib_name = String::new();
|
||||
for _ in 0..i {
|
||||
@ -63,8 +45,6 @@ fn main() {
|
||||
.arg(&file)
|
||||
.arg("-C")
|
||||
.arg(&bat_linker)
|
||||
.arg("--out-dir")
|
||||
.arg(&tmpdir)
|
||||
.env("YOU_ARE_A_LINKER", "1")
|
||||
.env("MY_LINKER", &me)
|
||||
.status()
|
||||
|
26
tests/run-make/long-linker-command-lines-cmd-exe/rmake.rs
Normal file
26
tests/run-make/long-linker-command-lines-cmd-exe/rmake.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Like the `long-linker-command-lines` test this test attempts to blow
|
||||
// a command line limit for running the linker. Unlike that test, however,
|
||||
// this test is testing `cmd.exe` specifically rather than the OS.
|
||||
//
|
||||
// Unfortunately, the maximum length of the string that you can use at the
|
||||
// command prompt (`cmd.exe`) is 8191 characters.
|
||||
// Anyone scripting rustc's linker
|
||||
// is probably using a `*.bat` script and is likely to hit this limit.
|
||||
//
|
||||
// This test uses a `foo.bat` script as the linker which just simply
|
||||
// delegates back to this program. The compiler should use a lower
|
||||
// limit for arguments before passing everything via `@`, which
|
||||
// means that everything should still succeed here.
|
||||
// See https://github.com/rust-lang/rust/pull/47507
|
||||
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
//@ only-windows
|
||||
// Reason: this test is specific to Windows executables
|
||||
|
||||
use run_make_support::{run, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").arg("-g").run();
|
||||
run("foo");
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
# ignore-cross-compile
|
||||
include ../tools.mk
|
||||
|
||||
export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs -g -O
|
||||
RUSTC="$(RUSTC_ORIGINAL)" $(call RUN,foo)
|
@ -1,12 +1,3 @@
|
||||
// This is a test which attempts to blow out the system limit with how many
|
||||
// arguments can be passed to a process. This'll successively call rustc with
|
||||
// larger and larger argument lists in an attempt to find one that's way too
|
||||
// big for the system at hand. This file itself is then used as a "linker" to
|
||||
// detect when the process creation succeeds.
|
||||
//
|
||||
// Eventually we should see an argument that looks like `@` as we switch from
|
||||
// passing literal arguments to passing everything in the file.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
@ -43,8 +34,7 @@ fn read_linker_args(path: &Path) -> String {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let tmpdir = PathBuf::from(env::var_os("TMPDIR").unwrap());
|
||||
let ok = tmpdir.join("ok");
|
||||
let ok = PathBuf::from("ok");
|
||||
if env::var("YOU_ARE_A_LINKER").is_ok() {
|
||||
if let Some(file) = env::args_os().find(|a| a.to_string_lossy().contains("@")) {
|
||||
let file = file.to_str().expect("non-utf8 file argument");
|
||||
@ -53,11 +43,11 @@ fn main() {
|
||||
return;
|
||||
}
|
||||
|
||||
let rustc = env::var_os("RUSTC").unwrap_or("rustc".into());
|
||||
let rustc = env::var_os("RUSTC").unwrap();
|
||||
let me_as_linker = format!("linker={}", env::current_exe().unwrap().display());
|
||||
for i in (1..).map(|i| i * 100) {
|
||||
println!("attempt: {}", i);
|
||||
let file = tmpdir.join("bar.rs");
|
||||
let file = PathBuf::from("bar.rs");
|
||||
let mut expected_libs = write_test_case(&file, i);
|
||||
|
||||
drop(fs::remove_file(&ok));
|
||||
@ -65,8 +55,6 @@ fn main() {
|
||||
.arg(&file)
|
||||
.arg("-C")
|
||||
.arg(&me_as_linker)
|
||||
.arg("--out-dir")
|
||||
.arg(&tmpdir)
|
||||
.env("YOU_ARE_A_LINKER", "1")
|
||||
.output()
|
||||
.unwrap();
|
||||
|
19
tests/run-make/long-linker-command-lines/rmake.rs
Normal file
19
tests/run-make/long-linker-command-lines/rmake.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// This is a test which attempts to blow out the system limit with how many
|
||||
// arguments can be passed to a process. This'll successively call rustc with
|
||||
// larger and larger argument lists in an attempt to find one that's way too
|
||||
// big for the system at hand. This file itself is then used as a "linker" to
|
||||
// detect when the process creation succeeds.
|
||||
//
|
||||
// Eventually we should see an argument that looks like `@` as we switch from
|
||||
// passing literal arguments to passing everything in the file.
|
||||
// See https://github.com/rust-lang/rust/issues/41190
|
||||
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
use run_make_support::{run, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").arg("-g").opt().run();
|
||||
run("foo");
|
||||
}
|
Loading…
Reference in New Issue
Block a user