Skip to content

Commit

Permalink
Auto merge of rust-lang#126097 - Kobzol:runmake-change-cwd, r=jieyouxu
Browse files Browse the repository at this point in the history
Change how runmake v2 tests are executed

This PR makes execution of v2 runmake tests more sane, by executing each test in a temporary directory by default, rather than running it inside `tests/run-make`. This will have.. a lot of conflicts.

Fixes: rust-lang#126080
Closes rust-lang#125726, because it removes `tmp_dir`, lol.

r? `@jieyouxu`
  • Loading branch information
bors committed Jun 8, 2024
2 parents 655600c + 5844b67 commit a5bdab9
Show file tree
Hide file tree
Showing 74 changed files with 275 additions and 302 deletions.
37 changes: 19 additions & 18 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -3471,6 +3471,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();

Expand Down Expand Up @@ -3530,18 +3545,11 @@ impl<'test> TestCx<'test> {
.env("PYTHON", &self.config.python)
.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();
Expand Down Expand Up @@ -3571,7 +3579,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())
Expand All @@ -3582,16 +3590,9 @@ impl<'test> TestCx<'test> {
.env("SOURCE_ROOT", &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));
Expand Down
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::*;
Expand Down Expand Up @@ -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.
///
Expand Down Expand Up @@ -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):
//
Expand All @@ -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
Expand Down
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 {
Expand Down Expand Up @@ -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
}

Expand Down
54 changes: 28 additions & 26 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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)
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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")
}
Expand All @@ -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]
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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:
///
Expand Down
6 changes: 3 additions & 3 deletions src/tools/run-make-support/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
4 changes: 2 additions & 2 deletions src/tools/run-make-support/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}

Expand Down
10 changes: 5 additions & 5 deletions tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use run_make_support::{aux_build, rustc, source_root};
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 = std::fs::read_to_string(source_root().join("src/version")).unwrap();
Expand Down
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())
Expand Down
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
Expand Up @@ -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
Expand Up @@ -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
Expand Up @@ -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

0 comments on commit a5bdab9

Please sign in to comment.