Skip to content

Commit 9fb7320

Browse files
committed
Auto merge of rust-lang#139242 - jieyouxu:run-make-artifact-names-cross, r=<try>
[WIP] run-make-support: Calculate artifact names for target platform, not host platform > [!CAUTION] > > Stacked on top of rust-lang#139469. This was implemented incorrectly during the porting process, where we relied on std consts. However, `run-make-support` is a host-only library, which meant that these artifact names were for the *host* and not the *target*. Helps with rust-lang#138066. r? `@Kobzol` try-job: armhf-gnu try-job: test-various try-job: x86_64-msvc-1 try-job: i686-msvc-1 try-job: x86_64-mingw-1 try-job: aarch64-apple try-job: x86_64-apple-1
2 parents c6c1796 + d9cb404 commit 9fb7320

File tree

24 files changed

+342
-99
lines changed

24 files changed

+342
-99
lines changed

src/doc/rustc-dev-guide/src/tests/directives.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,13 @@ settings:
190190
specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8,
191191
16, ptr` will only run if it supports the comma-separated list of atomic
192192
widths.
193-
- `needs-dynamic-linking` - ignores if target does not support dynamic linking
193+
- `needs-dynamic-linking` ignores if target does not support dynamic linking
194194
(which is orthogonal to it being unable to create `dylib` and `cdylib` crate types)
195+
- `needs-crate-type` — ignores if target platform does not support one or more
196+
of the comma-delimited list of specified crate types. For example,
197+
`//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored
198+
on `wasm32-unknown-unknown` target because the target does not support the
199+
`proc-macro` crate type.
195200

196201
The following directives will check LLVM support:
197202

src/tools/compiletest/src/common.rs

+31
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ pub struct Config {
398398

399399
pub target_cfgs: OnceLock<TargetCfgs>,
400400
pub builtin_cfg_names: OnceLock<HashSet<String>>,
401+
pub supported_crate_types: OnceLock<HashSet<String>>,
401402

402403
pub nocapture: bool,
403404

@@ -475,6 +476,11 @@ impl Config {
475476
self.builtin_cfg_names.get_or_init(|| builtin_cfg_names(self))
476477
}
477478

479+
/// Get the list of crate types that the target platform supports.
480+
pub fn supported_crate_types(&self) -> &HashSet<String> {
481+
self.supported_crate_types.get_or_init(|| supported_crate_types(self))
482+
}
483+
478484
pub fn has_threads(&self) -> bool {
479485
// Wasm targets don't have threads unless `-threads` is in the target
480486
// name, such as `wasm32-wasip1-threads`.
@@ -748,6 +754,31 @@ fn builtin_cfg_names(config: &Config) -> HashSet<String> {
748754
.collect()
749755
}
750756

757+
pub const KNOWN_CRATE_TYPES: &[&str] =
758+
&["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
759+
760+
fn supported_crate_types(config: &Config) -> HashSet<String> {
761+
let crate_types: HashSet<_> = rustc_output(
762+
config,
763+
&["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"],
764+
Default::default(),
765+
)
766+
.lines()
767+
.map(|l| l.to_string())
768+
.collect();
769+
770+
for crate_type in crate_types.iter() {
771+
assert!(
772+
KNOWN_CRATE_TYPES.contains(&crate_type.as_str()),
773+
"unexpected crate type `{}`: known crate types are {:?}",
774+
crate_type,
775+
KNOWN_CRATE_TYPES
776+
);
777+
}
778+
779+
crate_types
780+
}
781+
751782
fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
752783
let mut command = Command::new(&config.rustc_path);
753784
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));

src/tools/compiletest/src/directive-list.rs

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
132132
"min-llvm-version",
133133
"min-system-llvm-version",
134134
"needs-asm-support",
135+
"needs-crate-type",
135136
"needs-deterministic-layouts",
136137
"needs-dlltool",
137138
"needs-dynamic-linking",

src/tools/compiletest/src/header/needs.rs

+46-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use crate::common::{Config, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
1+
use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
22
use crate::header::{IgnoreDecision, llvm_has_libzstd};
33

44
pub(super) fn handle_needs(
55
cache: &CachedNeedsConditions,
66
config: &Config,
77
ln: &str,
88
) -> IgnoreDecision {
9-
// Note thet we intentionally still put the needs- prefix here to make the file show up when
9+
// Note that we intentionally still put the needs- prefix here to make the file show up when
1010
// grepping for a directive name, even though we could technically strip that.
1111
let needs = &[
1212
Need {
@@ -224,6 +224,50 @@ pub(super) fn handle_needs(
224224
}
225225
}
226226

227+
// FIXME(jieyouxu): share multi-value directive logic with `needs-target-has-atomic` above.
228+
if name == "needs-crate-type" {
229+
let Some(rest) = rest else {
230+
return IgnoreDecision::Error {
231+
message:
232+
"expected `needs-crate-type` to have a comma-separated list of crate types"
233+
.to_string(),
234+
};
235+
};
236+
237+
// Expect directive value to be a list of comma-separated crate-types.
238+
let specified_crate_types = rest
239+
.split(',')
240+
.map(|crate_type| crate_type.trim())
241+
.map(ToString::to_string)
242+
.collect::<Vec<String>>();
243+
244+
for crate_type in &specified_crate_types {
245+
if !KNOWN_CRATE_TYPES.contains(&crate_type.as_str()) {
246+
return IgnoreDecision::Error {
247+
message: format!(
248+
"unknown crate type specified in `needs-crate-type`: `{crate_type}` is not \
249+
a known crate type, known values are `{:?}`",
250+
KNOWN_CRATE_TYPES
251+
),
252+
};
253+
}
254+
}
255+
256+
let satisfies_all_crate_types = specified_crate_types
257+
.iter()
258+
.all(|specified| config.supported_crate_types().contains(specified));
259+
if satisfies_all_crate_types {
260+
return IgnoreDecision::Continue;
261+
} else {
262+
return IgnoreDecision::Ignore {
263+
reason: format!(
264+
"skipping test as target does not support all of the crate types `{:?}`",
265+
specified_crate_types
266+
),
267+
};
268+
}
269+
}
270+
227271
if !name.starts_with("needs-") {
228272
return IgnoreDecision::Continue;
229273
}

src/tools/compiletest/src/header/tests.rs

+39
Original file line numberDiff line numberDiff line change
@@ -905,3 +905,42 @@ fn test_rustc_abi() {
905905
assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
906906
assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
907907
}
908+
909+
#[cfg(not(bootstrap))]
910+
#[test]
911+
fn test_supported_crate_types() {
912+
// Basic assumptions check on under-test compiler's `--print=supported-crate-types` output based
913+
// on knowledge about the cherry-picked `x86_64-unknown-linux-gnu` and `wasm32-unknown-unknown`
914+
// targets. Also smoke tests the `needs-crate-type` directive itself.
915+
916+
use std::collections::HashSet;
917+
918+
let config = cfg().target("x86_64-unknown-linux-gnu").build();
919+
assert_eq!(
920+
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
921+
HashSet::from(["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"]),
922+
);
923+
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
924+
assert!(!check_ignore(&config, "//@ needs-crate-type: dylib"));
925+
assert!(!check_ignore(
926+
&config,
927+
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
928+
));
929+
930+
let config = cfg().target("wasm32-unknown-unknown").build();
931+
assert_eq!(
932+
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
933+
HashSet::from(["bin", "cdylib", "lib", "rlib", "staticlib"]),
934+
);
935+
936+
// rlib is supported
937+
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
938+
// dylib is not
939+
assert!(check_ignore(&config, "//@ needs-crate-type: dylib"));
940+
// If multiple crate types are specified, then all specified crate types need to be supported.
941+
assert!(check_ignore(&config, "//@ needs-crate-type: cdylib, dylib"));
942+
assert!(check_ignore(
943+
&config,
944+
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
945+
));
946+
}

src/tools/compiletest/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
433433

434434
target_cfgs: OnceLock::new(),
435435
builtin_cfg_names: OnceLock::new(),
436+
supported_crate_types: OnceLock::new(),
436437

437438
nocapture: matches.opt_present("no-capture"),
438439

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//! A collection of helpers to construct artifact names, such as names of dynamic or static
2-
//! librarys which are target-dependent.
3-
4-
// FIXME(jieyouxu): convert these to return `PathBuf`s instead of strings!
2+
//! libraries which are target-dependent.
53
4+
use crate::target;
65
use crate::targets::is_msvc;
76

87
/// Construct the static library name based on the target.
8+
#[track_caller]
99
#[must_use]
1010
pub fn static_lib_name(name: &str) -> String {
1111
assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
@@ -14,15 +14,34 @@ pub fn static_lib_name(name: &str) -> String {
1414
}
1515

1616
/// Construct the dynamic library name based on the target.
17+
#[track_caller]
1718
#[must_use]
1819
pub fn dynamic_lib_name(name: &str) -> String {
1920
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
2021

21-
format!("{}{name}.{}", std::env::consts::DLL_PREFIX, std::env::consts::DLL_EXTENSION)
22+
format!("{}{name}.{}", dynamic_lib_prefix(), dynamic_lib_extension())
23+
}
24+
25+
fn dynamic_lib_prefix() -> &'static str {
26+
if target().contains("windows") { "" } else { "lib" }
2227
}
2328

24-
/// Construct the name of the import library for the dynamic library, exclusive to MSVC and
25-
/// accepted by link.exe.
29+
/// Construct the dynamic library extension based on the target.
30+
#[must_use]
31+
pub fn dynamic_lib_extension() -> &'static str {
32+
let target = target();
33+
34+
if target.contains("apple") {
35+
"dylib"
36+
} else if target.contains("windows") {
37+
"dll"
38+
} else {
39+
"so"
40+
}
41+
}
42+
43+
/// Construct the name of the import library for the dynamic library, exclusive to MSVC and accepted
44+
/// by link.exe.
2645
#[track_caller]
2746
#[must_use]
2847
pub fn msvc_import_dynamic_lib_name(name: &str) -> String {
@@ -32,20 +51,28 @@ pub fn msvc_import_dynamic_lib_name(name: &str) -> String {
3251
format!("{name}.dll.lib")
3352
}
3453

35-
/// Construct the dynamic library extension based on the target.
36-
#[must_use]
37-
pub fn dynamic_lib_extension() -> &'static str {
38-
std::env::consts::DLL_EXTENSION
39-
}
40-
4154
/// Construct the name of a rust library (rlib).
55+
#[track_caller]
4256
#[must_use]
4357
pub fn rust_lib_name(name: &str) -> String {
4458
format!("lib{name}.rlib")
4559
}
4660

4761
/// Construct the binary (executable) name based on the target.
62+
#[track_caller]
4863
#[must_use]
4964
pub fn bin_name(name: &str) -> String {
50-
format!("{name}{}", std::env::consts::EXE_SUFFIX)
65+
let target = target();
66+
67+
if target.contains("windows") {
68+
format!("{name}.exe")
69+
} else if target.contains("uefi") {
70+
format!("{name}.efi")
71+
} else if target.contains("wasm") {
72+
format!("{name}.wasm")
73+
} else if target.contains("nvptx") {
74+
format!("{name}.ptx")
75+
} else {
76+
name.to_string()
77+
}
5178
}
+27-5
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,43 @@
1-
use run_make_support::{bin_name, rust_lib_name, rustc};
1+
use run_make_support::{bin_name, rust_lib_name, rustc, target};
22

33
fn main() {
4-
rustc().print("crate-name").input("crate.rs").run().assert_stdout_equals("foo");
5-
rustc().print("file-names").input("crate.rs").run().assert_stdout_equals(bin_name("foo"));
64
rustc()
5+
.target(target())
6+
.print("crate-name")
7+
.input("crate.rs")
8+
.run()
9+
.assert_stdout_equals("foo");
10+
rustc()
11+
.target(target())
12+
.print("file-names")
13+
.input("crate.rs")
14+
.run()
15+
.assert_stdout_equals(bin_name("foo"));
16+
rustc()
17+
.target(target())
718
.print("file-names")
819
.crate_type("lib")
920
.arg("--test")
1021
.input("crate.rs")
1122
.run()
1223
.assert_stdout_equals(bin_name("foo"));
1324
rustc()
25+
.target(target())
1426
.print("file-names")
1527
.arg("--test")
1628
.input("lib.rs")
1729
.run()
1830
.assert_stdout_equals(bin_name("mylib"));
19-
rustc().print("file-names").input("lib.rs").run().assert_stdout_equals(rust_lib_name("mylib"));
20-
rustc().print("file-names").input("rlib.rs").run().assert_stdout_equals(rust_lib_name("mylib"));
31+
rustc()
32+
.target(target())
33+
.print("file-names")
34+
.input("lib.rs")
35+
.run()
36+
.assert_stdout_equals(rust_lib_name("mylib"));
37+
rustc()
38+
.target(target())
39+
.print("file-names")
40+
.input("rlib.rs")
41+
.run()
42+
.assert_stdout_equals(rust_lib_name("mylib"));
2143
}

tests/run-make/crate-name-priority/rmake.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
// and the compiler flags, and checks that the flag is favoured each time.
55
// See https://github.com/rust-lang/rust/pull/15518
66

7-
use run_make_support::{bin_name, rfs, rustc};
7+
//@ ignore-cross-compile (relocations in generic ELF against `arm-unknown-linux-gnueabihf`)
8+
9+
use run_make_support::{bin_name, rfs, rustc, target};
810

911
fn main() {
10-
rustc().input("foo.rs").run();
12+
rustc().target(target()).input("foo.rs").run();
1113
rfs::remove_file(bin_name("foo"));
12-
rustc().input("foo.rs").crate_name("bar").run();
14+
rustc().target(target()).input("foo.rs").crate_name("bar").run();
1315
rfs::remove_file(bin_name("bar"));
14-
rustc().input("foo1.rs").run();
16+
rustc().target(target()).input("foo1.rs").run();
1517
rfs::remove_file(bin_name("foo"));
16-
rustc().input("foo1.rs").output(bin_name("bar1")).run();
18+
rustc().target(target()).input("foo1.rs").output(bin_name("bar1")).run();
1719
rfs::remove_file(bin_name("bar1"));
1820
}

tests/run-make/extra-filename-with-temp-outputs/rmake.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
// are named as expected.
77
// See https://github.com/rust-lang/rust/pull/15686
88

9-
use run_make_support::{bin_name, cwd, has_prefix, has_suffix, rfs, rustc, shallow_find_files};
9+
//@ ignore-cross-compile (relocations in generic ELF against `arm-unknown-linux-gnueabihf`)
10+
11+
use run_make_support::{
12+
bin_name, cwd, has_prefix, has_suffix, rfs, rustc, shallow_find_files, target,
13+
};
1014

1115
fn main() {
12-
rustc().extra_filename("bar").input("foo.rs").arg("-Csave-temps").run();
16+
rustc().target(target()).extra_filename("bar").input("foo.rs").arg("-Csave-temps").run();
1317
let object_files = shallow_find_files(cwd(), |path| {
1418
has_prefix(path, "foobar.foo") && has_suffix(path, "0.rcgu.o")
1519
});

0 commit comments

Comments
 (0)