Skip to content

[WIP] [WIP] Enable automatic cross-compilation in run-make tests #139244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
36eea9f
Enable automatic cross-compilation in run-make tests
Kobzol Mar 5, 2025
e0957e7
[DO NOT MERGE] ----- commit stack separator -----
jieyouxu Apr 13, 2025
7913706
run-make-support: enable automatic cross-compilation for `rustdoc` too
jieyouxu Apr 2, 2025
42000eb
tests: use `bare_rustdoc` for `rustdoc-default-output`
jieyouxu Apr 2, 2025
e95fdc0
tests: ignore some doctests on cross-compile
jieyouxu Apr 19, 2025
cbdcb85
tests: adjust `embed-metadata` for cross-compile
jieyouxu Apr 19, 2025
0fa62e2
tests: adjust `embed-source-dwarf`
jieyouxu Apr 19, 2025
0d81211
tests: adjust `emit-stack-sizes`
jieyouxu Apr 19, 2025
da0521d
tests: adjust `invalid-so`
jieyouxu Apr 19, 2025
3a7ccb4
tests: ignore `env-dep-info` on cross-compile
jieyouxu Apr 19, 2025
df33a5b
tests: ignore `link-args-order` on cross-compile
jieyouxu Apr 19, 2025
ea09b00
tests: ignore `link-dedup` on cross-compile
jieyouxu Apr 19, 2025
d130889
tests: ignore `linker-warning` on cross-compile
jieyouxu Apr 19, 2025
6835798
tests: ignore `native-link-modifier-verbatim-link`
jieyouxu Apr 19, 2025
a845409
tests: ignore `no-builtins-attribute`
jieyouxu Apr 19, 2025
3104dd6
tests: fix `proc-macro-three-crates`
jieyouxu Apr 19, 2025
4a13088
tests: ignore `repr128-dwarf` on cross-compile
jieyouxu Apr 19, 2025
3e48b49
tests: fix `rustc-macro-dep-files`
jieyouxu Apr 19, 2025
fc7ca19
tests: fix `share-generics-dylib`
jieyouxu Apr 19, 2025
a62ec9b
tests: fix `stdin-rustc`
jieyouxu Apr 19, 2025
c334cb2
tests: fix `stdin-rustdoc`
jieyouxu Apr 19, 2025
89fce85
tests: fix `symbol-visibility`
jieyouxu Apr 19, 2025
96d6a81
tests: fix `track-path-dep-info`
jieyouxu Apr 19, 2025
150c4cc
tests: fix `used`
jieyouxu Apr 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/tools/run-make-support/src/external_deps/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::command::Command;
use crate::env::env_var;
use crate::path_helpers::cwd;
use crate::util::set_host_compiler_dylib_path;
use crate::{is_aix, is_darwin, is_msvc, is_windows, uname};
use crate::{is_aix, is_darwin, is_msvc, is_windows, target, uname};

/// Construct a new `rustc` invocation. This will automatically set the library
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
Expand All @@ -27,9 +27,15 @@ pub fn bare_rustc() -> Rustc {
#[must_use]
pub struct Rustc {
cmd: Command,
target: Option<String>,
}

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

pub fn rustc_path() -> String {
env_var("RUSTC")
Expand All @@ -46,19 +52,22 @@ impl Rustc {
// `rustc` invocation constructor methods

/// Construct a new `rustc` invocation. This will automatically set the library
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
/// search path as `-L cwd()` and also the compilation target.
/// Use [`bare_rustc`] to avoid this.
#[track_caller]
pub fn new() -> Self {
let mut cmd = setup_common();
cmd.arg("-L").arg(cwd());
Self { cmd }

// Automatically default to cross-compilation
Self { cmd, target: Some(target()) }
}

/// Construct a bare `rustc` invocation with no flags set.
#[track_caller]
pub fn bare() -> Self {
let cmd = setup_common();
Self { cmd }
Self { cmd, target: None }
}

// Argument provider methods
Expand Down Expand Up @@ -234,8 +243,9 @@ impl Rustc {

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

Expand Down
35 changes: 29 additions & 6 deletions src/tools/run-make-support/src/external_deps/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,35 @@ use std::path::Path;

use crate::command::Command;
use crate::env::env_var;
use crate::target;
use crate::util::set_host_compiler_dylib_path;

/// Construct a new `rustdoc` invocation.
/// Construct a new `rustdoc` invocation with target automatically set to cross-compile target. Use
/// [`bare_rustdoc`] to avoid this.
#[track_caller]
pub fn rustdoc() -> Rustdoc {
Rustdoc::new()
}

/// Bare `rustdoc` invocation, no args set.
#[track_caller]
pub fn bare_rustdoc() -> Rustdoc {
Rustdoc::bare()
}

#[derive(Debug)]
#[must_use]
pub struct Rustdoc {
cmd: Command,
target: Option<String>,
}

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

#[track_caller]
fn setup_common() -> Command {
Expand All @@ -28,11 +42,19 @@ fn setup_common() -> Command {
}

impl Rustdoc {
/// Construct a bare `rustdoc` invocation.
/// Construct a new `rustdoc` invocation with target automatically set to cross-compile target.
/// Use [`bare_rustdoc`] to avoid this.
#[track_caller]
pub fn new() -> Self {
let cmd = setup_common();
Self { cmd }
Self { cmd, target: Some(target()) }
}

/// Bare `rustdoc` invocation, no args set.
#[track_caller]
pub fn bare() -> Self {
let cmd = setup_common();
Self { cmd, target: None }
}

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

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

Expand Down
2 changes: 1 addition & 1 deletion src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub use llvm::{
};
pub use python::python_command;
pub use rustc::{bare_rustc, rustc, rustc_path, Rustc};
pub use rustdoc::{rustdoc, Rustdoc};
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};

/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
///
Expand Down
9 changes: 9 additions & 0 deletions src/tools/run-make-support/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@
/// }
/// ```
///
/// You can pass an optional second parameter which should be a function that is passed
/// `&mut self` just before the command is executed.
///
/// [`Command`]: crate::command::Command
/// [`CompletedProcess`]: crate::command::CompletedProcess
macro_rules! impl_common_helpers {
($wrapper: ident) => {
$crate::macros::impl_common_helpers!($wrapper, |_| {});
};
($wrapper: ident, $before_exec: expr) => {
impl $wrapper {
/// Specify an environment variable.
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
Expand Down Expand Up @@ -118,12 +124,14 @@ macro_rules! impl_common_helpers {
/// Run the constructed command and assert that it is successfully run.
#[track_caller]
pub fn run(&mut self) -> crate::command::CompletedProcess {
$before_exec(&mut *self);
self.cmd.run()
}

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

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

Expand Down
5 changes: 0 additions & 5 deletions tests/run-make/apple-deployment-target/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ fn main() {

// Remove env vars to get `rustc`'s default
let output = rustc()
.target(target())
.env_remove("MACOSX_DEPLOYMENT_TARGET")
.env_remove("IPHONEOS_DEPLOYMENT_TARGET")
.env_remove("WATCHOS_DEPLOYMENT_TARGET")
Expand All @@ -58,7 +57,6 @@ fn main() {
run_in_tmpdir(|| {
let rustc = || {
let mut rustc = rustc();
rustc.target(target());
rustc.crate_type("lib");
rustc.emit("obj");
rustc.input("foo.rs");
Expand All @@ -82,7 +80,6 @@ fn main() {

let rustc = || {
let mut rustc = rustc();
rustc.target(target());
rustc.crate_type("dylib");
rustc.input("foo.rs");
rustc.output("libfoo.dylib");
Expand All @@ -108,7 +105,6 @@ fn main() {
run_in_tmpdir(|| {
let rustc = || {
let mut rustc = rustc();
rustc.target(target());
rustc.crate_type("bin");
rustc.input("foo.rs");
rustc.output("foo");
Expand Down Expand Up @@ -147,7 +143,6 @@ fn main() {
run_in_tmpdir(|| {
let rustc = || {
let mut rustc = rustc();
rustc.target(target());
rustc.incremental("incremental");
rustc.crate_type("lib");
rustc.emit("obj");
Expand Down
9 changes: 3 additions & 6 deletions tests/run-make/apple-sdk-version/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ fn has_sdk_version(file: &str, version: &str) {

fn main() {
// Fetch rustc's inferred deployment target.
let current_deployment_target =
rustc().target(target()).print("deployment-target").run().stdout_utf8();
let current_deployment_target = rustc().print("deployment-target").run().stdout_utf8();
let current_deployment_target = current_deployment_target.split('=').last().unwrap().trim();

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

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

// Check the SDK version in the .rmeta file, as set in `create_object_file`.
//
// This is just to ensure that we don't set some odd version in `create_object_file`,
// if the rmeta file is packed in a different way in the future, this can safely be removed.
rustc().target(target()).crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
rustc().crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
// Extra .rmeta file (which is encoded as an object file).
cmd("ar").arg("-x").arg("libfoo.rlib").arg("lib.rmeta").run();
has_sdk_version("lib.rmeta", "n/a");
Expand All @@ -69,7 +68,6 @@ fn main() {
// Test with clang
let file_name = format!("foo_cc{file_ext}");
rustc()
.target(target())
.crate_type("bin")
.arg("-Clinker-flavor=gcc")
.input("foo.rs")
Expand All @@ -80,7 +78,6 @@ fn main() {
// Test with ld64
let file_name = format!("foo_ld{file_ext}");
rustc()
.target(target())
.crate_type("bin")
.arg("-Clinker-flavor=ld")
.input("foo.rs")
Expand Down
2 changes: 2 additions & 0 deletions tests/run-make/doctests-merge/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//@ ignore-cross-compile (needs to run doctests)

use std::path::Path;

use run_make_support::{cwd, diff, rustc, rustdoc};
Expand Down
2 changes: 2 additions & 0 deletions tests/run-make/doctests-runtool/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Tests behavior of rustdoc `--runtool`.

//@ ignore-cross-compile (attempts to run the doctests)

use std::path::PathBuf;

use run_make_support::rfs::{create_dir, remove_dir_all};
Expand Down
12 changes: 10 additions & 2 deletions tests/run-make/embed-metadata/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
// Tests the -Zembed-metadata compiler flag.
// Tracking issue: https://github.com/rust-lang/rust/issues/139165

//@ needs-dynamic-linking
//@ needs-crate-type: dylib

use run_make_support::rfs::{create_dir, remove_file, rename};
use run_make_support::{Rustc, dynamic_lib_name, path, run_in_tmpdir, rust_lib_name, rustc};
use run_make_support::{
Rustc, dynamic_lib_name, path, run_in_tmpdir, rust_lib_name, rustc, target,
};

#[derive(Debug, Copy, Clone)]
enum LibraryKind {
Expand Down Expand Up @@ -42,7 +47,7 @@ fn main() {
fn lookup_rmeta_in_lib_dir(kind: LibraryKind) {
run_in_tmpdir(|| {
build_dep_rustc(kind).run();
rustc().input("foo.rs").run();
rustc().target(target()).input("foo.rs").run();
});
}

Expand All @@ -54,6 +59,7 @@ fn lookup_rmeta_through_extern(kind: LibraryKind) {
build_dep_rustc(kind).out_dir("deps").run();

let mut rustc = rustc();
rustc.target(target());
kind.add_extern(&mut rustc, "dep1", "deps");
rustc.extern_("dep1", path("deps").join("libdep1.rmeta"));
rustc.input("foo.rs").run();
Expand All @@ -67,13 +73,15 @@ fn lookup_rmeta_missing(kind: LibraryKind) {
build_dep_rustc(kind).out_dir("deps").run();

let mut rustc = rustc();
rustc.target(target());
kind.add_extern(&mut rustc, "dep1", "deps");
rustc.input("foo.rs").run_fail().assert_stderr_contains("only metadata stub found");
});
}

fn build_dep_rustc(kind: LibraryKind) -> Rustc {
let mut dep_rustc = rustc();
dep_rustc.target(target());
dep_rustc
.arg("-Zembed-metadata=no")
.crate_type(kind.crate_type())
Expand Down
5 changes: 3 additions & 2 deletions tests/run-make/embed-source-dwarf/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//@ ignore-windows
//@ ignore-apple
//@ ignore-apple (needs DWARF)
//@ ignore-windows-msvc (needs DWARF)
//@ ignore-cross-compile (cross-compiled target can produce artifacts `object` can't yet parse)

// This test should be replaced with one in tests/debuginfo once we can easily
// tell via GDB or LLDB if debuginfo contains source code. Cheap tricks in LLDB
Expand Down
15 changes: 9 additions & 6 deletions tests/run-make/emit-stack-sizes/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
// this diagnostics information should be located.
// See https://github.com/rust-lang/rust/pull/51946

//@ ignore-windows
//@ ignore-apple
// Reason: this feature only works when the output object format is ELF.
// This won't be the case on Windows/OSX - for example, OSX produces a Mach-O binary.
//@ only-elf

use run_make_support::{llvm_readobj, rustc};
use run_make_support::{llvm_readobj, rustc, target};

fn main() {
rustc().opt_level("3").arg("-Zemit-stack-sizes").emit("obj").input("foo.rs").run();
rustc()
.target(target())
.opt_level("3")
.arg("-Zemit-stack-sizes")
.emit("obj")
.input("foo.rs")
.run();
llvm_readobj()
.arg("--section-headers")
.input("foo.o")
Expand Down
2 changes: 2 additions & 0 deletions tests/run-make/env-dep-info/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// appear in the output dep-info files.
// See https://github.com/rust-lang/rust/issues/40364

//@ ignore-cross-compile (cross-compile targets can introduce complicated env differences)

use run_make_support::{diff, rustc};

fn main() {
Expand Down
5 changes: 4 additions & 1 deletion tests/run-make/invalid-so/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
// explains that the file exists, but that its metadata is incorrect.
// See https://github.com/rust-lang/rust/pull/88368

use run_make_support::{dynamic_lib_name, rfs, rustc};
//@ needs-crate-type: dylib

use run_make_support::{dynamic_lib_name, rfs, rustc, target};

fn main() {
rfs::create_file(dynamic_lib_name("foo"));
rustc()
.target(target())
.crate_type("lib")
.extern_("foo", dynamic_lib_name("foo"))
.input("bar.rs")
Expand Down
2 changes: 2 additions & 0 deletions tests/run-make/link-args-order/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// checks that linker arguments remain intact and in the order they were originally passed in.
// See https://github.com/rust-lang/rust/pull/70665

//@ ignore-cross-compile (exercises host linker)

use run_make_support::{is_msvc, rustc};

fn main() {
Expand Down
Loading
Loading