Skip to content

Change how runmake v2 tests are executed #126097

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

Merged
merged 9 commits into from
Jun 8, 2024
Merged
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
37 changes: 19 additions & 18 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use crate::errors::{self, Error, ErrorKind};
use crate::header::TestProps;
use crate::json;
use crate::read2::{read2_abbreviated, Truncated};
use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
use crate::util::{add_dylib_path, copy_dir_all, dylib_env_var, logv, PathBufExt};
use crate::ColorConfig;
use colored::Colorize;
use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
@@ -3458,6 +3458,21 @@ impl<'test> TestCx<'test> {
let rmake_out_dir = base_dir.join("rmake_out");
create_dir_all(&rmake_out_dir).unwrap();

// Copy all input files (apart from rmake.rs) to the temporary directory,
// so that the input directory structure from `tests/run-make/<test>` is mirrored
// to the `rmake_out` directory.
for path in walkdir::WalkDir::new(&self.testpaths.file).min_depth(1) {
let path = path.unwrap().path().to_path_buf();
if path.file_name().is_some_and(|s| s != "rmake.rs") {
let target = rmake_out_dir.join(path.strip_prefix(&self.testpaths.file).unwrap());
if path.is_dir() {
copy_dir_all(&path, target).unwrap();
} else {
fs::copy(&path, target).unwrap();
}
}
}

// HACK: assume stageN-target, we only want stageN.
let stage = self.config.stage_id.split('-').next().unwrap();

@@ -3518,18 +3533,11 @@ impl<'test> TestCx<'test> {
.env("S", &src_root)
.env("RUST_BUILD_STAGE", &self.config.stage_id)
.env("RUSTC", cwd.join(&self.config.rustc_path))
.env("TMPDIR", &rmake_out_dir)
.env("LD_LIB_PATH_ENVVAR", dylib_env_var())
.env(dylib_env_var(), &host_dylib_env_paths)
.env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
.env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
.env("LLVM_COMPONENTS", &self.config.llvm_components)
// We for sure don't want these tests to run in parallel, so make
// sure they don't have access to these vars if we run via `make`
// at the top level
.env_remove("MAKEFLAGS")
.env_remove("MFLAGS")
.env_remove("CARGO_MAKEFLAGS");
.env("LLVM_COMPONENTS", &self.config.llvm_components);

if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
let mut stage0_sysroot = build_root.clone();
@@ -3559,7 +3567,7 @@ impl<'test> TestCx<'test> {
let target_rpath_env_path = env::join_paths(target_rpath_env_path).unwrap();

let mut cmd = Command::new(&recipe_bin);
cmd.current_dir(&self.testpaths.file)
cmd.current_dir(&rmake_out_dir)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.env("LD_LIB_PATH_ENVVAR", dylib_env_var())
@@ -3570,16 +3578,9 @@ impl<'test> TestCx<'test> {
.env("S", &src_root)
.env("RUST_BUILD_STAGE", &self.config.stage_id)
.env("RUSTC", cwd.join(&self.config.rustc_path))
.env("TMPDIR", &rmake_out_dir)
.env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
.env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
.env("LLVM_COMPONENTS", &self.config.llvm_components)
// We for sure don't want these tests to run in parallel, so make
// sure they don't have access to these vars if we run via `make`
// at the top level
.env_remove("MAKEFLAGS")
.env_remove("MFLAGS")
.env_remove("CARGO_MAKEFLAGS");
.env("LLVM_COMPONENTS", &self.config.llvm_components);

if let Some(ref rustdoc) = self.config.rustdoc_path {
cmd.env("RUSTDOC", cwd.join(rustdoc));
16 changes: 15 additions & 1 deletion src/tools/compiletest/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::common::Config;
use std::env;
use std::ffi::OsStr;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::process::Command;

use tracing::*;
@@ -76,3 +76,17 @@ pub fn add_dylib_path(cmd: &mut Command, paths: impl Iterator<Item = impl Into<P
let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten());
cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
}

pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> std::io::Result<()> {
std::fs::create_dir_all(&dst)?;
for entry in std::fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
} else {
std::fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())
}
13 changes: 5 additions & 8 deletions src/tools/run-make-support/src/cc.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::path::Path;
use std::process::Command;

use crate::{
bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, tmp_dir, uname,
};
use crate::{bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, uname};

/// Construct a new platform-specific C compiler invocation.
///
@@ -54,8 +52,7 @@ impl Cc {
self
}

/// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler. This assumes that the executable
/// is under `$TMPDIR`.
/// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler.
pub fn out_exe(&mut self, name: &str) -> &mut Self {
// Ref: tools.mk (irrelevant lines omitted):
//
@@ -69,13 +66,13 @@ impl Cc {
// ```

if is_msvc() {
let fe_path = cygpath_windows(tmp_dir().join(bin_name(name)));
let fo_path = cygpath_windows(tmp_dir().join(format!("{name}.obj")));
let fe_path = cygpath_windows(bin_name(name));
let fo_path = cygpath_windows(format!("{name}.obj"));
self.cmd.arg(format!("-Fe:{fe_path}"));
self.cmd.arg(format!("-Fo:{fo_path}"));
} else {
self.cmd.arg("-o");
self.cmd.arg(tmp_dir().join(name));
self.cmd.arg(name);
}

self
8 changes: 4 additions & 4 deletions src/tools/run-make-support/src/clang.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::Path;
use std::process::Command;

use crate::{bin_name, env_var, handle_failed_output, tmp_dir};
use crate::{bin_name, env_var, handle_failed_output};

/// Construct a new `clang` invocation. `clang` is not always available for all targets.
pub fn clang() -> Clang {
@@ -30,11 +30,11 @@ impl Clang {
self
}

/// Specify the name of the executable. The executable will be placed under `$TMPDIR`, and the
/// extension will be determined by [`bin_name`].
/// Specify the name of the executable. The executable will be placed under the current directory
/// and the extension will be determined by [`bin_name`].
pub fn out_exe(&mut self, name: &str) -> &mut Self {
self.cmd.arg("-o");
self.cmd.arg(tmp_dir().join(bin_name(name)));
self.cmd.arg(bin_name(name));
self
}

54 changes: 28 additions & 26 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
@@ -45,11 +45,6 @@ pub fn env_var_os(name: &str) -> OsString {
}
}

/// Path of `TMPDIR` (a temporary build directory, not under `/tmp`).
pub fn tmp_dir() -> PathBuf {
env_var_os("TMPDIR").into()
}

/// `TARGET`
pub fn target() -> String {
env_var("TARGET")
@@ -70,12 +65,6 @@ pub fn is_darwin() -> bool {
target().contains("darwin")
}

/// Construct a path to a static library under `$TMPDIR` given the library name. This will return a
/// path with `$TMPDIR` joined with platform-and-compiler-specific library name.
pub fn static_lib(name: &str) -> PathBuf {
tmp_dir().join(static_lib_name(name))
}

pub fn python_command() -> Command {
let python_path = env_var("PYTHON");
Command::new(python_path)
@@ -116,12 +105,6 @@ pub fn static_lib_name(name: &str) -> String {
if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
}

/// Construct a path to a dynamic library under `$TMPDIR` given the library name. This will return a
/// path with `$TMPDIR` joined with platform-and-compiler-specific library name.
pub fn dynamic_lib(name: &str) -> PathBuf {
tmp_dir().join(dynamic_lib_name(name))
}

/// Construct the dynamic library name based on the platform.
pub fn dynamic_lib_name(name: &str) -> String {
// See tools.mk (irrelevant lines omitted):
@@ -159,14 +142,7 @@ pub fn dynamic_lib_extension() -> &'static str {
}
}

/// Construct a path to a rust library (rlib) under `$TMPDIR` given the library name. This will return a
/// path with `$TMPDIR` joined with the library name.
pub fn rust_lib(name: &str) -> PathBuf {
tmp_dir().join(rust_lib_name(name))
}

/// Generate the name a rust library (rlib) would have. If you want the complete path, use
/// [`rust_lib`] instead.
/// Construct a rust library (rlib) name.
pub fn rust_lib_name(name: &str) -> String {
format!("lib{name}.rlib")
}
@@ -176,6 +152,11 @@ pub fn bin_name(name: &str) -> String {
if is_windows() { format!("{name}.exe") } else { name.to_string() }
}

/// Return the current working directory.
pub fn cwd() -> PathBuf {
env::current_dir().unwrap()
}

/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
/// available on the platform!
#[track_caller]
@@ -227,7 +208,7 @@ pub fn set_host_rpath(cmd: &mut Command) {
let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
cmd.env(&ld_lib_path_envvar, {
let mut paths = vec![];
paths.push(PathBuf::from(env_var("TMPDIR")));
paths.push(cwd());
paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
paths.push(p.to_path_buf());
@@ -315,6 +296,27 @@ pub fn assert_not_contains(haystack: &str, needle: &str) {
}
}

/// This function is designed for running commands in a temporary directory
/// that is cleared after the function ends.
///
/// What this function does:
/// 1) Creates a temporary directory (`tmpdir`)
/// 2) Copies all files from the current directory to `tmpdir`
/// 3) Changes the current working directory to `tmpdir`
/// 4) Calls `callback`
/// 5) Switches working directory back to the original one
/// 6) Removes `tmpdir`
pub fn run_in_tmpdir<F: FnOnce()>(callback: F) {
let original_dir = cwd();
let tmpdir = original_dir.join("../temporary-directory");
copy_dir_all(".", &tmpdir);

env::set_current_dir(&tmpdir).unwrap();
callback();
env::set_current_dir(original_dir).unwrap();
fs::remove_dir_all(tmpdir).unwrap();
}

/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
///
6 changes: 3 additions & 3 deletions src/tools/run-make-support/src/run.rs
Original file line number Diff line number Diff line change
@@ -2,19 +2,19 @@ use std::env;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};

use crate::{env_var, is_windows};
use crate::{cwd, env_var, is_windows};

use super::handle_failed_output;

fn run_common(name: &str) -> (Command, Output) {
let mut bin_path = PathBuf::new();
bin_path.push(env_var("TMPDIR"));
bin_path.push(cwd());
bin_path.push(name);
let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
let mut cmd = Command::new(bin_path);
cmd.env(&ld_lib_path_envvar, {
let mut paths = vec![];
paths.push(PathBuf::from(env_var("TMPDIR")));
paths.push(cwd());
for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) {
paths.push(p.to_path_buf());
}
4 changes: 2 additions & 2 deletions src/tools/run-make-support/src/rustc.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ use std::io::Write;
use std::path::Path;
use std::process::{Command, Output, Stdio};

use crate::{env_var, handle_failed_output, set_host_rpath, tmp_dir};
use crate::{cwd, env_var, handle_failed_output, set_host_rpath};

/// Construct a new `rustc` invocation.
pub fn rustc() -> Rustc {
@@ -28,7 +28,7 @@ fn setup_common() -> Command {
let rustc = env_var("RUSTC");
let mut cmd = Command::new(rustc);
set_host_rpath(&mut cmd);
cmd.arg("--out-dir").arg(tmp_dir()).arg("-L").arg(tmp_dir());
cmd.arg("-L").arg(cwd());
cmd
}

10 changes: 5 additions & 5 deletions tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
Original file line number Diff line number Diff line change
@@ -10,11 +10,11 @@ use run_make_support::{aux_build, rustc};
fn main() {
aux_build().input("stable.rs").emit("metadata").run();

let mut stable_path = PathBuf::from(env!("TMPDIR"));
stable_path.push("libstable.rmeta");

let output =
rustc().input("main.rs").emit("metadata").extern_("stable", &stable_path).command_output();
let output = rustc()
.input("main.rs")
.emit("metadata")
.extern_("stable", "libstable.rmeta")
.command_output();

let stderr = String::from_utf8_lossy(&output.stderr);
let version = include_str!(concat!(env!("S"), "/src/version"));
4 changes: 2 additions & 2 deletions tests/run-make/arguments-non-c-like-enum/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! Check that non-trivial `repr(C)` enum in Rust has valid C layout.
//@ ignore-cross-compile

use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib};
use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib_name};

pub fn main() {
use std::path::Path;

rustc().input("nonclike.rs").crate_type("staticlib").run();
cc().input("test.c")
.input(static_lib("nonclike"))
.input(static_lib_name("nonclike"))
.out_exe("test")
.args(&extra_c_flags())
.args(&extra_cxx_flags())
6 changes: 2 additions & 4 deletions tests/run-make/artifact-incr-cache-no-obj/rmake.rs
Original file line number Diff line number Diff line change
@@ -5,17 +5,15 @@
//
// Fixes: rust-lang/rust#123234

use run_make_support::{rustc, tmp_dir};
use run_make_support::rustc;

fn main() {
let inc_dir = tmp_dir();

for _ in 0..=1 {
rustc()
.input("lib.rs")
.crate_type("lib")
.emit("asm,dep-info,link,mir,llvm-ir,llvm-bc")
.incremental(&inc_dir)
.incremental("incremental")
.run();
}
}
6 changes: 2 additions & 4 deletions tests/run-make/artifact-incr-cache/rmake.rs
Original file line number Diff line number Diff line change
@@ -7,17 +7,15 @@
// Also see discussion at
// <https://internals.rust-lang.org/t/interaction-between-incremental-compilation-and-emit/20551>

use run_make_support::{rustc, tmp_dir};
use run_make_support::rustc;

fn main() {
let inc_dir = tmp_dir();

for _ in 0..=1 {
rustc()
.input("lib.rs")
.crate_type("lib")
.emit("obj,asm,dep-info,link,mir,llvm-ir,llvm-bc")
.incremental(&inc_dir)
.incremental("incremental")
.run();
}
}
6 changes: 1 addition & 5 deletions tests/run-make/bare-outfile/rmake.rs
Original file line number Diff line number Diff line change
@@ -3,13 +3,9 @@

//@ ignore-cross-compile

use run_make_support::{run, rustc, tmp_dir};
use std::env;
use std::fs;
use run_make_support::{run, rustc};

fn main() {
fs::copy("foo.rs", tmp_dir().join("foo.rs")).unwrap();
env::set_current_dir(tmp_dir());
rustc().output("foo").input("foo.rs").run();
run("foo");
}
Loading