Skip to content

Commit a0afa67

Browse files
committed
Auto merge of rust-lang#139244 - jieyouxu:exp/auto-cross-run-make, r=<try>
[WIP] [WIP] Enable automatic cross-compilation in run-make tests WIP for the WIP rust-lang#138066. Based on rust-lang#138066 with rust-lang#139242 + rust-lang#139239 cherry-picked in, plus `rustdoc()` cross-compile changes. r? `@ghost` 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: i686-mingw-1 try-job: aarch64-apple try-job: x86_64-apple-1
2 parents c9cd707 + c09efec commit a0afa67

File tree

14 files changed

+107
-67
lines changed

14 files changed

+107
-67
lines changed
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,26 @@ 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 {
74+
name.to_string()
75+
}
5176
}

src/tools/run-make-support/src/external_deps/rustc.rs

+17-21
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::command::Command;
66
use crate::env::env_var;
77
use crate::path_helpers::cwd;
88
use crate::util::set_host_compiler_dylib_path;
9-
use crate::{is_aix, is_darwin, is_msvc, is_windows, uname};
9+
use crate::{is_aix, is_darwin, is_msvc, is_windows, target, uname};
1010

1111
/// Construct a new `rustc` invocation. This will automatically set the library
1212
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
@@ -22,20 +22,20 @@ pub fn bare_rustc() -> Rustc {
2222
Rustc::bare()
2323
}
2424

25-
/// Construct a new `rustc` aux-build invocation.
26-
#[track_caller]
27-
pub fn aux_build() -> Rustc {
28-
Rustc::new_aux_build()
29-
}
30-
3125
/// A `rustc` invocation builder.
3226
#[derive(Debug)]
3327
#[must_use]
3428
pub struct Rustc {
3529
cmd: Command,
30+
target: Option<String>,
3631
}
3732

38-
crate::macros::impl_common_helpers!(Rustc);
33+
// Only fill in the target just before execution, so that it can be overridden.
34+
crate::macros::impl_common_helpers!(Rustc, |rustc: &mut Rustc| {
35+
if let Some(target) = &rustc.target {
36+
rustc.cmd.arg(&format!("--target={target}"));
37+
}
38+
});
3939

4040
pub fn rustc_path() -> String {
4141
env_var("RUSTC")
@@ -52,27 +52,22 @@ impl Rustc {
5252
// `rustc` invocation constructor methods
5353

5454
/// Construct a new `rustc` invocation. This will automatically set the library
55-
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
55+
/// search path as `-L cwd()` and also the compilation target.
56+
/// Use [`bare_rustc`] to avoid this.
5657
#[track_caller]
5758
pub fn new() -> Self {
5859
let mut cmd = setup_common();
5960
cmd.arg("-L").arg(cwd());
60-
Self { cmd }
61+
62+
// Automatically default to cross-compilation
63+
Self { cmd, target: Some(target()) }
6164
}
6265

6366
/// Construct a bare `rustc` invocation with no flags set.
6467
#[track_caller]
6568
pub fn bare() -> Self {
6669
let cmd = setup_common();
67-
Self { cmd }
68-
}
69-
70-
/// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
71-
#[track_caller]
72-
pub fn new_aux_build() -> Self {
73-
let mut cmd = setup_common();
74-
cmd.arg("--crate-type=lib");
75-
Self { cmd }
70+
Self { cmd, target: None }
7671
}
7772

7873
// Argument provider methods
@@ -248,8 +243,9 @@ impl Rustc {
248243

249244
/// Specify the target triple, or a path to a custom target json spec file.
250245
pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
251-
let target = target.as_ref();
252-
self.cmd.arg(format!("--target={target}"));
246+
// We store the target as a separate field, so that it can be specified multiple times.
247+
// This is in particular useful to override the default target set in Rustc::new().
248+
self.target = Some(target.as_ref().to_string());
253249
self
254250
}
255251

src/tools/run-make-support/src/external_deps/rustdoc.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,35 @@ use std::path::Path;
33

44
use crate::command::Command;
55
use crate::env::env_var;
6+
use crate::target;
67
use crate::util::set_host_compiler_dylib_path;
78

8-
/// Construct a new `rustdoc` invocation.
9+
/// Construct a new `rustdoc` invocation with target automatically set to cross-compile target. Use
10+
/// [`bare_rustdoc`] to avoid this.
911
#[track_caller]
1012
pub fn rustdoc() -> Rustdoc {
1113
Rustdoc::new()
1214
}
1315

16+
/// Bare `rustdoc` invocation, no args set.
17+
#[track_caller]
18+
pub fn bare_rustdoc() -> Rustdoc {
19+
Rustdoc::bare()
20+
}
21+
1422
#[derive(Debug)]
1523
#[must_use]
1624
pub struct Rustdoc {
1725
cmd: Command,
26+
target: Option<String>,
1827
}
1928

20-
crate::macros::impl_common_helpers!(Rustdoc);
29+
// Only fill in the target just before execution, so that it can be overridden.
30+
crate::macros::impl_common_helpers!(Rustdoc, |rustdoc: &mut Rustdoc| {
31+
if let Some(target) = &rustdoc.target {
32+
rustdoc.cmd.arg(&format!("--target={target}"));
33+
}
34+
});
2135

2236
#[track_caller]
2337
fn setup_common() -> Command {
@@ -28,11 +42,19 @@ fn setup_common() -> Command {
2842
}
2943

3044
impl Rustdoc {
31-
/// Construct a bare `rustdoc` invocation.
45+
/// Construct a new `rustdoc` invocation with target automatically set to cross-compile target.
46+
/// Use [`bare_rustdoc`] to avoid this.
3247
#[track_caller]
3348
pub fn new() -> Self {
3449
let cmd = setup_common();
35-
Self { cmd }
50+
Self { cmd, target: Some(target()) }
51+
}
52+
53+
/// Bare `rustdoc` invocation, no args set.
54+
#[track_caller]
55+
pub fn bare() -> Self {
56+
let cmd = setup_common();
57+
Self { cmd, target: None }
3658
}
3759

3860
/// Specify where an external library is located.
@@ -85,8 +107,9 @@ impl Rustdoc {
85107

86108
/// Specify the target triple, or a path to a custom target json spec file.
87109
pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
88-
let target = target.as_ref();
89-
self.cmd.arg(format!("--target={target}"));
110+
// We store the target as a separate field, so that it can be specified multiple times.
111+
// This is in particular useful to override the default target set in `Rustdoc::new()`.
112+
self.target = Some(target.as_ref().to_string());
90113
self
91114
}
92115

src/tools/run-make-support/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ pub use llvm::{
6868
LlvmFilecheck, LlvmNm, LlvmObjcopy, LlvmObjdump, LlvmProfdata, LlvmReadobj,
6969
};
7070
pub use python::python_command;
71-
pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
72-
pub use rustdoc::{rustdoc, Rustdoc};
71+
pub use rustc::{bare_rustc, rustc, rustc_path, Rustc};
72+
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
7373

7474
/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
7575
///

src/tools/run-make-support/src/macros.rs

+9
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@
2323
/// }
2424
/// ```
2525
///
26+
/// You can pass an optional second parameter which should be a function that is passed
27+
/// `&mut self` just before the command is executed.
28+
///
2629
/// [`Command`]: crate::command::Command
2730
/// [`CompletedProcess`]: crate::command::CompletedProcess
2831
macro_rules! impl_common_helpers {
2932
($wrapper: ident) => {
33+
$crate::macros::impl_common_helpers!($wrapper, |_| {});
34+
};
35+
($wrapper: ident, $before_exec: expr) => {
3036
impl $wrapper {
3137
/// Specify an environment variable.
3238
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
@@ -118,12 +124,14 @@ macro_rules! impl_common_helpers {
118124
/// Run the constructed command and assert that it is successfully run.
119125
#[track_caller]
120126
pub fn run(&mut self) -> crate::command::CompletedProcess {
127+
$before_exec(&mut *self);
121128
self.cmd.run()
122129
}
123130

124131
/// Run the constructed command and assert that it does not successfully run.
125132
#[track_caller]
126133
pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
134+
$before_exec(&mut *self);
127135
self.cmd.run_fail()
128136
}
129137

@@ -133,6 +141,7 @@ macro_rules! impl_common_helpers {
133141
/// whenever possible.
134142
#[track_caller]
135143
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
144+
$before_exec(&mut *self);
136145
self.cmd.run_unchecked()
137146
}
138147

tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
// Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current
44
// `rustc` version and the `since` property in feature stability gating is properly respected.
55

6-
use run_make_support::{aux_build, rfs, rustc, source_root};
6+
use run_make_support::{rfs, rustc, source_root};
77

88
fn main() {
9-
aux_build().input("stable.rs").emit("metadata").run();
9+
rustc().crate_type("lib").input("stable.rs").emit("metadata").run();
1010

1111
let output =
1212
rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run();

tests/run-make/apple-deployment-target/rmake.rs

-5
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ fn main() {
4141

4242
// Remove env vars to get `rustc`'s default
4343
let output = rustc()
44-
.target(target())
4544
.env_remove("MACOSX_DEPLOYMENT_TARGET")
4645
.env_remove("IPHONEOS_DEPLOYMENT_TARGET")
4746
.env_remove("WATCHOS_DEPLOYMENT_TARGET")
@@ -58,7 +57,6 @@ fn main() {
5857
run_in_tmpdir(|| {
5958
let rustc = || {
6059
let mut rustc = rustc();
61-
rustc.target(target());
6260
rustc.crate_type("lib");
6361
rustc.emit("obj");
6462
rustc.input("foo.rs");
@@ -82,7 +80,6 @@ fn main() {
8280

8381
let rustc = || {
8482
let mut rustc = rustc();
85-
rustc.target(target());
8683
rustc.crate_type("dylib");
8784
rustc.input("foo.rs");
8885
rustc.output("libfoo.dylib");
@@ -108,7 +105,6 @@ fn main() {
108105
run_in_tmpdir(|| {
109106
let rustc = || {
110107
let mut rustc = rustc();
111-
rustc.target(target());
112108
rustc.crate_type("bin");
113109
rustc.input("foo.rs");
114110
rustc.output("foo");
@@ -147,7 +143,6 @@ fn main() {
147143
run_in_tmpdir(|| {
148144
let rustc = || {
149145
let mut rustc = rustc();
150-
rustc.target(target());
151146
rustc.incremental("incremental");
152147
rustc.crate_type("lib");
153148
rustc.emit("obj");

tests/run-make/apple-sdk-version/rmake.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ fn has_sdk_version(file: &str, version: &str) {
2424

2525
fn main() {
2626
// Fetch rustc's inferred deployment target.
27-
let current_deployment_target =
28-
rustc().target(target()).print("deployment-target").run().stdout_utf8();
27+
let current_deployment_target = rustc().print("deployment-target").run().stdout_utf8();
2928
let current_deployment_target = current_deployment_target.split('=').last().unwrap().trim();
3029

3130
// Fetch current SDK version via. xcrun.
@@ -45,15 +44,15 @@ fn main() {
4544
let current_sdk_version = current_sdk_version.trim();
4645

4746
// Check the SDK version in the object file produced by the codegen backend.
48-
rustc().target(target()).crate_type("lib").emit("obj").input("foo.rs").output("foo.o").run();
47+
rustc().crate_type("lib").emit("obj").input("foo.rs").output("foo.o").run();
4948
// Set to 0, which means not set or "n/a".
5049
has_sdk_version("foo.o", "n/a");
5150

5251
// Check the SDK version in the .rmeta file, as set in `create_object_file`.
5352
//
5453
// This is just to ensure that we don't set some odd version in `create_object_file`,
5554
// if the rmeta file is packed in a different way in the future, this can safely be removed.
56-
rustc().target(target()).crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
55+
rustc().crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
5756
// Extra .rmeta file (which is encoded as an object file).
5857
cmd("ar").arg("-x").arg("libfoo.rlib").arg("lib.rmeta").run();
5958
has_sdk_version("lib.rmeta", "n/a");
@@ -69,7 +68,6 @@ fn main() {
6968
// Test with clang
7069
let file_name = format!("foo_cc{file_ext}");
7170
rustc()
72-
.target(target())
7371
.crate_type("bin")
7472
.arg("-Clinker-flavor=gcc")
7573
.input("foo.rs")
@@ -80,7 +78,6 @@ fn main() {
8078
// Test with ld64
8179
let file_name = format!("foo_ld{file_ext}");
8280
rustc()
83-
.target(target())
8481
.crate_type("bin")
8582
.arg("-Clinker-flavor=ld")
8683
.input("foo.rs")

0 commit comments

Comments
 (0)