mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #127760 - jieyouxu:rmake-support-reorganize, r=Kobzol
Reorganize the `run-make-support` library The `run_make_support` library has a kitchen sink `lib.rs` that make discovery/learning very difficult. Let's try to improve that by breaking up `lib.rs` into smaller more organized modules. This is a precursor to improving the documentation and learnability of the `run_make_support` library. ### Changes - Breakup `lib.rs` into smaller modules according to functionality - Rename `recursive_diff` -> `assert_dirs_are_equal` - Rename one of the `read_dir` with callback interface as `read_dir_entries` - Coalesced fs-related stuff onto a `fs` module, re-exported to tests as `rfs` - Minor doc improvements / fixes in a few places (I have a follow-up documentation PR planned) This PR is best reviewed commit-by-commit. r? `@Kobzol` (or Mark, or T-compiler or T-bootstrap) try-job: x86_64-msvc try-job: aarch64-apple try-job: test-various try-job: armhf-gnu try-job: dist-x86_64-linux
This commit is contained in:
commit
f00f850919
81
src/tools/run-make-support/src/artifact_names.rs
Normal file
81
src/tools/run-make-support/src/artifact_names.rs
Normal file
@ -0,0 +1,81 @@
|
||||
//! A collection of helpers to construct artifact names, such as names of dynamic or static
|
||||
//! librarys which are target-dependent.
|
||||
|
||||
use crate::targets::{is_darwin, is_msvc, is_windows};
|
||||
|
||||
/// Construct the static library name based on the target.
|
||||
#[must_use]
|
||||
pub fn static_lib_name(name: &str) -> String {
|
||||
// See tools.mk (irrelevant lines omitted):
|
||||
//
|
||||
// ```makefile
|
||||
// ifeq ($(UNAME),Darwin)
|
||||
// STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
// else
|
||||
// ifdef IS_WINDOWS
|
||||
// ifdef IS_MSVC
|
||||
// STATICLIB = $(TMPDIR)/$(1).lib
|
||||
// else
|
||||
// STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
// endif
|
||||
// else
|
||||
// STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
// endif
|
||||
// endif
|
||||
// ```
|
||||
assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
|
||||
|
||||
if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
|
||||
}
|
||||
|
||||
/// Construct the dynamic library name based on the target.
|
||||
#[must_use]
|
||||
pub fn dynamic_lib_name(name: &str) -> String {
|
||||
// See tools.mk (irrelevant lines omitted):
|
||||
//
|
||||
// ```makefile
|
||||
// ifeq ($(UNAME),Darwin)
|
||||
// DYLIB = $(TMPDIR)/lib$(1).dylib
|
||||
// else
|
||||
// ifdef IS_WINDOWS
|
||||
// DYLIB = $(TMPDIR)/$(1).dll
|
||||
// else
|
||||
// DYLIB = $(TMPDIR)/lib$(1).so
|
||||
// endif
|
||||
// endif
|
||||
// ```
|
||||
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
|
||||
|
||||
let extension = dynamic_lib_extension();
|
||||
if is_darwin() {
|
||||
format!("lib{name}.{extension}")
|
||||
} else if is_windows() {
|
||||
format!("{name}.{extension}")
|
||||
} else {
|
||||
format!("lib{name}.{extension}")
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct the dynamic library extension based on the target.
|
||||
#[must_use]
|
||||
pub fn dynamic_lib_extension() -> &'static str {
|
||||
if is_darwin() {
|
||||
"dylib"
|
||||
} else if is_windows() {
|
||||
"dll"
|
||||
} else {
|
||||
"so"
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct the name of a rust library (rlib).
|
||||
#[must_use]
|
||||
pub fn rust_lib_name(name: &str) -> String {
|
||||
format!("lib{name}.rlib")
|
||||
}
|
||||
|
||||
/// Construct the binary (executable) name based on the target.
|
||||
#[must_use]
|
||||
pub fn bin_name(name: &str) -> String {
|
||||
if is_windows() { format!("{name}.exe") } else { name.to_string() }
|
||||
}
|
73
src/tools/run-make-support/src/assertion_helpers.rs
Normal file
73
src/tools/run-make-support/src/assertion_helpers.rs
Normal file
@ -0,0 +1,73 @@
|
||||
//! Collection of assertions and assertion-related helpers.
|
||||
|
||||
use std::panic;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::fs;
|
||||
|
||||
/// Assert that `actual` is equal to `expected`.
|
||||
#[track_caller]
|
||||
pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) {
|
||||
let actual = actual.as_ref();
|
||||
let expected = expected.as_ref();
|
||||
if actual != expected {
|
||||
eprintln!("=== ACTUAL TEXT ===");
|
||||
eprintln!("{}", actual);
|
||||
eprintln!("=== EXPECTED ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("expected text was not found in actual text");
|
||||
}
|
||||
}
|
||||
|
||||
/// Assert that `haystack` contains `needle`.
|
||||
#[track_caller]
|
||||
pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
|
||||
let haystack = haystack.as_ref();
|
||||
let needle = needle.as_ref();
|
||||
if !haystack.contains(needle) {
|
||||
eprintln!("=== HAYSTACK ===");
|
||||
eprintln!("{}", haystack);
|
||||
eprintln!("=== NEEDLE ===");
|
||||
eprintln!("{}", needle);
|
||||
panic!("needle was not found in haystack");
|
||||
}
|
||||
}
|
||||
|
||||
/// Assert that `haystack` does not contain `needle`.
|
||||
#[track_caller]
|
||||
pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
|
||||
let haystack = haystack.as_ref();
|
||||
let needle = needle.as_ref();
|
||||
if haystack.contains(needle) {
|
||||
eprintln!("=== HAYSTACK ===");
|
||||
eprintln!("{}", haystack);
|
||||
eprintln!("=== NEEDLE ===");
|
||||
eprintln!("{}", needle);
|
||||
panic!("needle was unexpectedly found in haystack");
|
||||
}
|
||||
}
|
||||
|
||||
/// Assert that all files in `dir1` exist and have the same content in `dir2`
|
||||
pub fn assert_dirs_are_equal(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
|
||||
let dir2 = dir2.as_ref();
|
||||
fs::read_dir_entries(dir1, |entry_path| {
|
||||
let entry_name = entry_path.file_name().unwrap();
|
||||
if entry_path.is_dir() {
|
||||
assert_dirs_are_equal(&entry_path, &dir2.join(entry_name));
|
||||
} else {
|
||||
let path2 = dir2.join(entry_name);
|
||||
let file1 = fs::read(&entry_path);
|
||||
let file2 = fs::read(&path2);
|
||||
|
||||
// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
|
||||
// Why not using String? Because there might be minified files or even potentially
|
||||
// binary ones, so that would display useless output.
|
||||
assert!(
|
||||
file1 == file2,
|
||||
"`{}` and `{}` have different content",
|
||||
entry_path.display(),
|
||||
path2.display(),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
@ -5,7 +5,9 @@ use std::panic;
|
||||
use std::path::Path;
|
||||
use std::process::{Command as StdCommand, ExitStatus, Output, Stdio};
|
||||
|
||||
use crate::{assert_contains, assert_equals, assert_not_contains, handle_failed_output};
|
||||
use crate::util::handle_failed_output;
|
||||
use crate::{assert_contains, assert_equals, assert_not_contains};
|
||||
|
||||
use build_helper::drop_bomb::DropBomb;
|
||||
|
||||
/// This is a custom command wrapper that simplifies working with commands and makes it easier to
|
||||
|
@ -1,10 +1,12 @@
|
||||
use regex::Regex;
|
||||
use similar::TextDiff;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::fs_wrapper;
|
||||
use regex::Regex;
|
||||
use similar::TextDiff;
|
||||
|
||||
use build_helper::drop_bomb::DropBomb;
|
||||
|
||||
use crate::fs;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
@ -43,7 +45,7 @@ impl Diff {
|
||||
/// Specify the expected output for the diff from a file.
|
||||
pub fn expected_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
|
||||
let path = path.as_ref();
|
||||
let content = fs_wrapper::read_to_string(path);
|
||||
let content = fs::read_to_string(path);
|
||||
let name = path.to_string_lossy().to_string();
|
||||
|
||||
self.expected_file = Some(path.into());
|
||||
@ -62,7 +64,7 @@ impl Diff {
|
||||
/// Specify the actual output for the diff from a file.
|
||||
pub fn actual_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
|
||||
let path = path.as_ref();
|
||||
let content = fs_wrapper::read_to_string(path);
|
||||
let content = fs::read_to_string(path);
|
||||
let name = path.to_string_lossy().to_string();
|
||||
|
||||
self.actual = Some(content);
|
||||
@ -116,7 +118,7 @@ impl Diff {
|
||||
if let Some(ref expected_file) = self.expected_file {
|
||||
if std::env::var("RUSTC_BLESS_TEST").is_ok() {
|
||||
println!("Blessing `{}`", expected_file.display());
|
||||
fs_wrapper::write(expected_file, actual);
|
||||
fs::write(expected_file, actual);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -138,7 +140,7 @@ impl Diff {
|
||||
if let Some(ref expected_file) = self.expected_file {
|
||||
if std::env::var("RUSTC_BLESS_TEST").is_ok() {
|
||||
println!("Blessing `{}`", expected_file.display());
|
||||
fs_wrapper::write(expected_file, actual);
|
||||
fs::write(expected_file, actual);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
19
src/tools/run-make-support/src/env.rs
Normal file
19
src/tools/run-make-support/src/env.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn env_var(name: &str) -> String {
|
||||
match std::env::var(name) {
|
||||
Ok(v) => v,
|
||||
Err(err) => panic!("failed to retrieve environment variable {name:?}: {err:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn env_var_os(name: &str) -> OsString {
|
||||
match std::env::var_os(name) {
|
||||
Some(v) => v,
|
||||
None => panic!("failed to retrieve environment variable {name:?}"),
|
||||
}
|
||||
}
|
27
src/tools/run-make-support/src/external_deps/c_build.rs
Normal file
27
src/tools/run-make-support/src/external_deps/c_build.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::artifact_names::static_lib_name;
|
||||
use crate::external_deps::cc::cc;
|
||||
use crate::external_deps::llvm::llvm_ar;
|
||||
use crate::path_helpers::path;
|
||||
use crate::targets::is_msvc;
|
||||
|
||||
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
||||
#[track_caller]
|
||||
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
|
||||
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
|
||||
let src = format!("{lib_name}.c");
|
||||
let lib_path = static_lib_name(lib_name);
|
||||
if is_msvc() {
|
||||
cc().arg("-c").out_exe(&obj_file).input(src).run();
|
||||
} else {
|
||||
cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
|
||||
};
|
||||
let obj_file = if is_msvc() {
|
||||
PathBuf::from(format!("{lib_name}.obj"))
|
||||
} else {
|
||||
PathBuf::from(format!("{lib_name}.o"))
|
||||
};
|
||||
llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
|
||||
path(lib_path)
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::command::Command;
|
||||
use crate::{cygpath_windows, env_var, is_msvc, is_windows, uname};
|
||||
use crate::{env_var, is_msvc, is_windows, uname};
|
||||
|
||||
// FIXME(jieyouxu): can we get rid of the `cygpath` external dependency?
|
||||
use super::cygpath::get_windows_path;
|
||||
|
||||
/// Construct a new platform-specific C compiler invocation.
|
||||
///
|
||||
@ -20,7 +23,7 @@ pub struct Cc {
|
||||
cmd: Command,
|
||||
}
|
||||
|
||||
crate::impl_common_helpers!(Cc);
|
||||
crate::macros::impl_common_helpers!(Cc);
|
||||
|
||||
impl Cc {
|
||||
/// Construct a new platform-specific C compiler invocation.
|
||||
@ -72,10 +75,10 @@ impl Cc {
|
||||
|
||||
if is_msvc() {
|
||||
path.set_extension("exe");
|
||||
let fe_path = cygpath_windows(&path);
|
||||
let fe_path = get_windows_path(&path);
|
||||
path.set_extension("");
|
||||
path.set_extension("obj");
|
||||
let fo_path = cygpath_windows(path);
|
||||
let fo_path = get_windows_path(path);
|
||||
self.cmd.arg(format!("-Fe:{fe_path}"));
|
||||
self.cmd.arg(format!("-Fo:{fo_path}"));
|
||||
} else {
|
@ -16,7 +16,7 @@ pub struct Clang {
|
||||
cmd: Command,
|
||||
}
|
||||
|
||||
crate::impl_common_helpers!(Clang);
|
||||
crate::macros::impl_common_helpers!(Clang);
|
||||
|
||||
impl Clang {
|
||||
/// Construct a new `clang` invocation. `clang` is not always available for all targets.
|
35
src/tools/run-make-support/src/external_deps/cygpath.rs
Normal file
35
src/tools/run-make-support/src/external_deps/cygpath.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use std::panic;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::command::Command;
|
||||
use crate::util::handle_failed_output;
|
||||
|
||||
/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
|
||||
/// available on the platform!
|
||||
///
|
||||
/// # FIXME
|
||||
///
|
||||
/// FIXME(jieyouxu): we should consider not depending on `cygpath`.
|
||||
///
|
||||
/// > The cygpath program is a utility that converts Windows native filenames to Cygwin POSIX-style
|
||||
/// > pathnames and vice versa.
|
||||
/// >
|
||||
/// > [irrelevant entries omitted...]
|
||||
/// >
|
||||
/// > `-w, --windows print Windows form of NAMEs (C:\WINNT)`
|
||||
/// >
|
||||
/// > -- *from [cygpath documentation](https://cygwin.com/cygwin-ug-net/cygpath.html)*.
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn get_windows_path<P: AsRef<Path>>(path: P) -> String {
|
||||
let caller = panic::Location::caller();
|
||||
let mut cygpath = Command::new("cygpath");
|
||||
cygpath.arg("-w");
|
||||
cygpath.arg(path.as_ref());
|
||||
let output = cygpath.run();
|
||||
if !output.status().success() {
|
||||
handle_failed_output(&cygpath, output, caller.line());
|
||||
}
|
||||
// cygpath -w can attach a newline
|
||||
output.stdout_utf8().trim().to_string()
|
||||
}
|
14
src/tools/run-make-support/src/external_deps/htmldocck.rs
Normal file
14
src/tools/run-make-support/src/external_deps/htmldocck.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use crate::command::Command;
|
||||
use crate::source_root;
|
||||
|
||||
use super::python::python_command;
|
||||
|
||||
/// `htmldocck` is a python script which is used for rustdoc test suites, it is assumed to be
|
||||
/// available at `$SOURCE_ROOT/src/etc/htmldocck.py`.
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn htmldocck() -> Command {
|
||||
let mut python = python_command();
|
||||
python.arg(source_root().join("src/etc/htmldocck.py"));
|
||||
python
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::{env_var, Command};
|
||||
use crate::command::Command;
|
||||
use crate::env::env_var;
|
||||
|
||||
/// Construct a new `llvm-readobj` invocation with the `GNU` output style.
|
||||
/// This assumes that `llvm-readobj` is available at `$LLVM_BIN_DIR/llvm-readobj`.
|
||||
@ -70,11 +71,11 @@ pub struct LlvmAr {
|
||||
cmd: Command,
|
||||
}
|
||||
|
||||
crate::impl_common_helpers!(LlvmReadobj);
|
||||
crate::impl_common_helpers!(LlvmProfdata);
|
||||
crate::impl_common_helpers!(LlvmFilecheck);
|
||||
crate::impl_common_helpers!(LlvmObjdump);
|
||||
crate::impl_common_helpers!(LlvmAr);
|
||||
crate::macros::impl_common_helpers!(LlvmReadobj);
|
||||
crate::macros::impl_common_helpers!(LlvmProfdata);
|
||||
crate::macros::impl_common_helpers!(LlvmFilecheck);
|
||||
crate::macros::impl_common_helpers!(LlvmObjdump);
|
||||
crate::macros::impl_common_helpers!(LlvmAr);
|
||||
|
||||
/// Generate the path to the bin directory of LLVM.
|
||||
#[must_use]
|
14
src/tools/run-make-support/src/external_deps/mod.rs
Normal file
14
src/tools/run-make-support/src/external_deps/mod.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//! This module contains external tool dependencies that we assume are available in the environment,
|
||||
//! such as `cc` or `python`.
|
||||
|
||||
pub mod c_build;
|
||||
pub mod cc;
|
||||
pub mod clang;
|
||||
pub mod htmldocck;
|
||||
pub mod llvm;
|
||||
pub mod python;
|
||||
pub mod rustc;
|
||||
pub mod rustdoc;
|
||||
|
||||
// Library-internal external dependency.
|
||||
mod cygpath;
|
11
src/tools/run-make-support/src/external_deps/python.rs
Normal file
11
src/tools/run-make-support/src/external_deps/python.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate::command::Command;
|
||||
use crate::env::env_var;
|
||||
|
||||
/// Obtain path of python as provided by the `PYTHON` environment variable. It is up to the caller
|
||||
/// to document and check if the python version is compatible with its intended usage.
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn python_command() -> Command {
|
||||
let python_path = env_var("PYTHON");
|
||||
Command::new(python_path)
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
use command::Command;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{command, cwd, env_var, set_host_rpath};
|
||||
use crate::command::Command;
|
||||
use crate::env::env_var;
|
||||
use crate::path_helpers::cwd;
|
||||
use crate::util::set_host_rpath;
|
||||
|
||||
/// Construct a new `rustc` invocation. This will automatically set the library
|
||||
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
|
||||
@ -31,7 +33,7 @@ pub struct Rustc {
|
||||
cmd: Command,
|
||||
}
|
||||
|
||||
crate::impl_common_helpers!(Rustc);
|
||||
crate::macros::impl_common_helpers!(Rustc);
|
||||
|
||||
#[track_caller]
|
||||
fn setup_common() -> Command {
|
@ -2,7 +2,8 @@ use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::command::Command;
|
||||
use crate::{env_var, env_var_os, set_host_rpath};
|
||||
use crate::env::{env_var, env_var_os};
|
||||
use crate::util::set_host_rpath;
|
||||
|
||||
/// Construct a plain `rustdoc` invocation with no flags set.
|
||||
#[track_caller]
|
||||
@ -22,7 +23,7 @@ pub struct Rustdoc {
|
||||
cmd: Command,
|
||||
}
|
||||
|
||||
crate::impl_common_helpers!(Rustdoc);
|
||||
crate::macros::impl_common_helpers!(Rustdoc);
|
||||
|
||||
#[track_caller]
|
||||
fn setup_common() -> Command {
|
@ -1,17 +1,82 @@
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
// FIXME(jieyouxu): modify create_symlink to panic on windows.
|
||||
|
||||
/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
|
||||
#[cfg(target_family = "windows")]
|
||||
pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
|
||||
if link.as_ref().exists() {
|
||||
std::fs::remove_dir(link.as_ref()).unwrap();
|
||||
}
|
||||
std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
|
||||
"failed to create symlink {:?} for {:?}",
|
||||
link.as_ref().display(),
|
||||
original.as_ref().display(),
|
||||
));
|
||||
}
|
||||
|
||||
/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
|
||||
#[cfg(target_family = "unix")]
|
||||
pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
|
||||
if link.as_ref().exists() {
|
||||
std::fs::remove_dir(link.as_ref()).unwrap();
|
||||
}
|
||||
std::os::unix::fs::symlink(original.as_ref(), link.as_ref()).expect(&format!(
|
||||
"failed to create symlink {:?} for {:?}",
|
||||
link.as_ref().display(),
|
||||
original.as_ref().display(),
|
||||
));
|
||||
}
|
||||
|
||||
/// Copy a directory into another.
|
||||
pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
||||
fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
let dst = dst.as_ref();
|
||||
if !dst.is_dir() {
|
||||
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_inner(entry.path(), dst.join(entry.file_name()))?;
|
||||
} else {
|
||||
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if let Err(e) = copy_dir_all_inner(&src, &dst) {
|
||||
// Trying to give more context about what exactly caused the failure
|
||||
panic!(
|
||||
"failed to copy `{}` to `{}`: {:?}",
|
||||
src.as_ref().display(),
|
||||
dst.as_ref().display(),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper for reading entries in a given directory.
|
||||
pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F) {
|
||||
for entry in read_dir(dir) {
|
||||
callback(&entry.unwrap().path());
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn remove_file<P: AsRef<Path>>(path: P) {
|
||||
fs::remove_file(path.as_ref())
|
||||
std::fs::remove_file(path.as_ref())
|
||||
.expect(&format!("the file in path \"{}\" could not be removed", path.as_ref().display()));
|
||||
}
|
||||
|
||||
/// A wrapper around [`std::fs::copy`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
|
||||
fs::copy(from.as_ref(), to.as_ref()).expect(&format!(
|
||||
std::fs::copy(from.as_ref(), to.as_ref()).expect(&format!(
|
||||
"the file \"{}\" could not be copied over to \"{}\"",
|
||||
from.as_ref().display(),
|
||||
to.as_ref().display(),
|
||||
@ -21,21 +86,21 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
|
||||
/// A wrapper around [`std::fs::File::create`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn create_file<P: AsRef<Path>>(path: P) {
|
||||
fs::File::create(path.as_ref())
|
||||
std::fs::File::create(path.as_ref())
|
||||
.expect(&format!("the file in path \"{}\" could not be created", path.as_ref().display()));
|
||||
}
|
||||
|
||||
/// A wrapper around [`std::fs::read`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn read<P: AsRef<Path>>(path: P) -> Vec<u8> {
|
||||
fs::read(path.as_ref())
|
||||
std::fs::read(path.as_ref())
|
||||
.expect(&format!("the file in path \"{}\" could not be read", path.as_ref().display()))
|
||||
}
|
||||
|
||||
/// A wrapper around [`std::fs::read_to_string`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn read_to_string<P: AsRef<Path>>(path: P) -> String {
|
||||
fs::read_to_string(path.as_ref()).expect(&format!(
|
||||
std::fs::read_to_string(path.as_ref()).expect(&format!(
|
||||
"the file in path \"{}\" could not be read into a String",
|
||||
path.as_ref().display()
|
||||
))
|
||||
@ -43,15 +108,15 @@ pub fn read_to_string<P: AsRef<Path>>(path: P) -> String {
|
||||
|
||||
/// A wrapper around [`std::fs::read_dir`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn read_dir<P: AsRef<Path>>(path: P) -> fs::ReadDir {
|
||||
fs::read_dir(path.as_ref())
|
||||
pub fn read_dir<P: AsRef<Path>>(path: P) -> std::fs::ReadDir {
|
||||
std::fs::read_dir(path.as_ref())
|
||||
.expect(&format!("the directory in path \"{}\" could not be read", path.as_ref().display()))
|
||||
}
|
||||
|
||||
/// A wrapper around [`std::fs::write`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) {
|
||||
fs::write(path.as_ref(), contents.as_ref()).expect(&format!(
|
||||
std::fs::write(path.as_ref(), contents.as_ref()).expect(&format!(
|
||||
"the file in path \"{}\" could not be written to",
|
||||
path.as_ref().display()
|
||||
));
|
||||
@ -60,7 +125,7 @@ pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) {
|
||||
/// A wrapper around [`std::fs::remove_dir_all`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn remove_dir_all<P: AsRef<Path>>(path: P) {
|
||||
fs::remove_dir_all(path.as_ref()).expect(&format!(
|
||||
std::fs::remove_dir_all(path.as_ref()).expect(&format!(
|
||||
"the directory in path \"{}\" could not be removed alongside all its contents",
|
||||
path.as_ref().display(),
|
||||
));
|
||||
@ -69,7 +134,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) {
|
||||
/// A wrapper around [`std::fs::create_dir`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn create_dir<P: AsRef<Path>>(path: P) {
|
||||
fs::create_dir(path.as_ref()).expect(&format!(
|
||||
std::fs::create_dir(path.as_ref()).expect(&format!(
|
||||
"the directory in path \"{}\" could not be created",
|
||||
path.as_ref().display()
|
||||
));
|
||||
@ -78,7 +143,7 @@ pub fn create_dir<P: AsRef<Path>>(path: P) {
|
||||
/// A wrapper around [`std::fs::create_dir_all`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn create_dir_all<P: AsRef<Path>>(path: P) {
|
||||
fs::create_dir_all(path.as_ref()).expect(&format!(
|
||||
std::fs::create_dir_all(path.as_ref()).expect(&format!(
|
||||
"the directory (and all its parents) in path \"{}\" could not be created",
|
||||
path.as_ref().display()
|
||||
));
|
||||
@ -86,8 +151,8 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) {
|
||||
|
||||
/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn metadata<P: AsRef<Path>>(path: P) -> fs::Metadata {
|
||||
fs::metadata(path.as_ref()).expect(&format!(
|
||||
pub fn metadata<P: AsRef<Path>>(path: P) -> std::fs::Metadata {
|
||||
std::fs::metadata(path.as_ref()).expect(&format!(
|
||||
"the file's metadata in path \"{}\" could not be read",
|
||||
path.as_ref().display()
|
||||
))
|
||||
@ -96,7 +161,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> fs::Metadata {
|
||||
/// A wrapper around [`std::fs::rename`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
|
||||
fs::rename(from.as_ref(), to.as_ref()).expect(&format!(
|
||||
std::fs::rename(from.as_ref(), to.as_ref()).expect(&format!(
|
||||
"the file \"{}\" could not be moved over to \"{}\"",
|
||||
from.as_ref().display(),
|
||||
to.as_ref().display(),
|
||||
@ -105,8 +170,8 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
|
||||
|
||||
/// A wrapper around [`std::fs::set_permissions`] which includes the file path in the panic message.
|
||||
#[track_caller]
|
||||
pub fn set_permissions<P: AsRef<Path>>(path: P, perm: fs::Permissions) {
|
||||
fs::set_permissions(path.as_ref(), perm).expect(&format!(
|
||||
pub fn set_permissions<P: AsRef<Path>>(path: P, perm: std::fs::Permissions) {
|
||||
std::fs::set_permissions(path.as_ref(), perm).expect(&format!(
|
||||
"the file's permissions in path \"{}\" could not be changed",
|
||||
path.as_ref().display()
|
||||
));
|
@ -3,651 +3,84 @@
|
||||
//! notably is built via cargo: this means that if your test wants some non-trivial utility, such
|
||||
//! as `object` or `wasmparser`, they can be re-exported and be made available through this library.
|
||||
|
||||
pub mod cc;
|
||||
pub mod clang;
|
||||
mod command;
|
||||
mod macros;
|
||||
mod util;
|
||||
|
||||
pub mod artifact_names;
|
||||
pub mod assertion_helpers;
|
||||
pub mod diff;
|
||||
pub mod fs_wrapper;
|
||||
pub mod llvm;
|
||||
pub mod env;
|
||||
pub mod external_deps;
|
||||
pub mod path_helpers;
|
||||
pub mod run;
|
||||
pub mod rustc;
|
||||
pub mod rustdoc;
|
||||
pub mod scoped_run;
|
||||
pub mod string;
|
||||
pub mod targets;
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::panic;
|
||||
use std::path::{Path, PathBuf};
|
||||
mod fs;
|
||||
|
||||
/// [`std::fs`] wrappers and assorted filesystem-related helpers. Public to tests as `rfs` to not be
|
||||
/// confused with [`std::fs`].
|
||||
pub mod rfs {
|
||||
pub use crate::fs::*;
|
||||
}
|
||||
|
||||
// Re-exports of third-party library crates.
|
||||
pub use bstr;
|
||||
pub use gimli;
|
||||
pub use object;
|
||||
pub use regex;
|
||||
pub use wasmparser;
|
||||
|
||||
// Re-exports of external dependencies.
|
||||
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
|
||||
|
||||
// These rely on external dependencies.
|
||||
pub use c_build::build_native_static_lib;
|
||||
pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
|
||||
pub use clang::{clang, Clang};
|
||||
pub use diff::{diff, Diff};
|
||||
pub use htmldocck::htmldocck;
|
||||
pub use llvm::{
|
||||
llvm_ar, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmFilecheck,
|
||||
LlvmObjdump, LlvmProfdata, LlvmReadobj,
|
||||
};
|
||||
pub use run::{cmd, run, run_fail, run_with_args};
|
||||
pub use python::python_command;
|
||||
pub use rustc::{aux_build, bare_rustc, rustc, Rustc};
|
||||
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
|
||||
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn env_var(name: &str) -> String {
|
||||
match env::var(name) {
|
||||
Ok(v) => v,
|
||||
Err(err) => panic!("failed to retrieve environment variable {name:?}: {err:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn env_var_os(name: &str) -> OsString {
|
||||
match env::var_os(name) {
|
||||
Some(v) => v,
|
||||
None => panic!("failed to retrieve environment variable {name:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// `TARGET`
|
||||
#[must_use]
|
||||
pub fn target() -> String {
|
||||
env_var("TARGET")
|
||||
}
|
||||
|
||||
/// Check if target is windows-like.
|
||||
#[must_use]
|
||||
pub fn is_windows() -> bool {
|
||||
target().contains("windows")
|
||||
}
|
||||
|
||||
/// Check if target uses msvc.
|
||||
#[must_use]
|
||||
pub fn is_msvc() -> bool {
|
||||
target().contains("msvc")
|
||||
}
|
||||
|
||||
/// Check if target uses macOS.
|
||||
#[must_use]
|
||||
pub fn is_darwin() -> bool {
|
||||
target().contains("darwin")
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn python_command() -> Command {
|
||||
let python_path = env_var("PYTHON");
|
||||
Command::new(python_path)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn htmldocck() -> Command {
|
||||
let mut python = python_command();
|
||||
python.arg(source_root().join("src/etc/htmldocck.py"));
|
||||
python
|
||||
}
|
||||
|
||||
/// Returns the path for a local test file.
|
||||
pub fn path<P: AsRef<Path>>(p: P) -> PathBuf {
|
||||
cwd().join(p.as_ref())
|
||||
}
|
||||
|
||||
/// Path to the root rust-lang/rust source checkout.
|
||||
#[must_use]
|
||||
pub fn source_root() -> PathBuf {
|
||||
env_var("SOURCE_ROOT").into()
|
||||
}
|
||||
|
||||
/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
|
||||
#[cfg(target_family = "windows")]
|
||||
pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
|
||||
if link.as_ref().exists() {
|
||||
std::fs::remove_dir(link.as_ref()).unwrap();
|
||||
}
|
||||
use std::os::windows::fs;
|
||||
fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
|
||||
"failed to create symlink {:?} for {:?}",
|
||||
link.as_ref().display(),
|
||||
original.as_ref().display(),
|
||||
));
|
||||
}
|
||||
|
||||
/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
|
||||
#[cfg(target_family = "unix")]
|
||||
pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
|
||||
if link.as_ref().exists() {
|
||||
std::fs::remove_dir(link.as_ref()).unwrap();
|
||||
}
|
||||
use std::os::unix::fs;
|
||||
fs::symlink(original.as_ref(), link.as_ref()).expect(&format!(
|
||||
"failed to create symlink {:?} for {:?}",
|
||||
link.as_ref().display(),
|
||||
original.as_ref().display(),
|
||||
));
|
||||
}
|
||||
|
||||
/// Construct the static library name based on the platform.
|
||||
#[must_use]
|
||||
pub fn static_lib_name(name: &str) -> String {
|
||||
// See tools.mk (irrelevant lines omitted):
|
||||
//
|
||||
// ```makefile
|
||||
// ifeq ($(UNAME),Darwin)
|
||||
// STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
// else
|
||||
// ifdef IS_WINDOWS
|
||||
// ifdef IS_MSVC
|
||||
// STATICLIB = $(TMPDIR)/$(1).lib
|
||||
// else
|
||||
// STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
// endif
|
||||
// else
|
||||
// STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
// endif
|
||||
// endif
|
||||
// ```
|
||||
assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
|
||||
|
||||
if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
|
||||
}
|
||||
|
||||
/// Construct the dynamic library name based on the platform.
|
||||
#[must_use]
|
||||
pub fn dynamic_lib_name(name: &str) -> String {
|
||||
// See tools.mk (irrelevant lines omitted):
|
||||
//
|
||||
// ```makefile
|
||||
// ifeq ($(UNAME),Darwin)
|
||||
// DYLIB = $(TMPDIR)/lib$(1).dylib
|
||||
// else
|
||||
// ifdef IS_WINDOWS
|
||||
// DYLIB = $(TMPDIR)/$(1).dll
|
||||
// else
|
||||
// DYLIB = $(TMPDIR)/lib$(1).so
|
||||
// endif
|
||||
// endif
|
||||
// ```
|
||||
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
|
||||
|
||||
let extension = dynamic_lib_extension();
|
||||
if is_darwin() {
|
||||
format!("lib{name}.{extension}")
|
||||
} else if is_windows() {
|
||||
format!("{name}.{extension}")
|
||||
} else {
|
||||
format!("lib{name}.{extension}")
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn dynamic_lib_extension() -> &'static str {
|
||||
if is_darwin() {
|
||||
"dylib"
|
||||
} else if is_windows() {
|
||||
"dll"
|
||||
} else {
|
||||
"so"
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate the name a rust library (rlib) would have.
|
||||
#[must_use]
|
||||
pub fn rust_lib_name(name: &str) -> String {
|
||||
format!("lib{name}.rlib")
|
||||
}
|
||||
|
||||
/// Construct the binary name based on platform.
|
||||
#[must_use]
|
||||
pub fn bin_name(name: &str) -> String {
|
||||
if is_windows() { format!("{name}.exe") } else { name.to_string() }
|
||||
}
|
||||
|
||||
/// Return the current working directory.
|
||||
#[must_use]
|
||||
pub fn cwd() -> PathBuf {
|
||||
env::current_dir().unwrap()
|
||||
}
|
||||
|
||||
// FIXME(Oneirical): This will no longer be required after compiletest receives the ability
|
||||
// to manipulate read-only files. See https://github.com/rust-lang/rust/issues/126334
|
||||
/// Ensure that the path P is read-only while the test runs, and restore original permissions
|
||||
/// at the end so compiletest can clean up.
|
||||
/// This will panic on Windows if the path is a directory (as it would otherwise do nothing)
|
||||
#[track_caller]
|
||||
pub fn test_while_readonly<P: AsRef<Path>, F: FnOnce() + std::panic::UnwindSafe>(
|
||||
path: P,
|
||||
closure: F,
|
||||
) {
|
||||
let path = path.as_ref();
|
||||
if is_windows() && path.is_dir() {
|
||||
eprintln!("This helper function cannot be used on Windows to make directories readonly.");
|
||||
eprintln!(
|
||||
"See the official documentation:
|
||||
https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.set_readonly"
|
||||
);
|
||||
panic!("`test_while_readonly` on directory detected while on Windows.");
|
||||
}
|
||||
let metadata = fs_wrapper::metadata(&path);
|
||||
let original_perms = metadata.permissions();
|
||||
|
||||
let mut new_perms = original_perms.clone();
|
||||
new_perms.set_readonly(true);
|
||||
fs_wrapper::set_permissions(&path, new_perms);
|
||||
|
||||
let success = std::panic::catch_unwind(closure);
|
||||
|
||||
fs_wrapper::set_permissions(&path, original_perms);
|
||||
success.unwrap();
|
||||
}
|
||||
|
||||
/// Browse the directory `path` non-recursively and return all files which respect the parameters
|
||||
/// outlined by `closure`.
|
||||
#[track_caller]
|
||||
pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
|
||||
path: P,
|
||||
filter: F,
|
||||
) -> Vec<PathBuf> {
|
||||
let mut matching_files = Vec::new();
|
||||
for entry in fs_wrapper::read_dir(path) {
|
||||
let entry = entry.expect("failed to read directory entry.");
|
||||
let path = entry.path();
|
||||
|
||||
if path.is_file() && filter(&path) {
|
||||
matching_files.push(path);
|
||||
}
|
||||
}
|
||||
matching_files
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` starts with `prefix`.
|
||||
pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
|
||||
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` has the extension `extension`.
|
||||
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
|
||||
path.as_ref().extension().is_some_and(|ext| ext == extension)
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` does not contain `expected`.
|
||||
pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
|
||||
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
|
||||
}
|
||||
|
||||
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
||||
#[track_caller]
|
||||
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
|
||||
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
|
||||
let src = format!("{lib_name}.c");
|
||||
let lib_path = static_lib_name(lib_name);
|
||||
if is_msvc() {
|
||||
cc().arg("-c").out_exe(&obj_file).input(src).run();
|
||||
} else {
|
||||
cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
|
||||
};
|
||||
let obj_file = if is_msvc() {
|
||||
PathBuf::from(format!("{lib_name}.obj"))
|
||||
} else {
|
||||
PathBuf::from(format!("{lib_name}.o"))
|
||||
};
|
||||
llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
|
||||
path(lib_path)
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` is not in `expected`.
|
||||
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
|
||||
let expected = expected.as_ref();
|
||||
path.as_ref()
|
||||
.file_name()
|
||||
.is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` ends with `suffix`.
|
||||
pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
|
||||
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
|
||||
}
|
||||
|
||||
/// Gathers all files in the current working directory that have the extension `ext`, and counts
|
||||
/// the number of lines within that contain a match with the regex pattern `re`.
|
||||
pub fn count_regex_matches_in_files_with_extension(re: ®ex::Regex, ext: &str) -> usize {
|
||||
let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
|
||||
|
||||
let mut count = 0;
|
||||
for file in fetched_files {
|
||||
let content = fs_wrapper::read_to_string(file);
|
||||
count += content.lines().filter(|line| re.is_match(&line)).count();
|
||||
}
|
||||
|
||||
count
|
||||
}
|
||||
|
||||
/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
|
||||
/// available on the platform!
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn cygpath_windows<P: AsRef<Path>>(path: P) -> String {
|
||||
let caller = panic::Location::caller();
|
||||
let mut cygpath = Command::new("cygpath");
|
||||
cygpath.arg("-w");
|
||||
cygpath.arg(path.as_ref());
|
||||
let output = cygpath.run();
|
||||
if !output.status().success() {
|
||||
handle_failed_output(&cygpath, output, caller.line());
|
||||
}
|
||||
// cygpath -w can attach a newline
|
||||
output.stdout_utf8().trim().to_string()
|
||||
}
|
||||
|
||||
/// Run `uname`. This assumes that `uname` is available on the platform!
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn uname() -> String {
|
||||
let caller = panic::Location::caller();
|
||||
let mut uname = Command::new("uname");
|
||||
let output = uname.run();
|
||||
if !output.status().success() {
|
||||
handle_failed_output(&uname, output, caller.line());
|
||||
}
|
||||
output.stdout_utf8()
|
||||
}
|
||||
|
||||
fn handle_failed_output(cmd: &Command, output: CompletedProcess, caller_line_number: u32) -> ! {
|
||||
if output.status().success() {
|
||||
eprintln!("command unexpectedly succeeded at line {caller_line_number}");
|
||||
} else {
|
||||
eprintln!("command failed at line {caller_line_number}");
|
||||
}
|
||||
eprintln!("{cmd:?}");
|
||||
eprintln!("output status: `{}`", output.status());
|
||||
eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8());
|
||||
eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8());
|
||||
std::process::exit(1)
|
||||
}
|
||||
|
||||
/// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
|
||||
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(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());
|
||||
}
|
||||
env::join_paths(paths.iter()).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
/// Read the contents of a file that cannot simply be read by
|
||||
/// read_to_string, due to invalid utf8 data, then assert that it contains `expected`.
|
||||
#[track_caller]
|
||||
pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
||||
let buffer = fs_wrapper::read(path.as_ref());
|
||||
let expected = expected.as_ref();
|
||||
if !String::from_utf8_lossy(&buffer).contains(expected) {
|
||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
||||
eprintln!("=== SPECIFIED TEXT ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("specified text was not found in file");
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the contents of a file that cannot simply be read by
|
||||
/// read_to_string, due to invalid utf8 data, then assert that it does not contain `expected`.
|
||||
#[track_caller]
|
||||
pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
||||
let buffer = fs_wrapper::read(path.as_ref());
|
||||
let expected = expected.as_ref();
|
||||
if String::from_utf8_lossy(&buffer).contains(expected) {
|
||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
||||
eprintln!("=== SPECIFIED TEXT ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("specified text was unexpectedly found in file");
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy a directory into another.
|
||||
pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
||||
fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
let dst = dst.as_ref();
|
||||
if !dst.is_dir() {
|
||||
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_inner(entry.path(), dst.join(entry.file_name()))?;
|
||||
} else {
|
||||
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if let Err(e) = copy_dir_all_inner(&src, &dst) {
|
||||
// Trying to give more context about what exactly caused the failure
|
||||
panic!(
|
||||
"failed to copy `{}` to `{}`: {:?}",
|
||||
src.as_ref().display(),
|
||||
dst.as_ref().display(),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
|
||||
pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
|
||||
let dir2 = dir2.as_ref();
|
||||
read_dir(dir1, |entry_path| {
|
||||
let entry_name = entry_path.file_name().unwrap();
|
||||
if entry_path.is_dir() {
|
||||
recursive_diff(&entry_path, &dir2.join(entry_name));
|
||||
} else {
|
||||
let path2 = dir2.join(entry_name);
|
||||
let file1 = fs_wrapper::read(&entry_path);
|
||||
let file2 = fs_wrapper::read(&path2);
|
||||
|
||||
// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
|
||||
// Why not using String? Because there might be minified files or even potentially
|
||||
// binary ones, so that would display useless output.
|
||||
assert!(
|
||||
file1 == file2,
|
||||
"`{}` and `{}` have different content",
|
||||
entry_path.display(),
|
||||
path2.display(),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn read_dir<F: FnMut(&Path)>(dir: impl AsRef<Path>, mut callback: F) {
|
||||
for entry in fs_wrapper::read_dir(dir) {
|
||||
callback(&entry.unwrap().path());
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that `actual` is equal to `expected`. Panic otherwise.
|
||||
#[track_caller]
|
||||
pub fn assert_equals<S1: AsRef<str>, S2: AsRef<str>>(actual: S1, expected: S2) {
|
||||
let actual = actual.as_ref();
|
||||
let expected = expected.as_ref();
|
||||
if actual != expected {
|
||||
eprintln!("=== ACTUAL TEXT ===");
|
||||
eprintln!("{}", actual);
|
||||
eprintln!("=== EXPECTED ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("expected text was not found in actual text");
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that `haystack` contains `needle`. Panic otherwise.
|
||||
#[track_caller]
|
||||
pub fn assert_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
|
||||
let haystack = haystack.as_ref();
|
||||
let needle = needle.as_ref();
|
||||
if !haystack.contains(needle) {
|
||||
eprintln!("=== HAYSTACK ===");
|
||||
eprintln!("{}", haystack);
|
||||
eprintln!("=== NEEDLE ===");
|
||||
eprintln!("{}", needle);
|
||||
panic!("needle was not found in haystack");
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that `haystack` does not contain `needle`. Panic otherwise.
|
||||
#[track_caller]
|
||||
pub fn assert_not_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
|
||||
let haystack = haystack.as_ref();
|
||||
let needle = needle.as_ref();
|
||||
if haystack.contains(needle) {
|
||||
eprintln!("=== HAYSTACK ===");
|
||||
eprintln!("{}", haystack);
|
||||
eprintln!("=== NEEDLE ===");
|
||||
eprintln!("{}", needle);
|
||||
panic!("needle was unexpectedly found in haystack");
|
||||
}
|
||||
}
|
||||
|
||||
/// This function is designed for running commands in a temporary directory
|
||||
/// that is cleared after the function ends.
|
||||
/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
|
||||
///
|
||||
/// 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);
|
||||
/// [similar]: https://github.com/mitsuhiko/similar
|
||||
pub use diff::{diff, Diff};
|
||||
|
||||
env::set_current_dir(&tmpdir).unwrap();
|
||||
callback();
|
||||
env::set_current_dir(original_dir).unwrap();
|
||||
fs::remove_dir_all(tmpdir).unwrap();
|
||||
}
|
||||
/// Panic-on-fail [`std::env::var`] and [`std::env::var_os`] wrappers.
|
||||
pub use env::{env_var, env_var_os};
|
||||
|
||||
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
|
||||
/// containing a `cmd: Command` field. The provided helpers are:
|
||||
///
|
||||
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
|
||||
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
|
||||
/// new specific helper methods over relying on these generic argument providers.
|
||||
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
|
||||
/// methods of the same name on [`Command`].
|
||||
/// 3. Output and execution: `run` and `run_fail` are provided. These are
|
||||
/// higher-level convenience methods which wait for the command to finish running and assert
|
||||
/// that the command successfully ran or failed as expected. They return
|
||||
/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
|
||||
/// process.
|
||||
///
|
||||
/// Example usage:
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
|
||||
///
|
||||
/// crate::impl_common_helpers!(CommandWrapper);
|
||||
///
|
||||
/// impl CommandWrapper {
|
||||
/// // ... additional specific helper methods
|
||||
/// }
|
||||
/// ```
|
||||
macro_rules! impl_common_helpers {
|
||||
($wrapper: ident) => {
|
||||
impl $wrapper {
|
||||
/// Specify an environment variable.
|
||||
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
|
||||
where
|
||||
K: AsRef<::std::ffi::OsStr>,
|
||||
V: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.env(key, value);
|
||||
self
|
||||
}
|
||||
/// Convenience helpers for running binaries and other commands.
|
||||
pub use run::{cmd, run, run_fail, run_with_args};
|
||||
|
||||
/// Remove an environmental variable.
|
||||
pub fn env_remove<K>(&mut self, key: K) -> &mut Self
|
||||
where
|
||||
K: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.env_remove(key);
|
||||
self
|
||||
}
|
||||
/// Helpers for checking target information.
|
||||
pub use targets::{is_darwin, is_msvc, is_windows, target, uname};
|
||||
|
||||
/// Generic command argument provider. Prefer specific helper methods if possible.
|
||||
/// Note that for some executables, arguments might be platform specific. For C/C++
|
||||
/// compilers, arguments might be platform *and* compiler specific.
|
||||
pub fn arg<S>(&mut self, arg: S) -> &mut Self
|
||||
where
|
||||
S: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.arg(arg);
|
||||
self
|
||||
}
|
||||
/// Helpers for building names of output artifacts that are potentially target-specific.
|
||||
pub use artifact_names::{
|
||||
bin_name, dynamic_lib_extension, dynamic_lib_name, rust_lib_name, static_lib_name,
|
||||
};
|
||||
|
||||
/// Generic command arguments provider. Prefer specific helper methods if possible.
|
||||
/// Note that for some executables, arguments might be platform specific. For C/C++
|
||||
/// compilers, arguments might be platform *and* compiler specific.
|
||||
pub fn args<V, S>(&mut self, args: V) -> &mut Self
|
||||
where
|
||||
V: AsRef<[S]>,
|
||||
S: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.args(args.as_ref());
|
||||
self
|
||||
}
|
||||
/// Path-related helpers.
|
||||
pub use path_helpers::{
|
||||
cwd, filename_not_in_denylist, has_extension, has_prefix, has_suffix, not_contains, path,
|
||||
shallow_find_files, source_root,
|
||||
};
|
||||
|
||||
/// Inspect what the underlying [`Command`] is up to the
|
||||
/// current construction.
|
||||
pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
|
||||
where
|
||||
I: FnOnce(&::std::process::Command),
|
||||
{
|
||||
self.cmd.inspect(inspector);
|
||||
self
|
||||
}
|
||||
/// Helpers for scoped test execution where certain properties are attempted to be maintained.
|
||||
pub use scoped_run::{run_in_tmpdir, test_while_readonly};
|
||||
|
||||
/// Run the constructed command and assert that it is successfully run.
|
||||
#[track_caller]
|
||||
pub fn run(&mut self) -> crate::command::CompletedProcess {
|
||||
self.cmd.run()
|
||||
}
|
||||
pub use assertion_helpers::{
|
||||
assert_contains, assert_dirs_are_equal, assert_equals, assert_not_contains,
|
||||
};
|
||||
|
||||
/// Run the constructed command and assert that it does not successfully run.
|
||||
#[track_caller]
|
||||
pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
|
||||
self.cmd.run_fail()
|
||||
}
|
||||
|
||||
/// Run the command but do not check its exit status.
|
||||
/// Only use if you explicitly don't care about the exit status.
|
||||
/// Prefer to use [`Self::run`] and [`Self::run_fail`]
|
||||
/// whenever possible.
|
||||
#[track_caller]
|
||||
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
|
||||
self.cmd.run_unchecked()
|
||||
}
|
||||
|
||||
/// Set the path where the command will be run.
|
||||
pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
|
||||
self.cmd.current_dir(path);
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
use crate::command::{Command, CompletedProcess};
|
||||
pub(crate) use impl_common_helpers;
|
||||
pub use string::{
|
||||
count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains,
|
||||
};
|
||||
|
113
src/tools/run-make-support/src/macros.rs
Normal file
113
src/tools/run-make-support/src/macros.rs
Normal file
@ -0,0 +1,113 @@
|
||||
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
|
||||
/// containing a `cmd: Command` field. The provided helpers are:
|
||||
///
|
||||
/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
|
||||
/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
|
||||
/// new specific helper methods over relying on these generic argument providers.
|
||||
/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
|
||||
/// methods of the same name on [`Command`].
|
||||
/// 3. Output and execution: `run` and `run_fail` are provided. These are higher-level convenience
|
||||
/// methods which wait for the command to finish running and assert that the command successfully
|
||||
/// ran or failed as expected. They return [`CompletedProcess`], which can be used to assert the
|
||||
/// stdout/stderr/exit code of the executed process.
|
||||
///
|
||||
/// Example usage:
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
|
||||
///
|
||||
/// crate::macros::impl_common_helpers!(CommandWrapper);
|
||||
///
|
||||
/// impl CommandWrapper {
|
||||
/// // ... additional specific helper methods
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`Command`]: crate::command::Command
|
||||
/// [`CompletedProcess`]: crate::command::CompletedProcess
|
||||
macro_rules! impl_common_helpers {
|
||||
($wrapper: ident) => {
|
||||
impl $wrapper {
|
||||
/// Specify an environment variable.
|
||||
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
|
||||
where
|
||||
K: AsRef<::std::ffi::OsStr>,
|
||||
V: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.env(key, value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Remove an environmental variable.
|
||||
pub fn env_remove<K>(&mut self, key: K) -> &mut Self
|
||||
where
|
||||
K: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.env_remove(key);
|
||||
self
|
||||
}
|
||||
|
||||
/// Generic command argument provider. Prefer specific helper methods if possible.
|
||||
/// Note that for some executables, arguments might be platform specific. For C/C++
|
||||
/// compilers, arguments might be platform *and* compiler specific.
|
||||
pub fn arg<S>(&mut self, arg: S) -> &mut Self
|
||||
where
|
||||
S: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.arg(arg);
|
||||
self
|
||||
}
|
||||
|
||||
/// Generic command arguments provider. Prefer specific helper methods if possible.
|
||||
/// Note that for some executables, arguments might be platform specific. For C/C++
|
||||
/// compilers, arguments might be platform *and* compiler specific.
|
||||
pub fn args<V, S>(&mut self, args: V) -> &mut Self
|
||||
where
|
||||
V: AsRef<[S]>,
|
||||
S: AsRef<::std::ffi::OsStr>,
|
||||
{
|
||||
self.cmd.args(args.as_ref());
|
||||
self
|
||||
}
|
||||
|
||||
/// Inspect what the underlying [`Command`] is up to the
|
||||
/// current construction.
|
||||
pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
|
||||
where
|
||||
I: FnOnce(&::std::process::Command),
|
||||
{
|
||||
self.cmd.inspect(inspector);
|
||||
self
|
||||
}
|
||||
|
||||
/// Run the constructed command and assert that it is successfully run.
|
||||
#[track_caller]
|
||||
pub fn run(&mut self) -> crate::command::CompletedProcess {
|
||||
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 {
|
||||
self.cmd.run_fail()
|
||||
}
|
||||
|
||||
/// Run the command but do not check its exit status.
|
||||
/// Only use if you explicitly don't care about the exit status.
|
||||
/// Prefer to use [`Self::run`] and [`Self::run_fail`]
|
||||
/// whenever possible.
|
||||
#[track_caller]
|
||||
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
|
||||
self.cmd.run_unchecked()
|
||||
}
|
||||
|
||||
/// Set the path where the command will be run.
|
||||
pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
|
||||
self.cmd.current_dir(path);
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use impl_common_helpers;
|
80
src/tools/run-make-support/src/path_helpers.rs
Normal file
80
src/tools/run-make-support/src/path_helpers.rs
Normal file
@ -0,0 +1,80 @@
|
||||
//! Collection of path-related helpers.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::env::env_var;
|
||||
|
||||
/// Return the current working directory.
|
||||
///
|
||||
/// This forwards to [`std::env::current_dir`], please see its docs regarding platform-specific
|
||||
/// behavior.
|
||||
#[must_use]
|
||||
pub fn cwd() -> PathBuf {
|
||||
std::env::current_dir().unwrap()
|
||||
}
|
||||
|
||||
/// Construct a `PathBuf` relative to the current working directory by joining `cwd()` with the
|
||||
/// relative path. This is mostly a convenience helper so the test writer does not need to write
|
||||
/// `PathBuf::from(path_like_string)`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let p = path("support_file.txt");
|
||||
/// ```
|
||||
pub fn path<P: AsRef<Path>>(p: P) -> PathBuf {
|
||||
cwd().join(p.as_ref())
|
||||
}
|
||||
|
||||
/// Path to the root `rust-lang/rust` source checkout.
|
||||
#[must_use]
|
||||
pub fn source_root() -> PathBuf {
|
||||
env_var("SOURCE_ROOT").into()
|
||||
}
|
||||
|
||||
/// Browse the directory `path` non-recursively and return all files which respect the parameters
|
||||
/// outlined by `closure`.
|
||||
#[track_caller]
|
||||
pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
|
||||
path: P,
|
||||
filter: F,
|
||||
) -> Vec<PathBuf> {
|
||||
let mut matching_files = Vec::new();
|
||||
for entry in std::fs::read_dir(path).unwrap() {
|
||||
let entry = entry.expect("failed to read directory entry.");
|
||||
let path = entry.path();
|
||||
|
||||
if path.is_file() && filter(&path) {
|
||||
matching_files.push(path);
|
||||
}
|
||||
}
|
||||
matching_files
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` does not contain `expected`.
|
||||
pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
|
||||
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` is not in `expected`.
|
||||
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
|
||||
let expected = expected.as_ref();
|
||||
path.as_ref()
|
||||
.file_name()
|
||||
.is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` starts with `prefix`.
|
||||
pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
|
||||
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` has the extension `extension`.
|
||||
pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
|
||||
path.as_ref().extension().is_some_and(|ext| ext == extension)
|
||||
}
|
||||
|
||||
/// Returns true if the filename at `path` ends with `suffix`.
|
||||
pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
|
||||
path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
|
||||
}
|
@ -4,9 +4,8 @@ use std::panic;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::command::{Command, CompletedProcess};
|
||||
use crate::{cwd, env_var, is_windows, set_host_rpath};
|
||||
|
||||
use super::handle_failed_output;
|
||||
use crate::util::{handle_failed_output, set_host_rpath};
|
||||
use crate::{cwd, env_var, is_windows};
|
||||
|
||||
#[track_caller]
|
||||
fn run_common(name: &str, args: Option<&[&str]>) -> Command {
|
||||
|
69
src/tools/run-make-support/src/scoped_run.rs
Normal file
69
src/tools/run-make-support/src/scoped_run.rs
Normal file
@ -0,0 +1,69 @@
|
||||
//! Collection of helpers that try to maintain certain properties while running a test closure.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::fs;
|
||||
use crate::path_helpers::cwd;
|
||||
use crate::targets::is_windows;
|
||||
|
||||
/// Ensure that the path P is read-only while the test runs, and restore original permissions at the
|
||||
/// end so compiletest can clean up. This will panic on Windows if the path is a directory (as it
|
||||
/// would otherwise do nothing)
|
||||
///
|
||||
/// # Pitfalls
|
||||
///
|
||||
/// - Some CI runners are ran as root which may bypass read-only permission restrictions. Unclear
|
||||
/// exactly when such scenarios occur.
|
||||
///
|
||||
/// # FIXME
|
||||
///
|
||||
/// FIXME(Oneirical): This will no longer be required after compiletest receives the ability to
|
||||
/// manipulate read-only files. See <https://github.com/rust-lang/rust/issues/126334>.
|
||||
#[track_caller]
|
||||
pub fn test_while_readonly<P, F>(path: P, closure: F)
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
F: FnOnce() + std::panic::UnwindSafe,
|
||||
{
|
||||
let path = path.as_ref();
|
||||
if is_windows() && path.is_dir() {
|
||||
eprintln!("This helper function cannot be used on Windows to make directories readonly.");
|
||||
eprintln!(
|
||||
"See the official documentation:
|
||||
https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.set_readonly"
|
||||
);
|
||||
panic!("`test_while_readonly` on directory detected while on Windows.");
|
||||
}
|
||||
let metadata = fs::metadata(&path);
|
||||
let original_perms = metadata.permissions();
|
||||
|
||||
let mut new_perms = original_perms.clone();
|
||||
new_perms.set_readonly(true);
|
||||
fs::set_permissions(&path, new_perms);
|
||||
|
||||
let success = std::panic::catch_unwind(closure);
|
||||
|
||||
fs::set_permissions(&path, original_perms);
|
||||
success.unwrap();
|
||||
}
|
||||
|
||||
/// 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");
|
||||
fs::copy_dir_all(".", &tmpdir);
|
||||
|
||||
std::env::set_current_dir(&tmpdir).unwrap();
|
||||
callback();
|
||||
std::env::set_current_dir(original_dir).unwrap();
|
||||
fs::remove_dir_all(tmpdir);
|
||||
}
|
50
src/tools/run-make-support/src/string.rs
Normal file
50
src/tools/run-make-support/src/string.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::fs;
|
||||
use crate::path_helpers::{cwd, has_extension, shallow_find_files};
|
||||
|
||||
/// Gathers all files in the current working directory that have the extension `ext`, and counts
|
||||
/// the number of lines within that contain a match with the regex pattern `re`.
|
||||
pub fn count_regex_matches_in_files_with_extension(re: ®ex::Regex, ext: &str) -> usize {
|
||||
let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
|
||||
|
||||
let mut count = 0;
|
||||
for file in fetched_files {
|
||||
let content = fs::read_to_string(file);
|
||||
count += content.lines().filter(|line| re.is_match(&line)).count();
|
||||
}
|
||||
|
||||
count
|
||||
}
|
||||
|
||||
/// Read the contents of a file that cannot simply be read by
|
||||
/// [`read_to_string`][crate::fs::read_to_string], due to invalid UTF-8 data, then assert
|
||||
/// that it contains `expected`.
|
||||
#[track_caller]
|
||||
pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
||||
let buffer = fs::read(path.as_ref());
|
||||
let expected = expected.as_ref();
|
||||
if !String::from_utf8_lossy(&buffer).contains(expected) {
|
||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
||||
eprintln!("=== SPECIFIED TEXT ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("specified text was not found in file");
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the contents of a file that cannot simply be read by
|
||||
/// [`read_to_string`][crate::fs::read_to_string], due to invalid UTF-8 data, then assert
|
||||
/// that it does not contain `expected`.
|
||||
#[track_caller]
|
||||
pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
|
||||
let buffer = fs::read(path.as_ref());
|
||||
let expected = expected.as_ref();
|
||||
if String::from_utf8_lossy(&buffer).contains(expected) {
|
||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||
eprintln!("{}", String::from_utf8_lossy(&buffer));
|
||||
eprintln!("=== SPECIFIED TEXT ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("specified text was unexpectedly found in file");
|
||||
}
|
||||
}
|
42
src/tools/run-make-support/src/targets.rs
Normal file
42
src/tools/run-make-support/src/targets.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use std::panic;
|
||||
|
||||
use crate::command::Command;
|
||||
use crate::env_var;
|
||||
use crate::util::handle_failed_output;
|
||||
|
||||
/// `TARGET`
|
||||
#[must_use]
|
||||
pub fn target() -> String {
|
||||
env_var("TARGET")
|
||||
}
|
||||
|
||||
/// Check if target is windows-like.
|
||||
#[must_use]
|
||||
pub fn is_windows() -> bool {
|
||||
target().contains("windows")
|
||||
}
|
||||
|
||||
/// Check if target uses msvc.
|
||||
#[must_use]
|
||||
pub fn is_msvc() -> bool {
|
||||
target().contains("msvc")
|
||||
}
|
||||
|
||||
/// Check if target uses macOS.
|
||||
#[must_use]
|
||||
pub fn is_darwin() -> bool {
|
||||
target().contains("darwin")
|
||||
}
|
||||
|
||||
/// Run `uname`. This assumes that `uname` is available on the platform!
|
||||
#[track_caller]
|
||||
#[must_use]
|
||||
pub fn uname() -> String {
|
||||
let caller = panic::Location::caller();
|
||||
let mut uname = Command::new("uname");
|
||||
let output = uname.run();
|
||||
if !output.status().success() {
|
||||
handle_failed_output(&uname, output, caller.line());
|
||||
}
|
||||
output.stdout_utf8()
|
||||
}
|
39
src/tools/run-make-support/src/util.rs
Normal file
39
src/tools/run-make-support/src/util.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::command::{Command, CompletedProcess};
|
||||
use crate::env::env_var;
|
||||
use crate::path_helpers::cwd;
|
||||
|
||||
/// If a given [`Command`] failed (as indicated by its [`CompletedProcess`]), verbose print the
|
||||
/// executed command, failure location, output status and stdout/stderr, and abort the process with
|
||||
/// exit code `1`.
|
||||
pub(crate) fn handle_failed_output(
|
||||
cmd: &Command,
|
||||
output: CompletedProcess,
|
||||
caller_line_number: u32,
|
||||
) -> ! {
|
||||
if output.status().success() {
|
||||
eprintln!("command unexpectedly succeeded at line {caller_line_number}");
|
||||
} else {
|
||||
eprintln!("command failed at line {caller_line_number}");
|
||||
}
|
||||
eprintln!("{cmd:?}");
|
||||
eprintln!("output status: `{}`", output.status());
|
||||
eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8());
|
||||
eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8());
|
||||
std::process::exit(1)
|
||||
}
|
||||
|
||||
/// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
|
||||
pub(crate) 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(cwd());
|
||||
paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
|
||||
for p in std::env::split_paths(&env_var(&ld_lib_path_envvar)) {
|
||||
paths.push(p.to_path_buf());
|
||||
}
|
||||
std::env::join_paths(paths.iter()).unwrap()
|
||||
});
|
||||
}
|
@ -5,14 +5,14 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use run_make_support::{aux_build, fs_wrapper, rustc, source_root};
|
||||
use run_make_support::{aux_build, rfs, rustc, source_root};
|
||||
|
||||
fn main() {
|
||||
aux_build().input("stable.rs").emit("metadata").run();
|
||||
|
||||
let output =
|
||||
rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run();
|
||||
let version = fs_wrapper::read_to_string(source_root().join("src/version"));
|
||||
let version = rfs::read_to_string(source_root().join("src/version"));
|
||||
let expected_string = format!("stable since {}", version.trim());
|
||||
output.assert_stderr_contains(expected_string);
|
||||
}
|
||||
|
@ -3,9 +3,7 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{
|
||||
cc, cwd, dynamic_lib_extension, fs_wrapper, is_msvc, read_dir, run, run_fail, rustc,
|
||||
};
|
||||
use run_make_support::{cc, cwd, dynamic_lib_extension, is_msvc, rfs, run, run_fail, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").run();
|
||||
@ -21,14 +19,14 @@ fn main() {
|
||||
run("bar");
|
||||
|
||||
let expected_extension = dynamic_lib_extension();
|
||||
read_dir(cwd(), |path| {
|
||||
rfs::read_dir_entries(cwd(), |path| {
|
||||
if path.is_file()
|
||||
&& path.extension().is_some_and(|ext| ext == expected_extension)
|
||||
&& path.file_name().and_then(|name| name.to_str()).is_some_and(|name| {
|
||||
name.ends_with(".so") || name.ends_with(".dll") || name.ends_with(".dylib")
|
||||
})
|
||||
{
|
||||
fs_wrapper::remove_file(path);
|
||||
rfs::remove_file(path);
|
||||
}
|
||||
});
|
||||
run_fail("bar");
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::fs_wrapper::remove_file;
|
||||
use run_make_support::rfs::remove_file;
|
||||
use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name};
|
||||
use std::fs;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{cc, cwd, dynamic_lib_name, fs_wrapper, is_msvc, run, rustc};
|
||||
use run_make_support::{cc, cwd, dynamic_lib_name, is_msvc, rfs, run, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("bar.rs").run();
|
||||
@ -23,7 +23,7 @@ fn main() {
|
||||
}
|
||||
|
||||
run("foo");
|
||||
fs_wrapper::remove_file(dynamic_lib_name("foo"));
|
||||
rfs::remove_file(dynamic_lib_name("foo"));
|
||||
|
||||
rustc().input("foo.rs").arg("-Clto").run();
|
||||
run("foo");
|
||||
|
@ -10,8 +10,9 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use run_make_support::llvm_readobj;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::rustc;
|
||||
use run_make_support::{cwd, env_var, read_dir, run_in_tmpdir};
|
||||
use run_make_support::{cwd, env_var, run_in_tmpdir};
|
||||
|
||||
fn main() {
|
||||
let target = env_var("TARGET");
|
||||
@ -33,7 +34,7 @@ fn main() {
|
||||
|
||||
// Check all object files (including temporary outputs) have a `.comment`
|
||||
// section with the expected content.
|
||||
read_dir(cwd(), |f| {
|
||||
rfs::read_dir_entries(cwd(), |f| {
|
||||
if !f.extension().is_some_and(|ext| ext == "o") {
|
||||
return;
|
||||
}
|
||||
|
@ -14,12 +14,12 @@
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use run_make_support::fs_wrapper::{read, read_dir};
|
||||
use run_make_support::object::read::archive::ArchiveFile;
|
||||
use run_make_support::object::read::Object;
|
||||
use run_make_support::object::ObjectSection;
|
||||
use run_make_support::object::ObjectSymbol;
|
||||
use run_make_support::object::RelocationTarget;
|
||||
use run_make_support::rfs::{read, read_dir};
|
||||
use run_make_support::{cmd, env_var, object};
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
|
@ -9,16 +9,16 @@
|
||||
//@ ignore-wasm64
|
||||
// Reason: a C compiler is required for build_native_static_lib
|
||||
|
||||
use run_make_support::{build_native_static_lib, fs_wrapper, rustc, static_lib_name};
|
||||
use run_make_support::{build_native_static_lib, rfs, rustc, static_lib_name};
|
||||
|
||||
fn main() {
|
||||
build_native_static_lib("native");
|
||||
let lib_native = static_lib_name("native");
|
||||
fs_wrapper::create_dir_all("crate");
|
||||
fs_wrapper::create_dir_all("native");
|
||||
fs_wrapper::rename(&lib_native, format!("native/{}", &lib_native));
|
||||
rfs::create_dir_all("crate");
|
||||
rfs::create_dir_all("native");
|
||||
rfs::rename(&lib_native, format!("native/{}", &lib_native));
|
||||
rustc().input("a.rs").run();
|
||||
fs_wrapper::rename("liba.rlib", "crate/liba.rlib");
|
||||
rfs::rename("liba.rlib", "crate/liba.rlib");
|
||||
rustc().input("b.rs").specific_library_search_path("native", "crate").run_fail();
|
||||
rustc().input("b.rs").specific_library_search_path("dependency", "crate").run_fail();
|
||||
rustc().input("b.rs").specific_library_search_path("crate", "crate").run();
|
||||
@ -35,8 +35,8 @@ fn main() {
|
||||
rustc().input("d.rs").specific_library_search_path("all", "native").run();
|
||||
|
||||
// Deduplication tests.
|
||||
fs_wrapper::create_dir_all("e1");
|
||||
fs_wrapper::create_dir_all("e2");
|
||||
rfs::create_dir_all("e1");
|
||||
rfs::create_dir_all("e2");
|
||||
|
||||
rustc().input("e.rs").output("e1/libe.rlib").run();
|
||||
rustc().input("e.rs").output("e2/libe.rlib").run();
|
||||
|
@ -1,11 +1,11 @@
|
||||
// Tests that const prop lints interrupting codegen don't leave `.o` files around.
|
||||
|
||||
use run_make_support::{cwd, fs_wrapper, rustc};
|
||||
use run_make_support::{cwd, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("input.rs").run_fail().assert_exit_code(1);
|
||||
|
||||
for entry in fs_wrapper::read_dir(cwd()) {
|
||||
for entry in rfs::read_dir(cwd()) {
|
||||
let entry = entry.unwrap();
|
||||
let path = entry.path();
|
||||
|
||||
|
@ -4,15 +4,15 @@
|
||||
// and the compiler flags, and checks that the flag is favoured each time.
|
||||
// See https://github.com/rust-lang/rust/pull/15518
|
||||
|
||||
use run_make_support::{bin_name, fs_wrapper, rustc};
|
||||
use run_make_support::{bin_name, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").run();
|
||||
fs_wrapper::remove_file(bin_name("foo"));
|
||||
rfs::remove_file(bin_name("foo"));
|
||||
rustc().input("foo.rs").crate_name("bar").run();
|
||||
fs_wrapper::remove_file(bin_name("bar"));
|
||||
rfs::remove_file(bin_name("bar"));
|
||||
rustc().input("foo1.rs").run();
|
||||
fs_wrapper::remove_file(bin_name("foo"));
|
||||
rfs::remove_file(bin_name("foo"));
|
||||
rustc().input("foo1.rs").output(bin_name("bar1")).run();
|
||||
fs_wrapper::remove_file(bin_name("bar1"));
|
||||
rfs::remove_file(bin_name("bar1"));
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Check that valid binaries are persisted by running them, regardless of whether the
|
||||
// --run or --no-run option is used.
|
||||
|
||||
use run_make_support::fs_wrapper::{create_dir, remove_dir_all};
|
||||
use run_make_support::rfs::{create_dir, remove_dir_all};
|
||||
use run_make_support::{run, rustc, rustdoc};
|
||||
use std::path::Path;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Tests behavior of rustdoc `--runtool`.
|
||||
|
||||
use run_make_support::fs_wrapper::{create_dir, remove_dir_all};
|
||||
use run_make_support::rfs::{create_dir, remove_dir_all};
|
||||
use run_make_support::{rustc, rustdoc};
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// a specific expected string.
|
||||
// See https://github.com/rust-lang/rust/pull/105481
|
||||
|
||||
use run_make_support::{cwd, fs_wrapper, rustc};
|
||||
use run_make_support::{cwd, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc()
|
||||
@ -13,5 +13,5 @@ fn main() {
|
||||
.arg(format!("-Zdump-mono-stats={}", cwd().display()))
|
||||
.arg("-Zdump-mono-stats-format=json")
|
||||
.run();
|
||||
assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains(r#""name":"bar""#));
|
||||
assert!(rfs::read_to_string("foo.mono_items.json").contains(r#""name":"bar""#));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
use run_make_support::{dynamic_lib_name, fs_wrapper, run, run_fail, rustc};
|
||||
use run_make_support::{dynamic_lib_name, rfs, run, run_fail, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("m1.rs").arg("-Cprefer-dynamic").run();
|
||||
@ -16,8 +16,8 @@ fn main() {
|
||||
rustc().input("m3.rs").arg("-Cprefer-dynamic").run();
|
||||
rustc().input("m4.rs").run();
|
||||
run("m4");
|
||||
fs_wrapper::remove_file(dynamic_lib_name("m1"));
|
||||
fs_wrapper::remove_file(dynamic_lib_name("m2"));
|
||||
fs_wrapper::remove_file(dynamic_lib_name("m3"));
|
||||
rfs::remove_file(dynamic_lib_name("m1"));
|
||||
rfs::remove_file(dynamic_lib_name("m2"));
|
||||
rfs::remove_file(dynamic_lib_name("m3"));
|
||||
run_fail("m4");
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) {
|
||||
let out_file = out_dir.join(out_file);
|
||||
@ -11,7 +11,7 @@ fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) {
|
||||
fn main() {
|
||||
let out_dir = Path::new("emit");
|
||||
|
||||
fs_wrapper::create_dir(&out_dir);
|
||||
rfs::create_dir(&out_dir);
|
||||
|
||||
emit_and_check(&out_dir, "libfoo.s", "asm");
|
||||
emit_and_check(&out_dir, "libfoo.bc", "llvm-bc");
|
||||
|
@ -6,13 +6,13 @@
|
||||
// adding a new output type (in this test, metadata).
|
||||
// See https://github.com/rust-lang/rust/issues/86044
|
||||
|
||||
use run_make_support::{diff, fs_wrapper, rustc};
|
||||
use run_make_support::{diff, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_dir("emit");
|
||||
fs_wrapper::create_dir("emit/a");
|
||||
fs_wrapper::create_dir("emit/b");
|
||||
fs_wrapper::create_dir("emit/c");
|
||||
rfs::create_dir("emit");
|
||||
rfs::create_dir("emit/a");
|
||||
rfs::create_dir("emit/b");
|
||||
rfs::create_dir("emit/c");
|
||||
// The default output name.
|
||||
rustc().emit("link").input("foo.rs").run();
|
||||
// The output is named with the output flag.
|
||||
|
@ -8,21 +8,21 @@
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
use run_make_support::{dynamic_lib_name, fs_wrapper, run, run_fail, rust_lib_name, rustc};
|
||||
use run_make_support::{dynamic_lib_name, rfs, run, run_fail, rust_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("bar.rs").crate_type("rlib").crate_type("dylib").arg("-Cprefer-dynamic").run();
|
||||
|
||||
// By default, the rlib has priority over the dylib.
|
||||
rustc().input("foo.rs").arg("--extern").arg("bar").run();
|
||||
fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
run("foo");
|
||||
fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
rfs::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
|
||||
rustc().input("foo.rs").extern_("bar", rust_lib_name("bar")).arg("--extern").arg("bar").run();
|
||||
fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
run("foo");
|
||||
fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
rfs::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
|
||||
// The first explicit usage of extern overrides the second pathless --extern bar.
|
||||
rustc()
|
||||
@ -31,13 +31,13 @@ fn main() {
|
||||
.arg("--extern")
|
||||
.arg("bar")
|
||||
.run();
|
||||
fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
run_fail("foo");
|
||||
fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
rfs::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
|
||||
// With prefer-dynamic, execution fails as it refuses to use the rlib.
|
||||
rustc().input("foo.rs").arg("--extern").arg("bar").arg("-Cprefer-dynamic").run();
|
||||
fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
|
||||
run_fail("foo");
|
||||
fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
rfs::rename("bar.tmp", dynamic_lib_name("bar"));
|
||||
}
|
||||
|
@ -6,9 +6,7 @@
|
||||
// are named as expected.
|
||||
// See https://github.com/rust-lang/rust/pull/15686
|
||||
|
||||
use run_make_support::{
|
||||
bin_name, cwd, fs_wrapper, has_prefix, has_suffix, rustc, shallow_find_files,
|
||||
};
|
||||
use run_make_support::{bin_name, cwd, has_prefix, has_suffix, rfs, rustc, shallow_find_files};
|
||||
|
||||
fn main() {
|
||||
rustc().extra_filename("bar").input("foo.rs").arg("-Csave-temps").run();
|
||||
@ -16,6 +14,6 @@ fn main() {
|
||||
has_prefix(path, "foobar.foo") && has_suffix(path, "0.rcgu.o")
|
||||
});
|
||||
let object_file = object_files.get(0).unwrap();
|
||||
fs_wrapper::remove_file(object_file);
|
||||
fs_wrapper::remove_file(bin_name("foobar"));
|
||||
rfs::remove_file(object_file);
|
||||
rfs::remove_file(bin_name("foobar"));
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
// If we used `rustc` the additional '-L rmake_out' option would allow rustc to
|
||||
// actually find the crate.
|
||||
|
||||
use run_make_support::{bare_rustc, fs_wrapper, rust_lib_name, rustc};
|
||||
use run_make_support::{bare_rustc, rfs, rust_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().crate_name("a").crate_type("rlib").input("a.rs").arg("--verbose").run();
|
||||
|
@ -24,11 +24,11 @@
|
||||
// Reason: `set_readonly` has no effect on directories
|
||||
// and does not prevent modification.
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, test_while_readonly};
|
||||
use run_make_support::{rfs, rustc, test_while_readonly};
|
||||
|
||||
fn main() {
|
||||
// Create an inaccessible directory.
|
||||
fs_wrapper::create_dir("inaccessible");
|
||||
rfs::create_dir("inaccessible");
|
||||
test_while_readonly("inaccessible", || {
|
||||
// Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one,
|
||||
// so that it can't create `tmp`.
|
||||
|
@ -13,14 +13,14 @@
|
||||
//@ ignore-nvptx64-nvidia-cuda
|
||||
// FIXME: can't find crate for `std`
|
||||
|
||||
use run_make_support::fs_wrapper as fs;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
fs::create_dir("src");
|
||||
fs::create_dir("incr");
|
||||
fs::copy("a.rs", "src/main.rs");
|
||||
rfs::create_dir("src");
|
||||
rfs::create_dir("incr");
|
||||
rfs::copy("a.rs", "src/main.rs");
|
||||
rustc().incremental("incr").input("src/main.rs").run();
|
||||
fs::copy("b.rs", "src/main.rs");
|
||||
rfs::copy("b.rs", "src/main.rs");
|
||||
rustc().incremental("incr").input("src/main.rs").run();
|
||||
}
|
||||
|
@ -14,14 +14,14 @@
|
||||
//@ ignore-nvptx64-nvidia-cuda
|
||||
// FIXME: can't find crate for 'std'
|
||||
|
||||
use run_make_support::{fs_wrapper, rust_lib_name, rustc};
|
||||
use run_make_support::{rfs, rust_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_dir("incr");
|
||||
fs_wrapper::create_dir("src");
|
||||
fs_wrapper::create_dir("src/mydir");
|
||||
fs_wrapper::copy("main.rs", "src/main.rs");
|
||||
rfs::create_dir("incr");
|
||||
rfs::create_dir("src");
|
||||
rfs::create_dir("src/mydir");
|
||||
rfs::copy("main.rs", "src/main.rs");
|
||||
rustc().input("src/main.rs").incremental("incr").arg("--test").run();
|
||||
fs_wrapper::rename("src/main.rs", "src/mydir/main.rs");
|
||||
rfs::rename("src/main.rs", "src/mydir/main.rs");
|
||||
rustc().input("src/mydir/main.rs").incremental("incr").arg("--test").run();
|
||||
}
|
||||
|
@ -2,14 +2,14 @@
|
||||
// (in this case, foo.py and foo.natvis) are picked up when compiling incrementally.
|
||||
// See https://github.com/rust-lang/rust/pull/111641
|
||||
|
||||
use run_make_support::{fs_wrapper, invalid_utf8_contains, invalid_utf8_not_contains, rustc};
|
||||
use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rfs, rustc};
|
||||
use std::io::Read;
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_file("foo.py");
|
||||
fs_wrapper::write("foo.py", "GDB script v1");
|
||||
fs_wrapper::create_file("foo.natvis");
|
||||
fs_wrapper::write("foo.natvis", "Natvis v1");
|
||||
rfs::create_file("foo.py");
|
||||
rfs::write("foo.py", "GDB script v1");
|
||||
rfs::create_file("foo.natvis");
|
||||
rfs::write("foo.natvis", "Natvis v1");
|
||||
rustc()
|
||||
.input("foo.rs")
|
||||
.crate_type("rlib")
|
||||
@ -22,9 +22,9 @@ fn main() {
|
||||
invalid_utf8_contains("libfoo.rmeta", "Natvis v1");
|
||||
|
||||
// Change only the GDB script and check that the change has been picked up
|
||||
fs_wrapper::remove_file("foo.py");
|
||||
fs_wrapper::create_file("foo.py");
|
||||
fs_wrapper::write("foo.py", "GDB script v2");
|
||||
rfs::remove_file("foo.py");
|
||||
rfs::create_file("foo.py");
|
||||
rfs::write("foo.py", "GDB script v2");
|
||||
rustc()
|
||||
.input("foo.rs")
|
||||
.crate_type("rlib")
|
||||
@ -38,9 +38,9 @@ fn main() {
|
||||
invalid_utf8_contains("libfoo.rmeta", "Natvis v1");
|
||||
|
||||
// Now change the Natvis version and check that the change has been picked up
|
||||
fs_wrapper::remove_file("foo.natvis");
|
||||
fs_wrapper::create_file("foo.natvis");
|
||||
fs_wrapper::write("foo.natvis", "Natvis v2");
|
||||
rfs::remove_file("foo.natvis");
|
||||
rfs::create_file("foo.natvis");
|
||||
rfs::write("foo.natvis", "Natvis v2");
|
||||
rustc()
|
||||
.input("foo.rs")
|
||||
.crate_type("rlib")
|
||||
|
@ -4,10 +4,10 @@
|
||||
// the ensuing compilation failure is not an ICE.
|
||||
// See https://github.com/rust-lang/rust/pull/85698
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_file("session");
|
||||
rfs::create_file("session");
|
||||
// rustc should fail to create the session directory here.
|
||||
let out = rustc().input("foo.rs").crate_type("rlib").incremental("session").run_fail();
|
||||
out.assert_stderr_contains("could not create incremental compilation crate directory");
|
||||
|
@ -1,6 +1,6 @@
|
||||
use run_make_support::fs_wrapper::read_to_string;
|
||||
use run_make_support::regex::Regex;
|
||||
use run_make_support::{read_dir, rustc};
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::rustc;
|
||||
|
||||
use std::ffi::OsStr;
|
||||
|
||||
@ -8,9 +8,9 @@ fn main() {
|
||||
rustc().input("foo.rs").emit("llvm-ir").codegen_units(2).run();
|
||||
let re = Regex::new(r"\bcall\b").unwrap();
|
||||
let mut nb_ll = 0;
|
||||
read_dir(".", |path| {
|
||||
rfs::read_dir_entries(".", |path| {
|
||||
if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("ll")) {
|
||||
assert!(!re.is_match(&read_to_string(path)));
|
||||
assert!(!re.is_match(&rfs::read_to_string(path)));
|
||||
nb_ll += 1;
|
||||
}
|
||||
});
|
||||
|
@ -8,13 +8,13 @@
|
||||
//@ ignore-windows
|
||||
// Reason: Because of Windows exception handling, the code is not necessarily any shorter.
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().opt().emit("asm").input("exit-ret.rs").run();
|
||||
rustc().opt().emit("asm").input("exit-unreachable.rs").run();
|
||||
assert!(
|
||||
fs_wrapper::read_to_string("exit-unreachable.s").lines().count()
|
||||
< fs_wrapper::read_to_string("exit-ret.s").lines().count()
|
||||
rfs::read_to_string("exit-unreachable.s").lines().count()
|
||||
< rfs::read_to_string("exit-ret.s").lines().count()
|
||||
);
|
||||
}
|
||||
|
@ -4,11 +4,11 @@
|
||||
// one appearing in stderr in this scenario.
|
||||
// See https://github.com/rust-lang/rust/pull/12645
|
||||
|
||||
use run_make_support::fs_wrapper::create_file;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::{llvm_ar, rustc};
|
||||
|
||||
fn main() {
|
||||
create_file("lib.rmeta");
|
||||
rfs::create_file("lib.rmeta");
|
||||
llvm_ar().obj_to_ar().output_input("libfoo-ffffffff-1.0.rlib", "lib.rmeta").run();
|
||||
rustc().input("foo.rs").run_fail().assert_stderr_contains("found invalid metadata");
|
||||
}
|
||||
|
@ -4,10 +4,10 @@
|
||||
// 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, fs_wrapper, rustc};
|
||||
use run_make_support::{dynamic_lib_name, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_file(dynamic_lib_name("foo"));
|
||||
rfs::create_file(dynamic_lib_name("foo"));
|
||||
rustc()
|
||||
.crate_type("lib")
|
||||
.extern_("foo", dynamic_lib_name("foo"))
|
||||
|
@ -4,10 +4,10 @@
|
||||
// an internal compiler error (ICE).
|
||||
// See https://github.com/rust-lang/rust/pull/28673
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, static_lib_name};
|
||||
use run_make_support::{rfs, rustc, static_lib_name};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_file(static_lib_name("foo"));
|
||||
rfs::create_file(static_lib_name("foo"));
|
||||
rustc()
|
||||
.arg("-")
|
||||
.crate_type("rlib")
|
||||
|
@ -3,7 +3,7 @@
|
||||
#[cfg(unix)]
|
||||
extern crate libc;
|
||||
|
||||
use run_make_support::{aux_build, fs_wrapper};
|
||||
use run_make_support::{aux_build, rfs};
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
@ -20,7 +20,7 @@ fn main() {
|
||||
}
|
||||
|
||||
fn verify(path: &Path) {
|
||||
let perm = fs_wrapper::metadata(path).permissions();
|
||||
let perm = rfs::metadata(path).permissions();
|
||||
|
||||
assert!(!perm.readonly());
|
||||
|
||||
|
@ -6,12 +6,12 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::fs_wrapper;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").run();
|
||||
rustc().arg("-Zls=root").input("foo").run();
|
||||
fs_wrapper::create_file("bar");
|
||||
rfs::create_file("bar");
|
||||
rustc().arg("-Zls=root").input("bar").run();
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::fs_wrapper;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::{run, rust_lib_name, rustc, test_while_readonly};
|
||||
|
||||
fn main() {
|
||||
|
@ -4,12 +4,12 @@
|
||||
// what should be done to fix the issue.
|
||||
// See https://github.com/rust-lang/rust/issues/13266
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_dir("a1");
|
||||
fs_wrapper::create_dir("a2");
|
||||
fs_wrapper::create_dir("a3");
|
||||
rfs::create_dir("a1");
|
||||
rfs::create_dir("a2");
|
||||
rfs::create_dir("a3");
|
||||
rustc().crate_type("rlib").out_dir("a1").input("crateA1.rs").run();
|
||||
rustc().crate_type("rlib").library_search_path("a1").input("crateB.rs").run();
|
||||
rustc().crate_type("rlib").out_dir("a2").input("crateA2.rs").run();
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{dynamic_lib_name, fs_wrapper, rustc};
|
||||
use run_make_support::{dynamic_lib_name, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("rlib.rs").crate_type("rlib").crate_type("dylib").run();
|
||||
@ -16,6 +16,6 @@ fn main() {
|
||||
|
||||
// librlib's dynamic version needs to be removed here to prevent prog.rs from fetching
|
||||
// the wrong one.
|
||||
fs_wrapper::remove_file(dynamic_lib_name("rlib"));
|
||||
rfs::remove_file(dynamic_lib_name("rlib"));
|
||||
rustc().input("prog.rs").run_fail();
|
||||
}
|
||||
|
@ -17,20 +17,20 @@
|
||||
//@ ignore-nvptx64-nvidia-cuda
|
||||
// FIXME: can't find crate for 'std'
|
||||
|
||||
use run_make_support::{fs_wrapper, rust_lib_name, rustc};
|
||||
use run_make_support::{rfs, rust_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_dir("incr");
|
||||
fs_wrapper::create_dir("first_src");
|
||||
fs_wrapper::create_dir("output");
|
||||
fs_wrapper::rename("my_lib.rs", "first_src/my_lib.rs");
|
||||
fs_wrapper::rename("main.rs", "first_src/main.rs");
|
||||
rfs::create_dir("incr");
|
||||
rfs::create_dir("first_src");
|
||||
rfs::create_dir("output");
|
||||
rfs::rename("my_lib.rs", "first_src/my_lib.rs");
|
||||
rfs::rename("main.rs", "first_src/main.rs");
|
||||
// Build from "first_src"
|
||||
std::env::set_current_dir("first_src").unwrap();
|
||||
rustc().input("my_lib.rs").incremental("incr").crate_type("lib").run();
|
||||
rustc().input("main.rs").incremental("incr").extern_("my_lib", rust_lib_name("my_lib")).run();
|
||||
std::env::set_current_dir("..").unwrap();
|
||||
fs_wrapper::rename("first_src", "second_src");
|
||||
rfs::rename("first_src", "second_src");
|
||||
std::env::set_current_dir("second_src").unwrap();
|
||||
// Build from "second_src" - the output and incremental directory remain identical
|
||||
rustc().input("my_lib.rs").incremental("incr").crate_type("lib").run();
|
||||
|
@ -1,4 +1,4 @@
|
||||
use run_make_support::fs_wrapper;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
@ -7,6 +7,6 @@ fn main() {
|
||||
#[cfg(windows)]
|
||||
let non_unicode: std::ffi::OsString = std::os::windows::ffi::OsStringExt::from_wide(&[0xD800]);
|
||||
let output = rustc().input("non_unicode_env.rs").env("NON_UNICODE_VAR", non_unicode).run_fail();
|
||||
let expected = fs_wrapper::read_to_string("non_unicode_env.stderr");
|
||||
let expected = rfs::read_to_string("non_unicode_env.stderr");
|
||||
output.assert_stderr_equals(expected);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
#[cfg(unix)]
|
||||
@ -17,8 +17,8 @@ fn main() {
|
||||
}
|
||||
let incr_dir = "incr-dir";
|
||||
rustc().input("foo.rs").incremental(&incr_dir).run();
|
||||
for crate_dir in fs_wrapper::read_dir(&incr_dir) {
|
||||
fs_wrapper::create_dir(crate_dir.unwrap().path().join(&non_unicode));
|
||||
for crate_dir in rfs::read_dir(&incr_dir) {
|
||||
rfs::create_dir(crate_dir.unwrap().path().join(&non_unicode));
|
||||
}
|
||||
rustc().input("foo.rs").incremental(&incr_dir).run();
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{
|
||||
cwd, dynamic_lib_name, fs_wrapper, has_extension, rust_lib_name, rustc, shallow_find_files,
|
||||
cwd, dynamic_lib_name, has_extension, rfs, rust_lib_name, rustc, shallow_find_files,
|
||||
};
|
||||
use std::path::Path;
|
||||
|
||||
@ -15,7 +15,7 @@ fn main() {
|
||||
assert!(Path::new(&dynamic_lib_name("test")).exists());
|
||||
assert!(Path::new(&rust_lib_name("test")).exists());
|
||||
|
||||
fs_wrapper::remove_file(rust_lib_name("test"));
|
||||
rfs::remove_file(rust_lib_name("test"));
|
||||
rustc().crate_type("dylib").input("test.rs").run();
|
||||
assert!(shallow_find_files(cwd(), |path| { has_extension(path, "rlib") }).is_empty());
|
||||
}
|
||||
|
@ -4,10 +4,10 @@
|
||||
// potentially-confusing linker error.
|
||||
// See https://github.com/rust-lang/rust/pull/47203
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_dir("foo");
|
||||
rfs::create_dir("foo");
|
||||
rustc().input("foo.rs").output("foo").run_fail().assert_stderr_contains(
|
||||
r#"the generated executable for the input file "foo.rs" conflicts with the existing directory "foo""#,
|
||||
);
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::copy("foo.rs", "foo");
|
||||
rfs::copy("foo.rs", "foo");
|
||||
rustc().input("foo").output("foo").run_fail().assert_stderr_contains(
|
||||
r#"the input file "foo" would be overwritten by the generated executable"#,
|
||||
);
|
||||
fs_wrapper::copy("bar.rs", "bar.rlib");
|
||||
rfs::copy("bar.rs", "bar.rlib");
|
||||
rustc().input("bar.rlib").output("bar.rlib").run_fail().assert_stderr_contains(
|
||||
r#"the input file "bar.rlib" would be overwritten by the generated executable"#,
|
||||
);
|
||||
|
@ -5,7 +5,7 @@
|
||||
// See https://github.com/rust-lang/rust/pull/12020
|
||||
|
||||
use run_make_support::{
|
||||
bin_name, dynamic_lib_name, filename_not_in_denylist, fs_wrapper, rust_lib_name, rustc,
|
||||
bin_name, dynamic_lib_name, filename_not_in_denylist, rfs, rust_lib_name, rustc,
|
||||
shallow_find_files, static_lib_name,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
@ -20,10 +20,10 @@ fn assert_expected_output_files(expectations: Expectations, rustc_invocation: im
|
||||
let Expectations { expected_files: must_exist, allowed_files: can_exist, test_dir: dir } =
|
||||
expectations;
|
||||
|
||||
fs_wrapper::create_dir(&dir);
|
||||
rfs::create_dir(&dir);
|
||||
rustc_invocation();
|
||||
for file in must_exist {
|
||||
fs_wrapper::remove_file(PathBuf::from(&dir).join(&file));
|
||||
rfs::remove_file(PathBuf::from(&dir).join(&file));
|
||||
}
|
||||
let actual_output_files =
|
||||
shallow_find_files(dir, |path| filename_not_in_denylist(path, &can_exist));
|
||||
@ -526,17 +526,14 @@ fn main() {
|
||||
test_dir: "rlib-emits".to_string(),
|
||||
},
|
||||
|| {
|
||||
fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc");
|
||||
rfs::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc");
|
||||
rustc()
|
||||
.input("foo.rs")
|
||||
.emit("llvm-bc,link")
|
||||
.crate_type("rlib")
|
||||
.out_dir("rlib-emits")
|
||||
.run();
|
||||
assert_eq!(
|
||||
fs_wrapper::read("rlib-emits/foo.bc"),
|
||||
fs_wrapper::read("rlib-emits/bar.bc")
|
||||
);
|
||||
assert_eq!(rfs::read("rlib-emits/foo.bc"), rfs::read("rlib-emits/bar.bc"));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -5,12 +5,12 @@
|
||||
// conflicts. This test uses this flag and checks for successful compilation.
|
||||
// See https://github.com/rust-lang/rust/pull/83846
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
use std::sync::{Arc, Barrier};
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_file("lib.rs");
|
||||
rfs::create_file("lib.rs");
|
||||
let barrier = Arc::new(Barrier::new(2));
|
||||
let handle = {
|
||||
let barrier = Arc::clone(&barrier);
|
||||
|
@ -10,14 +10,14 @@
|
||||
//@ needs-profiler-support
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{fs_wrapper, llvm_filecheck, llvm_profdata, run_with_args, rustc};
|
||||
use run_make_support::{llvm_filecheck, llvm_profdata, rfs, run_with_args, rustc};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let path_prof_data_dir = Path::new("prof_data_dir");
|
||||
let path_merged_profdata = path_prof_data_dir.join("merged.profdata");
|
||||
rustc().input("opaque.rs").run();
|
||||
fs_wrapper::create_dir_all(&path_prof_data_dir);
|
||||
rfs::create_dir_all(&path_prof_data_dir);
|
||||
rustc()
|
||||
.input("interesting.rs")
|
||||
.profile_generate(&path_prof_data_dir)
|
||||
@ -34,8 +34,5 @@ fn main() {
|
||||
.codegen_units(1)
|
||||
.emit("llvm-ir")
|
||||
.run();
|
||||
llvm_filecheck()
|
||||
.patterns("filecheck-patterns.txt")
|
||||
.stdin(fs_wrapper::read("interesting.ll"))
|
||||
.run();
|
||||
llvm_filecheck().patterns("filecheck-patterns.txt").stdin(rfs::read("interesting.ll")).run();
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{
|
||||
cwd, fs_wrapper, has_extension, has_prefix, llvm_filecheck, llvm_profdata, run_with_args,
|
||||
rustc, shallow_find_files,
|
||||
cwd, has_extension, has_prefix, llvm_filecheck, llvm_profdata, rfs, run_with_args, rustc,
|
||||
shallow_find_files,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
@ -47,7 +47,7 @@ fn main() {
|
||||
// line with the function name before the line with the function attributes.
|
||||
// FileCheck only supports checking that something matches on the next line,
|
||||
// but not if something matches on the previous line.
|
||||
let ir = fs_wrapper::read_to_string("main.ll");
|
||||
let ir = rfs::read_to_string("main.ll");
|
||||
let lines: Vec<_> = ir.lines().rev().collect();
|
||||
let mut reversed_ir = lines.join("\n");
|
||||
reversed_ir.push('\n');
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{cwd, dynamic_lib_name, fs_wrapper, read_dir, run, run_fail, rustc};
|
||||
use run_make_support::{dynamic_lib_name, rfs, run, run_fail, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").arg("-Cprefer-dynamic").run();
|
||||
@ -8,7 +8,7 @@ fn main() {
|
||||
|
||||
run("foo");
|
||||
|
||||
fs_wrapper::remove_file(dynamic_lib_name("bar"));
|
||||
rfs::remove_file(dynamic_lib_name("bar"));
|
||||
// This time the command should fail.
|
||||
run_fail("foo");
|
||||
}
|
||||
|
@ -3,13 +3,13 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{dynamic_lib_name, fs_wrapper, path, run, rust_lib_name, rustc};
|
||||
use run_make_support::{dynamic_lib_name, path, rfs, run, rust_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").run();
|
||||
assert!(path(rust_lib_name("bar")).exists());
|
||||
rustc().input("foo.rs").run();
|
||||
fs_wrapper::remove_file(rust_lib_name("bar"));
|
||||
fs_wrapper::remove_file(dynamic_lib_name("bar"));
|
||||
rfs::remove_file(rust_lib_name("bar"));
|
||||
rfs::remove_file(dynamic_lib_name("bar"));
|
||||
run("foo");
|
||||
}
|
||||
|
@ -5,13 +5,13 @@
|
||||
// does not get an unexpected dep-info file.
|
||||
// See https://github.com/rust-lang/rust/issues/112898
|
||||
|
||||
use run_make_support::{fs_wrapper, invalid_utf8_contains, rustc};
|
||||
use run_make_support::{invalid_utf8_contains, rfs, rustc};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
rustc().emit("dep-info").arg("-Zunpretty=expanded").input("with-dep.rs").run();
|
||||
invalid_utf8_contains("with-dep.d", "with-dep.rs");
|
||||
fs_wrapper::remove_file("with-dep.d");
|
||||
rfs::remove_file("with-dep.d");
|
||||
rustc().emit("dep-info").arg("-Zunpretty=normal").input("with-dep.rs").run();
|
||||
assert!(!Path::new("with-dep.d").exists());
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use std::ffi::OsString;
|
||||
use std::iter::FromIterator;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
struct PrintCfg {
|
||||
target: &'static str,
|
||||
@ -96,7 +96,7 @@ fn check(PrintCfg { target, includes, disallow }: PrintCfg) {
|
||||
|
||||
rustc().target(target).arg(print_arg).run();
|
||||
|
||||
let output = fs_wrapper::read_to_string(&tmp_path);
|
||||
let output = rfs::read_to_string(&tmp_path);
|
||||
|
||||
check_(&output, includes, disallow);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, target};
|
||||
use run_make_support::{rfs, rustc, target};
|
||||
|
||||
struct Option<'a> {
|
||||
target: &'a str,
|
||||
@ -49,7 +49,7 @@ fn check(args: Option) {
|
||||
|
||||
rustc().target(args.target).arg(print_arg).run();
|
||||
|
||||
fs_wrapper::read_to_string(&tmp_path)
|
||||
rfs::read_to_string(&tmp_path)
|
||||
};
|
||||
|
||||
check_(&stdout, args.includes);
|
||||
|
@ -4,7 +4,7 @@
|
||||
// See https://github.com/rust-lang/rust/pull/85344
|
||||
|
||||
use run_make_support::bstr::ByteSlice;
|
||||
use run_make_support::{bstr, fs_wrapper, is_darwin, rustc};
|
||||
use run_make_support::{bstr, is_darwin, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
let mut out_simple = rustc();
|
||||
@ -60,12 +60,9 @@ fn main() {
|
||||
// helper functions.
|
||||
fn rmeta_contains(expected: &str) {
|
||||
// Normalize to account for path differences in Windows.
|
||||
if !bstr::BString::from(fs_wrapper::read("liblib.rmeta"))
|
||||
.replace(b"\\", b"/")
|
||||
.contains_str(expected)
|
||||
{
|
||||
if !bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) {
|
||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||
eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta")));
|
||||
eprintln!("{}", String::from_utf8_lossy(&rfs::read("liblib.rmeta")));
|
||||
eprintln!("=== SPECIFIED TEXT ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("specified text was not found in file");
|
||||
@ -74,12 +71,9 @@ fn rmeta_contains(expected: &str) {
|
||||
|
||||
fn rmeta_not_contains(expected: &str) {
|
||||
// Normalize to account for path differences in Windows.
|
||||
if bstr::BString::from(fs_wrapper::read("liblib.rmeta"))
|
||||
.replace(b"\\", b"/")
|
||||
.contains_str(expected)
|
||||
{
|
||||
if bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) {
|
||||
eprintln!("=== FILE CONTENTS (LOSSY) ===");
|
||||
eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta")));
|
||||
eprintln!("{}", String::from_utf8_lossy(&rfs::read("liblib.rmeta")));
|
||||
eprintln!("=== SPECIFIED TEXT ===");
|
||||
eprintln!("{}", expected);
|
||||
panic!("specified text was not found in file");
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian};
|
||||
use object::{Object, ObjectSection};
|
||||
use run_make_support::{fs_wrapper, gimli, object, rustc};
|
||||
use run_make_support::{gimli, object, rfs, rustc};
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
@ -19,7 +19,7 @@ fn main() {
|
||||
.join("DWARF")
|
||||
.join("repr128");
|
||||
let output =
|
||||
fs_wrapper::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output });
|
||||
rfs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output });
|
||||
let obj = object::File::parse(output.as_slice()).unwrap();
|
||||
let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big };
|
||||
let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{bin_name, fs_wrapper, rustc};
|
||||
use run_make_support::{bin_name, rfs, rustc};
|
||||
use std::path::Path;
|
||||
|
||||
fn compile(output_file: &str, emit: Option<&str>) {
|
||||
|
@ -5,12 +5,12 @@
|
||||
// the renamed library.
|
||||
// See https://github.com/rust-lang/rust/pull/49253
|
||||
|
||||
use run_make_support::fs_wrapper;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
rustc().extra_filename("-hash").input("foo.rs").run();
|
||||
rustc().input("bar.rs").run();
|
||||
fs_wrapper::rename("libfoo-hash.rlib", "libfoo-another-hash.rlib");
|
||||
rfs::rename("libfoo-hash.rlib", "libfoo-another-hash.rlib");
|
||||
rustc().input("baz.rs").run();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
use run_make_support::{fs_wrapper, run, rust_lib_name, rustc};
|
||||
use run_make_support::{rfs, run, rust_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("m1.rs").run();
|
||||
@ -16,8 +16,8 @@ fn main() {
|
||||
rustc().input("m3.rs").run();
|
||||
rustc().input("m4.rs").run();
|
||||
run("m4");
|
||||
fs_wrapper::remove_file(rust_lib_name("m1"));
|
||||
fs_wrapper::remove_file(rust_lib_name("m2"));
|
||||
fs_wrapper::remove_file(rust_lib_name("m3"));
|
||||
rfs::remove_file(rust_lib_name("m1"));
|
||||
rfs::remove_file(rust_lib_name("m2"));
|
||||
rfs::remove_file(rust_lib_name("m3"));
|
||||
run("m4");
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use run_make_support::{fs_wrapper, htmldocck, rustc, rustdoc, source_root};
|
||||
use run_make_support::{htmldocck, rfs, rustc, rustdoc, source_root};
|
||||
use std::path::Path;
|
||||
|
||||
pub fn scrape(extra_args: &[&str]) {
|
||||
let out_dir = Path::new("rustdoc");
|
||||
let crate_name = "foobar";
|
||||
let deps = fs_wrapper::read_dir("examples")
|
||||
let deps = rfs::read_dir("examples")
|
||||
.filter_map(|entry| entry.ok().map(|e| e.path()))
|
||||
.filter(|path| path.is_file() && path.extension().is_some_and(|ext| ext == "rs"))
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -1,10 +1,10 @@
|
||||
use run_make_support::{fs_wrapper, rustdoc};
|
||||
use run_make_support::{rfs, rustdoc};
|
||||
use std::iter;
|
||||
use std::path::Path;
|
||||
|
||||
fn generate_a_lot_of_cfgs(path: &Path) {
|
||||
let content = iter::repeat("--cfg=a\n").take(100_000).collect::<String>();
|
||||
fs_wrapper::write(path, content.as_bytes());
|
||||
rfs::write(path, content.as_bytes());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,15 +1,14 @@
|
||||
// Test that rustdoc will properly load in a theme file and display it in the theme selector.
|
||||
|
||||
use run_make_support::{fs_wrapper, htmldocck, rustdoc, source_root};
|
||||
use run_make_support::{htmldocck, rfs, rustdoc, source_root};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = Path::new("rustdoc-themes");
|
||||
let test_css = "test.css";
|
||||
|
||||
let no_script = fs_wrapper::read_to_string(
|
||||
source_root().join("src/librustdoc/html/static/css/noscript.css"),
|
||||
);
|
||||
let no_script =
|
||||
rfs::read_to_string(source_root().join("src/librustdoc/html/static/css/noscript.css"));
|
||||
|
||||
let mut test_content = String::new();
|
||||
let mut found_begin_light = false;
|
||||
@ -24,8 +23,8 @@ fn main() {
|
||||
}
|
||||
}
|
||||
assert!(!test_content.is_empty());
|
||||
fs_wrapper::create_dir_all(&out_dir);
|
||||
fs_wrapper::write(&test_css, test_content);
|
||||
rfs::create_dir_all(&out_dir);
|
||||
rfs::write(&test_css, test_content);
|
||||
|
||||
rustdoc().output(&out_dir).input("foo.rs").arg("--theme").arg(&test_css).run();
|
||||
htmldocck().arg(out_dir).arg("foo.rs").run();
|
||||
|
@ -1,7 +1,7 @@
|
||||
use run_make_support::fs_wrapper::copy;
|
||||
use run_make_support::rfs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use run_make_support::{copy_dir_all, recursive_diff, rustdoc};
|
||||
use run_make_support::{assert_dirs_are_equal, rustdoc};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum JsonOutput {
|
||||
@ -26,7 +26,7 @@ fn main() {
|
||||
generate_docs(&out_dir, JsonOutput::No);
|
||||
|
||||
// Copy first output for to check if it's exactly same after second compilation.
|
||||
copy_dir_all(&out_dir, &tmp_out_dir);
|
||||
rfs::copy_dir_all(&out_dir, &tmp_out_dir);
|
||||
|
||||
// Generate html docs once again on same output.
|
||||
generate_docs(&out_dir, JsonOutput::No);
|
||||
@ -38,12 +38,12 @@ fn main() {
|
||||
assert!(out_dir.join("foobar.json").is_file());
|
||||
|
||||
// Copy first json output to check if it's exactly same after second compilation.
|
||||
copy(out_dir.join("foobar.json"), tmp_out_dir.join("foobar.json"));
|
||||
rfs::copy(out_dir.join("foobar.json"), tmp_out_dir.join("foobar.json"));
|
||||
|
||||
// Generate json doc on the same output.
|
||||
generate_docs(&out_dir, JsonOutput::Yes);
|
||||
|
||||
// Check if all docs(including both json and html formats) are still the same after multiple
|
||||
// compilations.
|
||||
recursive_diff(&out_dir, &tmp_out_dir);
|
||||
assert_dirs_are_equal(&out_dir, &tmp_out_dir);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
// See https://github.com/rust-lang/rust/pull/16367
|
||||
|
||||
use run_make_support::{
|
||||
count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc,
|
||||
count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
|
||||
shallow_find_files,
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
// See https://github.com/rust-lang/rust/pull/16367
|
||||
|
||||
use run_make_support::{
|
||||
count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc,
|
||||
count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
|
||||
shallow_find_files,
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// See https://github.com/rust-lang/rust/pull/16367
|
||||
|
||||
use run_make_support::{
|
||||
count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc,
|
||||
count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
|
||||
shallow_find_files,
|
||||
};
|
||||
|
||||
|
@ -11,13 +11,13 @@
|
||||
//@ ignore-windows
|
||||
// Reason: Windows refuses files with < and > in their names
|
||||
|
||||
use run_make_support::{diff, fs_wrapper, run, rustc};
|
||||
use run_make_support::{diff, rfs, run, rustc};
|
||||
|
||||
fn main() {
|
||||
fs_wrapper::create_file("<leading-lt");
|
||||
fs_wrapper::write("<leading-lt", r#""comes from a file with a name that begins with <""#);
|
||||
fs_wrapper::create_file("trailing-gt>");
|
||||
fs_wrapper::write("trailing-gt>", r#""comes from a file with a name that ends with >""#);
|
||||
rfs::create_file("<leading-lt");
|
||||
rfs::write("<leading-lt", r#""comes from a file with a name that begins with <""#);
|
||||
rfs::create_file("trailing-gt>");
|
||||
rfs::write("trailing-gt>", r#""comes from a file with a name that ends with >""#);
|
||||
rustc().input("silly-file-names.rs").output("silly-file-names").run();
|
||||
let out = run("silly-file-names").stdout_utf8();
|
||||
diff().expected_file("silly-file-names.run.stdout").actual_text("actual-stdout", out).run();
|
||||
|
@ -11,12 +11,12 @@
|
||||
//@ ignore-cross-compile
|
||||
//@ needs-symlink
|
||||
|
||||
use run_make_support::{create_symlink, cwd, fs_wrapper, rustc};
|
||||
use run_make_support::{cwd, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").run();
|
||||
fs_wrapper::create_dir_all("other");
|
||||
create_symlink("libfoo.rlib", "other");
|
||||
rfs::create_dir_all("other");
|
||||
rfs::create_symlink("libfoo.rlib", "other");
|
||||
rustc().input("bar.rs").library_search_path(cwd()).run();
|
||||
rustc().input("baz.rs").extern_("foo", "other").library_search_path(cwd()).run();
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
//@ ignore-cross-compile
|
||||
//@ needs-symlink
|
||||
|
||||
use run_make_support::{create_symlink, dynamic_lib_name, fs_wrapper, rustc};
|
||||
use run_make_support::{dynamic_lib_name, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").arg("-Cprefer-dynamic").run();
|
||||
fs_wrapper::create_dir_all("other");
|
||||
create_symlink(dynamic_lib_name("foo"), "other");
|
||||
rfs::create_dir_all("other");
|
||||
rfs::create_symlink(dynamic_lib_name("foo"), "other");
|
||||
rustc().input("bar.rs").library_search_path("other").run();
|
||||
}
|
||||
|
@ -8,10 +8,10 @@
|
||||
//@ ignore-cross-compile
|
||||
//@ needs-symlink
|
||||
|
||||
use run_make_support::{create_symlink, cwd, rustc};
|
||||
use run_make_support::{cwd, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").crate_type("rlib").output("foo.xxx").run();
|
||||
create_symlink("foo.xxx", "libfoo.rlib");
|
||||
rfs::create_symlink("foo.xxx", "libfoo.rlib");
|
||||
rustc().input("bar.rs").library_search_path(cwd()).run();
|
||||
}
|
||||
|
@ -5,11 +5,11 @@
|
||||
// using them correctly, or fails with the right error message when using them improperly.
|
||||
// See https://github.com/rust-lang/rust/pull/16156
|
||||
|
||||
use run_make_support::{diff, fs_wrapper, rustc};
|
||||
use run_make_support::{diff, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").target("my-awesome-platform.json").crate_type("lib").emit("asm").run();
|
||||
assert!(!fs_wrapper::read_to_string("foo.s").contains("morestack"));
|
||||
assert!(!rfs::read_to_string("foo.s").contains("morestack"));
|
||||
rustc()
|
||||
.input("foo.rs")
|
||||
.target("my-invalid-platform.json")
|
||||
@ -40,8 +40,8 @@ fn main() {
|
||||
.print("target-spec-json")
|
||||
.run()
|
||||
.stdout_utf8();
|
||||
fs_wrapper::create_file("test-platform.json");
|
||||
fs_wrapper::write("test-platform.json", test_platform.as_bytes());
|
||||
rfs::create_file("test-platform.json");
|
||||
rfs::write("test-platform.json", test_platform.as_bytes());
|
||||
let test_platform_2 = rustc()
|
||||
.arg("-Zunstable-options")
|
||||
.target("test-platform.json")
|
||||
|
@ -4,10 +4,10 @@
|
||||
// output successfully added the file as a dependency.
|
||||
// See https://github.com/rust-lang/rust/pull/84029
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("macro_def.rs").run();
|
||||
rustc().env("EXISTING_PROC_MACRO_ENV", "1").emit("dep-info").input("macro_use.rs").run();
|
||||
assert!(fs_wrapper::read_to_string("macro_use.d").contains("emojis.txt:"));
|
||||
assert!(rfs::read_to_string("macro_use.d").contains("emojis.txt:"));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// Reason: the binary is executed
|
||||
//@ needs-profiler-support
|
||||
|
||||
use run_make_support::{fs_wrapper, llvm_profdata, run, rustc};
|
||||
use run_make_support::{llvm_profdata, rfs, run, rustc};
|
||||
|
||||
fn main() {
|
||||
// Generate the profile-guided-optimization (PGO) profiles
|
||||
@ -19,5 +19,5 @@ fn main() {
|
||||
// Use the profiles in compilation
|
||||
rustc().profile_use("merged.profdata").emit("dep-info").input("main.rs").run();
|
||||
// Check that the profile file is in the dep-info emit file
|
||||
assert!(fs_wrapper::read_to_string("main.d").contains("merged.profdata"));
|
||||
assert!(rfs::read_to_string("main.d").contains("merged.profdata"));
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::fs_wrapper::read;
|
||||
use run_make_support::rfs;
|
||||
use run_make_support::{assert_contains, run, rustc};
|
||||
|
||||
fn main() {
|
||||
@ -11,7 +11,7 @@ fn main() {
|
||||
// ... and the loads/stores must not be optimized out.
|
||||
rustc().input("main.rs").emit("llvm-ir").run();
|
||||
|
||||
let raw_llvm_ir = read("main.ll");
|
||||
let raw_llvm_ir = rfs::read("main.ll");
|
||||
let llvm_ir = String::from_utf8_lossy(&raw_llvm_ir);
|
||||
assert_contains(&llvm_ir, "load volatile");
|
||||
assert_contains(&llvm_ir, "store volatile");
|
||||
|
@ -1,13 +1,13 @@
|
||||
//@ only-wasm32-wasip1
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, wasmparser};
|
||||
use run_make_support::{rfs, rustc, wasmparser};
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").target("wasm32-wasip1").run();
|
||||
rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
|
||||
|
||||
let file = fs_wrapper::read("bar.wasm");
|
||||
let file = rfs::read("bar.wasm");
|
||||
|
||||
let mut custom = HashMap::new();
|
||||
for payload in wasmparser::Parser::new(0).parse_all(&file) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ only-wasm32-wasip1
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, wasmparser};
|
||||
use run_make_support::{rfs, rustc, wasmparser};
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
@ -12,7 +12,7 @@ fn main() {
|
||||
|
||||
fn verify(path: &Path) {
|
||||
eprintln!("verify {path:?}");
|
||||
let file = fs_wrapper::read(&path);
|
||||
let file = rfs::read(&path);
|
||||
|
||||
let mut custom = HashMap::new();
|
||||
for payload in wasmparser::Parser::new(0).parse_all(&file) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ only-wasm32-wasip1
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, wasmparser};
|
||||
use run_make_support::{rfs, rustc, wasmparser};
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use wasmparser::ExternalKind::*;
|
||||
@ -33,7 +33,7 @@ fn test(args: &[&str]) {
|
||||
|
||||
fn verify_exports(path: &Path, exports: &[(&str, wasmparser::ExternalKind)]) {
|
||||
println!("verify {path:?}");
|
||||
let file = fs_wrapper::read(path);
|
||||
let file = rfs::read(path);
|
||||
let mut wasm_exports = HashMap::new();
|
||||
for payload in wasmparser::Parser::new(0).parse_all(&file) {
|
||||
let payload = payload.unwrap();
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ only-wasm32-wasip1
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, wasmparser};
|
||||
use run_make_support::{rfs, rustc, wasmparser};
|
||||
use std::collections::HashMap;
|
||||
use wasmparser::TypeRef::Func;
|
||||
|
||||
@ -8,7 +8,7 @@ fn main() {
|
||||
rustc().input("foo.rs").target("wasm32-wasip1").run();
|
||||
rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
|
||||
|
||||
let file = fs_wrapper::read("bar.wasm");
|
||||
let file = rfs::read("bar.wasm");
|
||||
|
||||
let mut imports = HashMap::new();
|
||||
for payload in wasmparser::Parser::new(0).parse_all(&file) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
//@ only-wasm32-wasip1
|
||||
#![deny(warnings)]
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
test("a");
|
||||
@ -15,7 +15,7 @@ fn test(cfg: &str) {
|
||||
|
||||
rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().cfg(cfg).run();
|
||||
|
||||
let bytes = fs_wrapper::read("foo.wasm");
|
||||
let bytes = rfs::read("foo.wasm");
|
||||
println!("{}", bytes.len());
|
||||
assert!(bytes.len() < 40_000);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ only-wasm32-wasip1
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, wasmparser};
|
||||
use run_make_support::{rfs, rustc, wasmparser};
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
@ -13,7 +13,7 @@ fn main() {
|
||||
.arg("-Copt-level=z")
|
||||
.run();
|
||||
|
||||
let file = fs_wrapper::read("main.wasm");
|
||||
let file = rfs::read("main.wasm");
|
||||
|
||||
let mut imports = HashMap::new();
|
||||
for payload in wasmparser::Parser::new(0).parse_all(&file) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
//@ only-wasm32-wasip1
|
||||
#![deny(warnings)]
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc};
|
||||
use run_make_support::{rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
|
||||
|
||||
let bytes = fs_wrapper::read("foo.wasm");
|
||||
let bytes = rfs::read("foo.wasm");
|
||||
println!("{}", bytes.len());
|
||||
assert!(bytes.len() < 50_000);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ only-wasm32-wasip1
|
||||
|
||||
use run_make_support::{fs_wrapper, rustc, wasmparser};
|
||||
use run_make_support::{rfs, rustc, wasmparser};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::Path;
|
||||
|
||||
@ -23,7 +23,7 @@ fn test(file: &str, args: &[&str], expected_imports: &[(&str, &[&str])]) {
|
||||
|
||||
rustc().input(file).target("wasm32-wasip1").args(args).run();
|
||||
|
||||
let file = fs_wrapper::read(Path::new(file).with_extension("wasm"));
|
||||
let file = rfs::read(Path::new(file).with_extension("wasm"));
|
||||
|
||||
let mut imports = HashMap::new();
|
||||
for payload in wasmparser::Parser::new(0).parse_all(&file) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user