Skip to content
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

Switch azure to macOS 10.15. #7906

Merged
merged 2 commits into from
Feb 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 2 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,8 @@ may also need to install additional tools for the target. For example, on Ubuntu
you should install the `gcc-multilib` package.

If you can't install an alternate target, you can set the
`CFG_DISABLE_CROSS_TESTS=1` environment variable to disable these tests.
Unfortunately 32-bit support on macOS is going away, so you may not be able to
run these tests on macOS. The Windows cross tests only support the MSVC
toolchain.
`CFG_DISABLE_CROSS_TESTS=1` environment variable to disable these tests. The
Windows cross tests only support the MSVC toolchain.

Some of the nightly tests require the `rustc-dev` component installed. This
component includes the compiler as a library. This may already be installed
Expand Down
4 changes: 2 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ jobs:

- job: macOS
pool:
vmImage: macos-10.13
vmImage: macos-10.15
steps:
- template: ci/azure-test-all.yml
variables:
TOOLCHAIN: stable
OTHER_TARGET: i686-apple-darwin
OTHER_TARGET: x86_64-apple-ios

- job: Windows
pool:
Expand Down
11 changes: 0 additions & 11 deletions ci/azure-install-rust.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
steps:
- bash: |
set -e
if command -v rustup; then
echo `command -v rustup` `rustup -V` already installed
rustup self update
else
curl -sSL https://sh.rustup.rs | sh -s -- -y --default-toolchain="$TOOLCHAIN" --profile=minimal
echo "##vso[task.prependpath]$HOME/.cargo/bin"
fi
displayName: Install rustup

- bash: |
set -e
rustup set profile minimal
Expand Down
208 changes: 143 additions & 65 deletions crates/cargo-test-support/src/cross_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,70 @@
//!
//! These tests are all disabled on rust-lang/rust's CI, but run in Cargo's CI.

use crate::{basic_bin_manifest, main_file, project};
use crate::{basic_manifest, main_file, project};
use cargo::util::ProcessError;
use cargo::CargoResult;
use std::env;
use std::process::Command;
use std::fmt::Write;
use std::process::{Command, Output};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once;

/// Whether or not the resulting cross binaries can run on the host.
static CAN_RUN_ON_HOST: AtomicBool = AtomicBool::new(false);

pub fn disabled() -> bool {
// First, disable if `./configure` requested so.
// First, disable if requested.
match env::var("CFG_DISABLE_CROSS_TESTS") {
Ok(ref s) if *s == "1" => return true,
_ => {}
}

// Right now, the Windows bots cannot cross compile due to the Mingw setup,
// so we disable ourselves on all but macOS/Linux setups where the rustc
// install script ensures we have both architectures.
// Cross tests are only tested to work on macos, linux, and MSVC windows.
if !(cfg!(target_os = "macos") || cfg!(target_os = "linux") || cfg!(target_env = "msvc")) {
return true;
}

// It's not particularly common to have a cross-compilation setup, so
// try to detect that before we fail a bunch of tests through no fault
// of the user.
static CAN_RUN_CROSS_TESTS: AtomicBool = AtomicBool::new(false);
static CAN_BUILD_CROSS_TESTS: AtomicBool = AtomicBool::new(false);
static CHECK: Once = Once::new();

let cross_target = alternate();

CHECK.call_once(|| {
let run_cross_test = || -> CargoResult<Output> {
let p = project()
.at("cross_test")
.file("Cargo.toml", &basic_bin_manifest("cross_test"))
.file("src/cross_test.rs", &main_file(r#""testing!""#, &[]))
.file("Cargo.toml", &basic_manifest("cross_test", "1.0.0"))
.file("src/main.rs", &main_file(r#""testing!""#, &[]))
.build();

let result = p
let build_result = p
.cargo("build --target")
.arg(&cross_target)
.exec_with_output();

if build_result.is_ok() {
CAN_BUILD_CROSS_TESTS.store(true, Ordering::SeqCst);
}

let result = p
.cargo("run --target")
.arg(&cross_target)
.exec_with_output();

if result.is_ok() {
CAN_RUN_CROSS_TESTS.store(true, Ordering::SeqCst);
CAN_RUN_ON_HOST.store(true, Ordering::SeqCst);
}
build_result
};

CHECK.call_once(|| {
drop(run_cross_test());
});

if CAN_RUN_CROSS_TESTS.load(Ordering::SeqCst) {
if CAN_BUILD_CROSS_TESTS.load(Ordering::SeqCst) {
// We were able to compile a simple project, so the user has the
// necessary `std::` bits installed. Therefore, tests should not
// be disabled.
Expand All @@ -75,74 +93,134 @@ pub fn disabled() -> bool {
}

// We are responsible for warning the user, which we do by panicking.
let rustup_available = Command::new("rustup").output().is_ok();

let linux_help = if cfg!(target_os = "linux") {
let mut message = format!(
"
Cannot cross compile to {}.

You may need to install runtime libraries for your Linux distribution as well."
.to_string()
} else {
"".to_string()
};
This failure can be safely ignored. If you would prefer to not see this
failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \"1\".

let rustup_help = if rustup_available {
format!(
Alternatively, you can install the necessary libraries to enable cross
compilation tests. Cross compilation tests depend on your host platform.
",
cross_target
);

if cfg!(target_os = "linux") {
message.push_str(
"
Linux cross tests target i686-unknown-linux-gnu, which requires the ability to
build and run 32-bit targets. This requires the 32-bit libraries to be
installed. For example, on Ubuntu, run `sudo apt install gcc-multilib` to
install the necessary libraries.
",
);
} else if cfg!(target_os = "macos") {
message.push_str(
"
macOS cross tests target x86_64-apple-ios, which requires the iOS SDK to be
installed. This should be included with Xcode automatically. If you are using
the Xcode command line tools, you'll need to install the full Xcode app (from
the Apple App Store), and switch to it with this command:

Alternatively, you can install the necessary libraries for cross-compilation with
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

rustup target add {}{}",
cross_target, linux_help
)
Some cross-tests want to *run* the executables on the host. These tests will
be ignored if this is not possible. On macOS, this means you need an iOS
simulator installed to run these tests. To install a simulator, open Xcode, go
to preferences > Components, and download the latest iOS simulator.
",
);
} else if cfg!(target_os = "windows") {
message.push_str(
"
Windows cross tests target i686-pc-windows-msvc, which requires the ability
to build and run 32-bit targets. This should work automatically if you have
properly installed Visual Studio build tools.
",
);
} else {
"".to_string()
};
// The check at the top should prevent this.
panic!("platform should have been skipped");
}

panic!(
"Cannot cross compile to {}.
let rustup_available = Command::new("rustup").output().is_ok();
if rustup_available {
write!(
message,
"
Make sure that the appropriate `rustc` target is installed with rustup:

This failure can be safely ignored. If you would prefer to not see this
failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \"1\".{}
rustup target add {}
",
cross_target, rustup_help
);
cross_target
)
.unwrap();
} else {
write!(
message,
"
rustup does not appear to be installed. Make sure that the appropriate
`rustc` target is installed for the target `{}`.
",
cross_target
)
.unwrap();
}

// Show the actual error message.
match run_cross_test() {
Ok(_) => message.push_str("\nUh oh, second run succeeded?\n"),
Err(err) => match err.downcast_ref::<ProcessError>() {
Some(proc_err) => write!(message, "\nTest error: {}\n", proc_err).unwrap(),
None => write!(message, "\nUnexpected non-process error: {}\n", err).unwrap(),
},
}

panic!(message);
}

pub fn alternate() -> String {
let platform = match env::consts::OS {
"linux" => "unknown-linux-gnu",
"macos" => "apple-darwin",
"windows" => "pc-windows-msvc",
_ => unreachable!(),
};
let arch = match env::consts::ARCH {
"x86" => "x86_64",
"x86_64" => "i686",
_ => unreachable!(),
};
format!("{}-{}", arch, platform)
/// The alternate target-triple to build with.
///
/// Only use this function on tests that check `cross_compile::disabled`.
pub fn alternate() -> &'static str {
if cfg!(target_os = "macos") {
"x86_64-apple-ios"
} else if cfg!(target_os = "linux") {
"i686-unknown-linux-gnu"
} else if cfg!(all(target_os = "windows", target_env = "msvc")) {
"i686-pc-windows-msvc"
} else {
panic!("This test should be gated on cross_compile::disabled.");
}
}

pub fn alternate_arch() -> &'static str {
match env::consts::ARCH {
"x86" => "x86_64",
"x86_64" => "x86",
_ => unreachable!(),
if cfg!(target_os = "macos") {
"x86_64"
} else {
"x86"
}
}

pub fn host() -> String {
let platform = match env::consts::OS {
"linux" => "unknown-linux-gnu",
"macos" => "apple-darwin",
"windows" => "pc-windows-msvc",
_ => unreachable!(),
};
let arch = match env::consts::ARCH {
"x86" => "i686",
"x86_64" => "x86_64",
_ => unreachable!(),
};
format!("{}-{}", arch, platform)
/// Whether or not the host can run cross-compiled executables.
pub fn can_run_on_host() -> bool {
if disabled() {
return false;
}
// macos is currently configured to cross compile to x86_64-apple-ios
// which requires a simulator to run. Azure's CI image appears to have the
// SDK installed, but are not configured to launch iOS images with a
// simulator.
if cfg!(target_os = "macos") {
if CAN_RUN_ON_HOST.load(Ordering::SeqCst) {
return true;
} else {
println!("Note: Cannot run on host, skipping.");
return false;
}
} else {
assert!(CAN_RUN_ON_HOST.load(Ordering::SeqCst));
return true;
}
}
4 changes: 4 additions & 0 deletions crates/cargo-test-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,10 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
.env_remove("GIT_COMMITTER_NAME")
.env_remove("GIT_COMMITTER_EMAIL")
.env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows
if cfg!(target_os = "macos") {
// Work-around a bug in macOS 10.15, see `link_or_copy` for details.
p.env("__CARGO_COPY_DONT_LINK_DO_NOT_USE_THIS", "1");
}
p
}

Expand Down
15 changes: 14 additions & 1 deletion src/cargo/util/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,20 @@ fn _link_or_copy(src: &Path, dst: &Path) -> CargoResult<()> {
};
symlink(src, dst)
} else {
fs::hard_link(src, dst)
if env::var_os("__CARGO_COPY_DONT_LINK_DO_NOT_USE_THIS").is_some() {
// This is a work-around for a bug in macOS 10.15. When running on
// APFS, there seems to be a strange race condition with
// Gatekeeper where it will forcefully kill a process launched via
// `cargo run` with SIGKILL. Copying seems to avoid the problem.
// This shouldn't affect anyone except Cargo's test suite because
// it is very rare, and only seems to happen under heavy load and
// rapidly creating lots of executables and running them.
// See https://github.com/rust-lang/cargo/issues/7821 for the
// gory details.
fs::copy(src, dst).map(|_| ())
} else {
fs::hard_link(src, dst)
}
};
link_result
.or_else(|err| {
Expand Down
2 changes: 2 additions & 0 deletions tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3554,6 +3554,8 @@ fn rename_with_link_search_path() {
}

#[cargo_test]
// Don't have a cdylib cross target on macos.
#[cfg_attr(target_os = "macos", ignore)]
fn rename_with_link_search_path_cross() {
if cross_compile::disabled() {
return;
Expand Down
Loading