authorbors <bors@rust-lang.org> 2024-07-17 15:52:03 UTC
committerbors <bors@rust-lang.org> 2024-07-17 15:52:03 UTC
logf00f85091904530ee8f5b29251c53571e0062a76
tree55c92bd435c1a7fb2423d59163dd975db1363b4a
parent08cdc2fa1a9fd5ba466838f69cfaf062a3a64ad1
parentd69cc1ccbf9d25225add138a4b0f6ee424d0d59a

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

110 files changed, 2107 insertions(+), 1948 deletions(-)

src/tools/run-make-support/src/artifact_names.rs created+81
......@@ -0,0 +1,81 @@
1//! A collection of helpers to construct artifact names, such as names of dynamic or static
2//! librarys which are target-dependent.
3
4use crate::targets::{is_darwin, is_msvc, is_windows};
5
6/// Construct the static library name based on the target.
7#[must_use]
8pub fn static_lib_name(name: &str) -> String {
9 // See tools.mk (irrelevant lines omitted):
10 //
11 // ```makefile
12 // ifeq ($(UNAME),Darwin)
13 // STATICLIB = $(TMPDIR)/lib$(1).a
14 // else
15 // ifdef IS_WINDOWS
16 // ifdef IS_MSVC
17 // STATICLIB = $(TMPDIR)/$(1).lib
18 // else
19 // STATICLIB = $(TMPDIR)/lib$(1).a
20 // endif
21 // else
22 // STATICLIB = $(TMPDIR)/lib$(1).a
23 // endif
24 // endif
25 // ```
26 assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
27
28 if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
29}
30
31/// Construct the dynamic library name based on the target.
32#[must_use]
33pub fn dynamic_lib_name(name: &str) -> String {
34 // See tools.mk (irrelevant lines omitted):
35 //
36 // ```makefile
37 // ifeq ($(UNAME),Darwin)
38 // DYLIB = $(TMPDIR)/lib$(1).dylib
39 // else
40 // ifdef IS_WINDOWS
41 // DYLIB = $(TMPDIR)/$(1).dll
42 // else
43 // DYLIB = $(TMPDIR)/lib$(1).so
44 // endif
45 // endif
46 // ```
47 assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
48
49 let extension = dynamic_lib_extension();
50 if is_darwin() {
51 format!("lib{name}.{extension}")
52 } else if is_windows() {
53 format!("{name}.{extension}")
54 } else {
55 format!("lib{name}.{extension}")
56 }
57}
58
59/// Construct the dynamic library extension based on the target.
60#[must_use]
61pub fn dynamic_lib_extension() -> &'static str {
62 if is_darwin() {
63 "dylib"
64 } else if is_windows() {
65 "dll"
66 } else {
67 "so"
68 }
69}
70
71/// Construct the name of a rust library (rlib).
72#[must_use]
73pub fn rust_lib_name(name: &str) -> String {
74 format!("lib{name}.rlib")
75}
76
77/// Construct the binary (executable) name based on the target.
78#[must_use]
79pub fn bin_name(name: &str) -> String {
80 if is_windows() { format!("{name}.exe") } else { name.to_string() }
81}
src/tools/run-make-support/src/assertion_helpers.rs created+73
......@@ -0,0 +1,73 @@
1//! Collection of assertions and assertion-related helpers.
2
3use std::panic;
4use std::path::Path;
5
6use crate::fs;
7
8/// Assert that `actual` is equal to `expected`.
9#[track_caller]
10pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) {
11 let actual = actual.as_ref();
12 let expected = expected.as_ref();
13 if actual != expected {
14 eprintln!("=== ACTUAL TEXT ===");
15 eprintln!("{}", actual);
16 eprintln!("=== EXPECTED ===");
17 eprintln!("{}", expected);
18 panic!("expected text was not found in actual text");
19 }
20}
21
22/// Assert that `haystack` contains `needle`.
23#[track_caller]
24pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
25 let haystack = haystack.as_ref();
26 let needle = needle.as_ref();
27 if !haystack.contains(needle) {
28 eprintln!("=== HAYSTACK ===");
29 eprintln!("{}", haystack);
30 eprintln!("=== NEEDLE ===");
31 eprintln!("{}", needle);
32 panic!("needle was not found in haystack");
33 }
34}
35
36/// Assert that `haystack` does not contain `needle`.
37#[track_caller]
38pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) {
39 let haystack = haystack.as_ref();
40 let needle = needle.as_ref();
41 if haystack.contains(needle) {
42 eprintln!("=== HAYSTACK ===");
43 eprintln!("{}", haystack);
44 eprintln!("=== NEEDLE ===");
45 eprintln!("{}", needle);
46 panic!("needle was unexpectedly found in haystack");
47 }
48}
49
50/// Assert that all files in `dir1` exist and have the same content in `dir2`
51pub fn assert_dirs_are_equal(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
52 let dir2 = dir2.as_ref();
53 fs::read_dir_entries(dir1, |entry_path| {
54 let entry_name = entry_path.file_name().unwrap();
55 if entry_path.is_dir() {
56 assert_dirs_are_equal(&entry_path, &dir2.join(entry_name));
57 } else {
58 let path2 = dir2.join(entry_name);
59 let file1 = fs::read(&entry_path);
60 let file2 = fs::read(&path2);
61
62 // We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
63 // Why not using String? Because there might be minified files or even potentially
64 // binary ones, so that would display useless output.
65 assert!(
66 file1 == file2,
67 "`{}` and `{}` have different content",
68 entry_path.display(),
69 path2.display(),
70 );
71 }
72 });
73}
src/tools/run-make-support/src/cc.rs deleted-191
......@@ -1,191 +0,0 @@
1use std::path::Path;
2
3use crate::command::Command;
4use crate::{cygpath_windows, env_var, is_msvc, is_windows, uname};
5
6/// Construct a new platform-specific C compiler invocation.
7///
8/// WARNING: This means that what flags are accepted by the underlying C compiler is
9/// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
10#[track_caller]
11pub fn cc() -> Cc {
12 Cc::new()
13}
14
15/// A platform-specific C compiler invocation builder. The specific C compiler used is
16/// passed down from compiletest.
17#[derive(Debug)]
18#[must_use]
19pub struct Cc {
20 cmd: Command,
21}
22
23crate::impl_common_helpers!(Cc);
24
25impl Cc {
26 /// Construct a new platform-specific C compiler invocation.
27 ///
28 /// WARNING: This means that what flags are accepted by the underlying C compile is
29 /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
30 #[track_caller]
31 pub fn new() -> Self {
32 let compiler = env_var("CC");
33
34 let mut cmd = Command::new(compiler);
35
36 let default_cflags = env_var("CC_DEFAULT_FLAGS");
37 for flag in default_cflags.split(char::is_whitespace) {
38 cmd.arg(flag);
39 }
40
41 Self { cmd }
42 }
43
44 /// Specify path of the input file.
45 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
46 self.cmd.arg(path.as_ref());
47 self
48 }
49
50 /// Adds directories to the list that the linker searches for libraries.
51 /// Equivalent to `-L`.
52 pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
53 self.cmd.arg("-L");
54 self.cmd.arg(path.as_ref());
55 self
56 }
57
58 /// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler.
59 pub fn out_exe(&mut self, name: &str) -> &mut Self {
60 // Ref: tools.mk (irrelevant lines omitted):
61 //
62 // ```makefile
63 // ifdef IS_MSVC
64 // OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
65 // -Fo:`cygpath -w $(TMPDIR)/$(1).obj`
66 // else
67 // OUT_EXE=-o $(TMPDIR)/$(1)
68 // endif
69 // ```
70
71 let mut path = std::path::PathBuf::from(name);
72
73 if is_msvc() {
74 path.set_extension("exe");
75 let fe_path = cygpath_windows(&path);
76 path.set_extension("");
77 path.set_extension("obj");
78 let fo_path = cygpath_windows(path);
79 self.cmd.arg(format!("-Fe:{fe_path}"));
80 self.cmd.arg(format!("-Fo:{fo_path}"));
81 } else {
82 self.cmd.arg("-o");
83 self.cmd.arg(name);
84 }
85
86 self
87 }
88
89 /// Specify path of the output binary.
90 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
91 self.cmd.arg("-o");
92 self.cmd.arg(path.as_ref());
93 self
94 }
95}
96
97/// `EXTRACFLAGS`
98pub fn extra_c_flags() -> Vec<&'static str> {
99 // Adapted from tools.mk (trimmed):
100 //
101 // ```makefile
102 // ifdef IS_WINDOWS
103 // ifdef IS_MSVC
104 // EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
105 // else
106 // EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
107 // endif
108 // else
109 // ifeq ($(UNAME),Darwin)
110 // EXTRACFLAGS := -lresolv
111 // else
112 // ifeq ($(UNAME),FreeBSD)
113 // EXTRACFLAGS := -lm -lpthread -lgcc_s
114 // else
115 // ifeq ($(UNAME),SunOS)
116 // EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
117 // else
118 // ifeq ($(UNAME),OpenBSD)
119 // EXTRACFLAGS := -lm -lpthread -lc++abi
120 // else
121 // EXTRACFLAGS := -lm -lrt -ldl -lpthread
122 // endif
123 // endif
124 // endif
125 // endif
126 // endif
127 // ```
128
129 if is_windows() {
130 if is_msvc() {
131 vec![
132 "ws2_32.lib",
133 "userenv.lib",
134 "advapi32.lib",
135 "bcrypt.lib",
136 "ntdll.lib",
137 "synchronization.lib",
138 ]
139 } else {
140 vec!["-lws2_32", "-luserenv", "-lbcrypt", "-lntdll", "-lsynchronization"]
141 }
142 } else {
143 match uname() {
144 n if n.contains("Darwin") => vec!["-lresolv"],
145 n if n.contains("FreeBSD") => vec!["-lm", "-lpthread", "-lgcc_s"],
146 n if n.contains("SunOS") => {
147 vec!["-lm", "-lpthread", "-lposix4", "-lsocket", "-lresolv"]
148 }
149 n if n.contains("OpenBSD") => vec!["-lm", "-lpthread", "-lc++abi"],
150 _ => vec!["-lm", "-lrt", "-ldl", "-lpthread"],
151 }
152 }
153}
154
155/// `EXTRACXXFLAGS`
156pub fn extra_cxx_flags() -> Vec<&'static str> {
157 // Adapted from tools.mk (trimmed):
158 //
159 // ```makefile
160 // ifdef IS_WINDOWS
161 // ifdef IS_MSVC
162 // else
163 // EXTRACXXFLAGS := -lstdc++
164 // endif
165 // else
166 // ifeq ($(UNAME),Darwin)
167 // EXTRACXXFLAGS := -lc++
168 // else
169 // ifeq ($(UNAME),FreeBSD)
170 // else
171 // ifeq ($(UNAME),SunOS)
172 // else
173 // ifeq ($(UNAME),OpenBSD)
174 // else
175 // EXTRACXXFLAGS := -lstdc++
176 // endif
177 // endif
178 // endif
179 // endif
180 // endif
181 // ```
182 if is_windows() {
183 if is_msvc() { vec![] } else { vec!["-lstdc++"] }
184 } else {
185 match &uname()[..] {
186 "Darwin" => vec!["-lc++"],
187 "FreeBSD" | "SunOS" | "OpenBSD" => vec![],
188 _ => vec!["-lstdc++"],
189 }
190 }
191}
src/tools/run-make-support/src/clang.rs deleted-74
......@@ -1,74 +0,0 @@
1use std::path::Path;
2
3use crate::command::Command;
4use crate::{bin_name, env_var};
5
6/// Construct a new `clang` invocation. `clang` is not always available for all targets.
7#[track_caller]
8pub fn clang() -> Clang {
9 Clang::new()
10}
11
12/// A `clang` invocation builder.
13#[derive(Debug)]
14#[must_use]
15pub struct Clang {
16 cmd: Command,
17}
18
19crate::impl_common_helpers!(Clang);
20
21impl Clang {
22 /// Construct a new `clang` invocation. `clang` is not always available for all targets.
23 #[track_caller]
24 pub fn new() -> Self {
25 let clang = env_var("CLANG");
26 let cmd = Command::new(clang);
27 Self { cmd }
28 }
29
30 /// Provide an input file.
31 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
32 self.cmd.arg(path.as_ref());
33 self
34 }
35
36 /// Specify the name of the executable. The executable will be placed under the current directory
37 /// and the extension will be determined by [`bin_name`].
38 pub fn out_exe(&mut self, name: &str) -> &mut Self {
39 self.cmd.arg("-o");
40 self.cmd.arg(bin_name(name));
41 self
42 }
43
44 /// Specify which target triple clang should target.
45 pub fn target(&mut self, target_triple: &str) -> &mut Self {
46 self.cmd.arg("-target");
47 self.cmd.arg(target_triple);
48 self
49 }
50
51 /// Pass `-nostdlib` to disable linking the C standard library.
52 pub fn no_stdlib(&mut self) -> &mut Self {
53 self.cmd.arg("-nostdlib");
54 self
55 }
56
57 /// Specify architecture.
58 pub fn arch(&mut self, arch: &str) -> &mut Self {
59 self.cmd.arg(format!("-march={arch}"));
60 self
61 }
62
63 /// Specify LTO settings.
64 pub fn lto(&mut self, lto: &str) -> &mut Self {
65 self.cmd.arg(format!("-flto={lto}"));
66 self
67 }
68
69 /// Specify which ld to use.
70 pub fn use_ld(&mut self, ld: &str) -> &mut Self {
71 self.cmd.arg(format!("-fuse-ld={ld}"));
72 self
73 }
74}
src/tools/run-make-support/src/command.rs+3-1
......@@ -5,7 +5,9 @@ use std::panic;
55use std::path::Path;
66use std::process::{Command as StdCommand, ExitStatus, Output, Stdio};
77
8use crate::{assert_contains, assert_equals, assert_not_contains, handle_failed_output};
8use crate::util::handle_failed_output;
9use crate::{assert_contains, assert_equals, assert_not_contains};
10
911use build_helper::drop_bomb::DropBomb;
1012
1113/// This is a custom command wrapper that simplifies working with commands and makes it easier to
src/tools/run-make-support/src/diff/mod.rs+8-6
......@@ -1,10 +1,12 @@
1use std::path::{Path, PathBuf};
2
13use regex::Regex;
24use similar::TextDiff;
3use std::path::{Path, PathBuf};
45
5use crate::fs_wrapper;
66use build_helper::drop_bomb::DropBomb;
77
8use crate::fs;
9
810#[cfg(test)]
911mod tests;
1012
......@@ -43,7 +45,7 @@ impl Diff {
4345 /// Specify the expected output for the diff from a file.
4446 pub fn expected_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
4547 let path = path.as_ref();
46 let content = fs_wrapper::read_to_string(path);
48 let content = fs::read_to_string(path);
4749 let name = path.to_string_lossy().to_string();
4850
4951 self.expected_file = Some(path.into());
......@@ -62,7 +64,7 @@ impl Diff {
6264 /// Specify the actual output for the diff from a file.
6365 pub fn actual_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
6466 let path = path.as_ref();
65 let content = fs_wrapper::read_to_string(path);
67 let content = fs::read_to_string(path);
6668 let name = path.to_string_lossy().to_string();
6769
6870 self.actual = Some(content);
......@@ -116,7 +118,7 @@ impl Diff {
116118 if let Some(ref expected_file) = self.expected_file {
117119 if std::env::var("RUSTC_BLESS_TEST").is_ok() {
118120 println!("Blessing `{}`", expected_file.display());
119 fs_wrapper::write(expected_file, actual);
121 fs::write(expected_file, actual);
120122 return;
121123 }
122124 }
......@@ -138,7 +140,7 @@ impl Diff {
138140 if let Some(ref expected_file) = self.expected_file {
139141 if std::env::var("RUSTC_BLESS_TEST").is_ok() {
140142 println!("Blessing `{}`", expected_file.display());
141 fs_wrapper::write(expected_file, actual);
143 fs::write(expected_file, actual);
142144 return;
143145 }
144146 }
src/tools/run-make-support/src/env.rs created+19
......@@ -0,0 +1,19 @@
1use std::ffi::OsString;
2
3#[track_caller]
4#[must_use]
5pub fn env_var(name: &str) -> String {
6 match std::env::var(name) {
7 Ok(v) => v,
8 Err(err) => panic!("failed to retrieve environment variable {name:?}: {err:?}"),
9 }
10}
11
12#[track_caller]
13#[must_use]
14pub fn env_var_os(name: &str) -> OsString {
15 match std::env::var_os(name) {
16 Some(v) => v,
17 None => panic!("failed to retrieve environment variable {name:?}"),
18 }
19}
src/tools/run-make-support/src/external_deps/c_build.rs created+27
......@@ -0,0 +1,27 @@
1use std::path::PathBuf;
2
3use crate::artifact_names::static_lib_name;
4use crate::external_deps::cc::cc;
5use crate::external_deps::llvm::llvm_ar;
6use crate::path_helpers::path;
7use crate::targets::is_msvc;
8
9/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
10#[track_caller]
11pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
12 let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
13 let src = format!("{lib_name}.c");
14 let lib_path = static_lib_name(lib_name);
15 if is_msvc() {
16 cc().arg("-c").out_exe(&obj_file).input(src).run();
17 } else {
18 cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
19 };
20 let obj_file = if is_msvc() {
21 PathBuf::from(format!("{lib_name}.obj"))
22 } else {
23 PathBuf::from(format!("{lib_name}.o"))
24 };
25 llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
26 path(lib_path)
27}
src/tools/run-make-support/src/external_deps/cc.rs created+194
......@@ -0,0 +1,194 @@
1use std::path::Path;
2
3use crate::command::Command;
4use crate::{env_var, is_msvc, is_windows, uname};
5
6// FIXME(jieyouxu): can we get rid of the `cygpath` external dependency?
7use super::cygpath::get_windows_path;
8
9/// Construct a new platform-specific C compiler invocation.
10///
11/// WARNING: This means that what flags are accepted by the underlying C compiler is
12/// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
13#[track_caller]
14pub fn cc() -> Cc {
15 Cc::new()
16}
17
18/// A platform-specific C compiler invocation builder. The specific C compiler used is
19/// passed down from compiletest.
20#[derive(Debug)]
21#[must_use]
22pub struct Cc {
23 cmd: Command,
24}
25
26crate::macros::impl_common_helpers!(Cc);
27
28impl Cc {
29 /// Construct a new platform-specific C compiler invocation.
30 ///
31 /// WARNING: This means that what flags are accepted by the underlying C compile is
32 /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
33 #[track_caller]
34 pub fn new() -> Self {
35 let compiler = env_var("CC");
36
37 let mut cmd = Command::new(compiler);
38
39 let default_cflags = env_var("CC_DEFAULT_FLAGS");
40 for flag in default_cflags.split(char::is_whitespace) {
41 cmd.arg(flag);
42 }
43
44 Self { cmd }
45 }
46
47 /// Specify path of the input file.
48 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
49 self.cmd.arg(path.as_ref());
50 self
51 }
52
53 /// Adds directories to the list that the linker searches for libraries.
54 /// Equivalent to `-L`.
55 pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
56 self.cmd.arg("-L");
57 self.cmd.arg(path.as_ref());
58 self
59 }
60
61 /// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler.
62 pub fn out_exe(&mut self, name: &str) -> &mut Self {
63 // Ref: tools.mk (irrelevant lines omitted):
64 //
65 // ```makefile
66 // ifdef IS_MSVC
67 // OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
68 // -Fo:`cygpath -w $(TMPDIR)/$(1).obj`
69 // else
70 // OUT_EXE=-o $(TMPDIR)/$(1)
71 // endif
72 // ```
73
74 let mut path = std::path::PathBuf::from(name);
75
76 if is_msvc() {
77 path.set_extension("exe");
78 let fe_path = get_windows_path(&path);
79 path.set_extension("");
80 path.set_extension("obj");
81 let fo_path = get_windows_path(path);
82 self.cmd.arg(format!("-Fe:{fe_path}"));
83 self.cmd.arg(format!("-Fo:{fo_path}"));
84 } else {
85 self.cmd.arg("-o");
86 self.cmd.arg(name);
87 }
88
89 self
90 }
91
92 /// Specify path of the output binary.
93 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
94 self.cmd.arg("-o");
95 self.cmd.arg(path.as_ref());
96 self
97 }
98}
99
100/// `EXTRACFLAGS`
101pub fn extra_c_flags() -> Vec<&'static str> {
102 // Adapted from tools.mk (trimmed):
103 //
104 // ```makefile
105 // ifdef IS_WINDOWS
106 // ifdef IS_MSVC
107 // EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
108 // else
109 // EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
110 // endif
111 // else
112 // ifeq ($(UNAME),Darwin)
113 // EXTRACFLAGS := -lresolv
114 // else
115 // ifeq ($(UNAME),FreeBSD)
116 // EXTRACFLAGS := -lm -lpthread -lgcc_s
117 // else
118 // ifeq ($(UNAME),SunOS)
119 // EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
120 // else
121 // ifeq ($(UNAME),OpenBSD)
122 // EXTRACFLAGS := -lm -lpthread -lc++abi
123 // else
124 // EXTRACFLAGS := -lm -lrt -ldl -lpthread
125 // endif
126 // endif
127 // endif
128 // endif
129 // endif
130 // ```
131
132 if is_windows() {
133 if is_msvc() {
134 vec![
135 "ws2_32.lib",
136 "userenv.lib",
137 "advapi32.lib",
138 "bcrypt.lib",
139 "ntdll.lib",
140 "synchronization.lib",
141 ]
142 } else {
143 vec!["-lws2_32", "-luserenv", "-lbcrypt", "-lntdll", "-lsynchronization"]
144 }
145 } else {
146 match uname() {
147 n if n.contains("Darwin") => vec!["-lresolv"],
148 n if n.contains("FreeBSD") => vec!["-lm", "-lpthread", "-lgcc_s"],
149 n if n.contains("SunOS") => {
150 vec!["-lm", "-lpthread", "-lposix4", "-lsocket", "-lresolv"]
151 }
152 n if n.contains("OpenBSD") => vec!["-lm", "-lpthread", "-lc++abi"],
153 _ => vec!["-lm", "-lrt", "-ldl", "-lpthread"],
154 }
155 }
156}
157
158/// `EXTRACXXFLAGS`
159pub fn extra_cxx_flags() -> Vec<&'static str> {
160 // Adapted from tools.mk (trimmed):
161 //
162 // ```makefile
163 // ifdef IS_WINDOWS
164 // ifdef IS_MSVC
165 // else
166 // EXTRACXXFLAGS := -lstdc++
167 // endif
168 // else
169 // ifeq ($(UNAME),Darwin)
170 // EXTRACXXFLAGS := -lc++
171 // else
172 // ifeq ($(UNAME),FreeBSD)
173 // else
174 // ifeq ($(UNAME),SunOS)
175 // else
176 // ifeq ($(UNAME),OpenBSD)
177 // else
178 // EXTRACXXFLAGS := -lstdc++
179 // endif
180 // endif
181 // endif
182 // endif
183 // endif
184 // ```
185 if is_windows() {
186 if is_msvc() { vec![] } else { vec!["-lstdc++"] }
187 } else {
188 match &uname()[..] {
189 "Darwin" => vec!["-lc++"],
190 "FreeBSD" | "SunOS" | "OpenBSD" => vec![],
191 _ => vec!["-lstdc++"],
192 }
193 }
194}
src/tools/run-make-support/src/external_deps/clang.rs created+74
......@@ -0,0 +1,74 @@
1use std::path::Path;
2
3use crate::command::Command;
4use crate::{bin_name, env_var};
5
6/// Construct a new `clang` invocation. `clang` is not always available for all targets.
7#[track_caller]
8pub fn clang() -> Clang {
9 Clang::new()
10}
11
12/// A `clang` invocation builder.
13#[derive(Debug)]
14#[must_use]
15pub struct Clang {
16 cmd: Command,
17}
18
19crate::macros::impl_common_helpers!(Clang);
20
21impl Clang {
22 /// Construct a new `clang` invocation. `clang` is not always available for all targets.
23 #[track_caller]
24 pub fn new() -> Self {
25 let clang = env_var("CLANG");
26 let cmd = Command::new(clang);
27 Self { cmd }
28 }
29
30 /// Provide an input file.
31 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
32 self.cmd.arg(path.as_ref());
33 self
34 }
35
36 /// Specify the name of the executable. The executable will be placed under the current directory
37 /// and the extension will be determined by [`bin_name`].
38 pub fn out_exe(&mut self, name: &str) -> &mut Self {
39 self.cmd.arg("-o");
40 self.cmd.arg(bin_name(name));
41 self
42 }
43
44 /// Specify which target triple clang should target.
45 pub fn target(&mut self, target_triple: &str) -> &mut Self {
46 self.cmd.arg("-target");
47 self.cmd.arg(target_triple);
48 self
49 }
50
51 /// Pass `-nostdlib` to disable linking the C standard library.
52 pub fn no_stdlib(&mut self) -> &mut Self {
53 self.cmd.arg("-nostdlib");
54 self
55 }
56
57 /// Specify architecture.
58 pub fn arch(&mut self, arch: &str) -> &mut Self {
59 self.cmd.arg(format!("-march={arch}"));
60 self
61 }
62
63 /// Specify LTO settings.
64 pub fn lto(&mut self, lto: &str) -> &mut Self {
65 self.cmd.arg(format!("-flto={lto}"));
66 self
67 }
68
69 /// Specify which ld to use.
70 pub fn use_ld(&mut self, ld: &str) -> &mut Self {
71 self.cmd.arg(format!("-fuse-ld={ld}"));
72 self
73 }
74}
src/tools/run-make-support/src/external_deps/cygpath.rs created+35
......@@ -0,0 +1,35 @@
1use std::panic;
2use std::path::Path;
3
4use crate::command::Command;
5use crate::util::handle_failed_output;
6
7/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
8/// available on the platform!
9///
10/// # FIXME
11///
12/// FIXME(jieyouxu): we should consider not depending on `cygpath`.
13///
14/// > The cygpath program is a utility that converts Windows native filenames to Cygwin POSIX-style
15/// > pathnames and vice versa.
16/// >
17/// > [irrelevant entries omitted...]
18/// >
19/// > `-w, --windows print Windows form of NAMEs (C:\WINNT)`
20/// >
21/// > -- *from [cygpath documentation](https://cygwin.com/cygwin-ug-net/cygpath.html)*.
22#[track_caller]
23#[must_use]
24pub fn get_windows_path<P: AsRef<Path>>(path: P) -> String {
25 let caller = panic::Location::caller();
26 let mut cygpath = Command::new("cygpath");
27 cygpath.arg("-w");
28 cygpath.arg(path.as_ref());
29 let output = cygpath.run();
30 if !output.status().success() {
31 handle_failed_output(&cygpath, output, caller.line());
32 }
33 // cygpath -w can attach a newline
34 output.stdout_utf8().trim().to_string()
35}
src/tools/run-make-support/src/external_deps/htmldocck.rs created+14
......@@ -0,0 +1,14 @@
1use crate::command::Command;
2use crate::source_root;
3
4use super::python::python_command;
5
6/// `htmldocck` is a python script which is used for rustdoc test suites, it is assumed to be
7/// available at `$SOURCE_ROOT/src/etc/htmldocck.py`.
8#[track_caller]
9#[must_use]
10pub fn htmldocck() -> Command {
11 let mut python = python_command();
12 python.arg(source_root().join("src/etc/htmldocck.py"));
13 python
14}
src/tools/run-make-support/src/external_deps/llvm.rs created+244
......@@ -0,0 +1,244 @@
1use std::path::{Path, PathBuf};
2
3use crate::command::Command;
4use crate::env::env_var;
5
6/// Construct a new `llvm-readobj` invocation with the `GNU` output style.
7/// This assumes that `llvm-readobj` is available at `$LLVM_BIN_DIR/llvm-readobj`.
8#[track_caller]
9pub fn llvm_readobj() -> LlvmReadobj {
10 LlvmReadobj::new()
11}
12
13/// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available
14/// at `$LLVM_BIN_DIR/llvm-profdata`.
15#[track_caller]
16pub fn llvm_profdata() -> LlvmProfdata {
17 LlvmProfdata::new()
18}
19
20/// Construct a new `llvm-filecheck` invocation. This assumes that `llvm-filecheck` is available
21/// at `$LLVM_FILECHECK`.
22#[track_caller]
23pub fn llvm_filecheck() -> LlvmFilecheck {
24 LlvmFilecheck::new()
25}
26
27/// Construct a new `llvm-objdump` invocation. This assumes that `llvm-objdump` is available
28/// at `$LLVM_BIN_DIR/llvm-objdump`.
29pub fn llvm_objdump() -> LlvmObjdump {
30 LlvmObjdump::new()
31}
32
33/// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available
34/// at `$LLVM_BIN_DIR/llvm-ar`.
35pub fn llvm_ar() -> LlvmAr {
36 LlvmAr::new()
37}
38
39/// A `llvm-readobj` invocation builder.
40#[derive(Debug)]
41#[must_use]
42pub struct LlvmReadobj {
43 cmd: Command,
44}
45
46/// A `llvm-profdata` invocation builder.
47#[derive(Debug)]
48#[must_use]
49pub struct LlvmProfdata {
50 cmd: Command,
51}
52
53/// A `llvm-filecheck` invocation builder.
54#[derive(Debug)]
55#[must_use]
56pub struct LlvmFilecheck {
57 cmd: Command,
58}
59
60/// A `llvm-objdump` invocation builder.
61#[derive(Debug)]
62#[must_use]
63pub struct LlvmObjdump {
64 cmd: Command,
65}
66
67/// A `llvm-ar` invocation builder.
68#[derive(Debug)]
69#[must_use]
70pub struct LlvmAr {
71 cmd: Command,
72}
73
74crate::macros::impl_common_helpers!(LlvmReadobj);
75crate::macros::impl_common_helpers!(LlvmProfdata);
76crate::macros::impl_common_helpers!(LlvmFilecheck);
77crate::macros::impl_common_helpers!(LlvmObjdump);
78crate::macros::impl_common_helpers!(LlvmAr);
79
80/// Generate the path to the bin directory of LLVM.
81#[must_use]
82pub fn llvm_bin_dir() -> PathBuf {
83 let llvm_bin_dir = env_var("LLVM_BIN_DIR");
84 PathBuf::from(llvm_bin_dir)
85}
86
87impl LlvmReadobj {
88 /// Construct a new `llvm-readobj` invocation with the `GNU` output style.
89 /// This assumes that `llvm-readobj` is available at `$LLVM_BIN_DIR/llvm-readobj`.
90 #[track_caller]
91 pub fn new() -> Self {
92 let llvm_readobj = llvm_bin_dir().join("llvm-readobj");
93 let cmd = Command::new(llvm_readobj);
94 let mut readobj = Self { cmd };
95 readobj.elf_output_style("GNU");
96 readobj
97 }
98
99 /// Specify the format of the ELF information.
100 ///
101 /// Valid options are `LLVM` (default), `GNU`, and `JSON`.
102 pub fn elf_output_style(&mut self, style: &str) -> &mut Self {
103 self.cmd.arg("--elf-output-style");
104 self.cmd.arg(style);
105 self
106 }
107
108 /// Provide an input file.
109 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
110 self.cmd.arg(path.as_ref());
111 self
112 }
113
114 /// Pass `--file-header` to display file headers.
115 pub fn file_header(&mut self) -> &mut Self {
116 self.cmd.arg("--file-header");
117 self
118 }
119
120 /// Pass `--program-headers` to display program headers.
121 pub fn program_headers(&mut self) -> &mut Self {
122 self.cmd.arg("--program-headers");
123 self
124 }
125
126 /// Pass `--symbols` to display the symbol.
127 pub fn symbols(&mut self) -> &mut Self {
128 self.cmd.arg("--symbols");
129 self
130 }
131
132 /// Pass `--dynamic-table` to display the dynamic symbol table.
133 pub fn dynamic_table(&mut self) -> &mut Self {
134 self.cmd.arg("--dynamic-table");
135 self
136 }
137
138 /// Specify the section to display.
139 pub fn section(&mut self, section: &str) -> &mut Self {
140 self.cmd.arg("--string-dump");
141 self.cmd.arg(section);
142 self
143 }
144}
145
146impl LlvmProfdata {
147 /// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available
148 /// at `$LLVM_BIN_DIR/llvm-profdata`.
149 #[track_caller]
150 pub fn new() -> Self {
151 let llvm_profdata = llvm_bin_dir().join("llvm-profdata");
152 let cmd = Command::new(llvm_profdata);
153 Self { cmd }
154 }
155
156 /// Provide an input file.
157 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
158 self.cmd.arg(path.as_ref());
159 self
160 }
161
162 /// Specify the output file path.
163 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
164 self.cmd.arg("-o");
165 self.cmd.arg(path.as_ref());
166 self
167 }
168
169 /// Take several profile data files generated by PGO instrumentation and merge them
170 /// together into a single indexed profile data file.
171 pub fn merge(&mut self) -> &mut Self {
172 self.cmd.arg("merge");
173 self
174 }
175}
176
177impl LlvmFilecheck {
178 /// Construct a new `llvm-filecheck` invocation. This assumes that `llvm-filecheck` is available
179 /// at `$LLVM_FILECHECK`.
180 #[track_caller]
181 pub fn new() -> Self {
182 let llvm_filecheck = env_var("LLVM_FILECHECK");
183 let cmd = Command::new(llvm_filecheck);
184 Self { cmd }
185 }
186
187 /// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call.
188 pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
189 self.cmd.stdin(input);
190 self
191 }
192
193 /// Provide the patterns that need to be matched.
194 pub fn patterns<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
195 self.cmd.arg(path.as_ref());
196 self
197 }
198
199 /// `--input-file` option.
200 pub fn input_file<P: AsRef<Path>>(&mut self, input_file: P) -> &mut Self {
201 self.cmd.arg("--input-file");
202 self.cmd.arg(input_file.as_ref());
203 self
204 }
205}
206
207impl LlvmObjdump {
208 /// Construct a new `llvm-objdump` invocation. This assumes that `llvm-objdump` is available
209 /// at `$LLVM_BIN_DIR/llvm-objdump`.
210 pub fn new() -> Self {
211 let llvm_objdump = llvm_bin_dir().join("llvm-objdump");
212 let cmd = Command::new(llvm_objdump);
213 Self { cmd }
214 }
215
216 /// Provide an input file.
217 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
218 self.cmd.arg(path.as_ref());
219 self
220 }
221}
222
223impl LlvmAr {
224 /// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available
225 /// at `$LLVM_BIN_DIR/llvm-ar`.
226 pub fn new() -> Self {
227 let llvm_ar = llvm_bin_dir().join("llvm-ar");
228 let cmd = Command::new(llvm_ar);
229 Self { cmd }
230 }
231
232 pub fn obj_to_ar(&mut self) -> &mut Self {
233 self.cmd.arg("rcus");
234 self
235 }
236
237 /// Provide an output, then an input file. Bundled in one function, as llvm-ar has
238 /// no "--output"-style flag.
239 pub fn output_input(&mut self, out: impl AsRef<Path>, input: impl AsRef<Path>) -> &mut Self {
240 self.cmd.arg(out.as_ref());
241 self.cmd.arg(input.as_ref());
242 self
243 }
244}
src/tools/run-make-support/src/external_deps/mod.rs created+14
......@@ -0,0 +1,14 @@
1//! This module contains external tool dependencies that we assume are available in the environment,
2//! such as `cc` or `python`.
3
4pub mod c_build;
5pub mod cc;
6pub mod clang;
7pub mod htmldocck;
8pub mod llvm;
9pub mod python;
10pub mod rustc;
11pub mod rustdoc;
12
13// Library-internal external dependency.
14mod cygpath;
src/tools/run-make-support/src/external_deps/python.rs created+11
......@@ -0,0 +1,11 @@
1use crate::command::Command;
2use crate::env::env_var;
3
4/// Obtain path of python as provided by the `PYTHON` environment variable. It is up to the caller
5/// to document and check if the python version is compatible with its intended usage.
6#[track_caller]
7#[must_use]
8pub fn python_command() -> Command {
9 let python_path = env_var("PYTHON");
10 Command::new(python_path)
11}
src/tools/run-make-support/src/external_deps/rustc.rs created+317
......@@ -0,0 +1,317 @@
1use std::ffi::{OsStr, OsString};
2use std::path::Path;
3
4use crate::command::Command;
5use crate::env::env_var;
6use crate::path_helpers::cwd;
7use crate::util::set_host_rpath;
8
9/// Construct a new `rustc` invocation. This will automatically set the library
10/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
11#[track_caller]
12pub fn rustc() -> Rustc {
13 Rustc::new()
14}
15
16/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_rpath`]
17/// still presets the environment variable `HOST_RPATH_DIR` by default.
18#[track_caller]
19pub fn bare_rustc() -> Rustc {
20 Rustc::bare()
21}
22
23/// Construct a new `rustc` aux-build invocation.
24#[track_caller]
25pub fn aux_build() -> Rustc {
26 Rustc::new_aux_build()
27}
28
29/// A `rustc` invocation builder.
30#[derive(Debug)]
31#[must_use]
32pub struct Rustc {
33 cmd: Command,
34}
35
36crate::macros::impl_common_helpers!(Rustc);
37
38#[track_caller]
39fn setup_common() -> Command {
40 let rustc = env_var("RUSTC");
41 let mut cmd = Command::new(rustc);
42 set_host_rpath(&mut cmd);
43 cmd
44}
45
46impl Rustc {
47 // `rustc` invocation constructor methods
48
49 /// Construct a new `rustc` invocation. This will automatically set the library
50 /// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
51 #[track_caller]
52 pub fn new() -> Self {
53 let mut cmd = setup_common();
54 cmd.arg("-L").arg(cwd());
55 Self { cmd }
56 }
57
58 /// Construct a bare `rustc` invocation with no flags set.
59 #[track_caller]
60 pub fn bare() -> Self {
61 let cmd = setup_common();
62 Self { cmd }
63 }
64
65 /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
66 #[track_caller]
67 pub fn new_aux_build() -> Self {
68 let mut cmd = setup_common();
69 cmd.arg("--crate-type=lib");
70 Self { cmd }
71 }
72
73 // Argument provider methods
74
75 /// Configure the compilation environment.
76 pub fn cfg(&mut self, s: &str) -> &mut Self {
77 self.cmd.arg("--cfg");
78 self.cmd.arg(s);
79 self
80 }
81
82 /// Specify default optimization level `-O` (alias for `-C opt-level=2`).
83 pub fn opt(&mut self) -> &mut Self {
84 self.cmd.arg("-O");
85 self
86 }
87
88 /// Specify a specific optimization level.
89 pub fn opt_level(&mut self, option: &str) -> &mut Self {
90 self.cmd.arg(format!("-Copt-level={option}"));
91 self
92 }
93
94 /// Incorporate a hashed string to mangled symbols.
95 pub fn metadata(&mut self, meta: &str) -> &mut Self {
96 self.cmd.arg(format!("-Cmetadata={meta}"));
97 self
98 }
99
100 /// Add a suffix in each output filename.
101 pub fn extra_filename(&mut self, suffix: &str) -> &mut Self {
102 self.cmd.arg(format!("-Cextra-filename={suffix}"));
103 self
104 }
105
106 /// Specify type(s) of output files to generate.
107 pub fn emit<S: AsRef<str>>(&mut self, kinds: S) -> &mut Self {
108 let kinds = kinds.as_ref();
109 self.cmd.arg(format!("--emit={kinds}"));
110 self
111 }
112
113 /// Specify where an external library is located.
114 pub fn extern_<P: AsRef<Path>>(&mut self, crate_name: &str, path: P) -> &mut Self {
115 assert!(
116 !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'),
117 "crate name cannot contain whitespace or path separators"
118 );
119
120 let path = path.as_ref().to_string_lossy();
121
122 self.cmd.arg("--extern");
123 self.cmd.arg(format!("{crate_name}={path}"));
124
125 self
126 }
127
128 /// Remap source path prefixes in all output.
129 pub fn remap_path_prefix<P: AsRef<Path>, P2: AsRef<Path>>(
130 &mut self,
131 from: P,
132 to: P2,
133 ) -> &mut Self {
134 let from = from.as_ref().to_string_lossy();
135 let to = to.as_ref().to_string_lossy();
136
137 self.cmd.arg("--remap-path-prefix");
138 self.cmd.arg(format!("{from}={to}"));
139
140 self
141 }
142
143 /// Specify path to the input file.
144 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
145 self.cmd.arg(path.as_ref());
146 self
147 }
148
149 //Adjust the backtrace level, displaying more detailed information at higher levels.
150 pub fn set_backtrace_level<R: AsRef<OsStr>>(&mut self, level: R) -> &mut Self {
151 self.cmd.env("RUST_BACKTRACE", level);
152 self
153 }
154
155 /// Specify path to the output file. Equivalent to `-o`` in rustc.
156 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
157 self.cmd.arg("-o");
158 self.cmd.arg(path.as_ref());
159 self
160 }
161
162 /// Specify path to the output directory. Equivalent to `--out-dir`` in rustc.
163 pub fn out_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
164 self.cmd.arg("--out-dir");
165 self.cmd.arg(path.as_ref());
166 self
167 }
168
169 /// This flag defers LTO optimizations to the linker.
170 pub fn linker_plugin_lto(&mut self, option: &str) -> &mut Self {
171 self.cmd.arg(format!("-Clinker-plugin-lto={option}"));
172 self
173 }
174
175 /// Specify what happens when the code panics.
176 pub fn panic(&mut self, option: &str) -> &mut Self {
177 self.cmd.arg(format!("-Cpanic={option}"));
178 self
179 }
180
181 /// Specify number of codegen units
182 pub fn codegen_units(&mut self, units: usize) -> &mut Self {
183 self.cmd.arg(format!("-Ccodegen-units={units}"));
184 self
185 }
186
187 /// Specify directory path used for incremental cache
188 pub fn incremental<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
189 let mut arg = OsString::new();
190 arg.push("-Cincremental=");
191 arg.push(path.as_ref());
192 self.cmd.arg(&arg);
193 self
194 }
195
196 /// Specify directory path used for profile generation
197 pub fn profile_generate<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
198 let mut arg = OsString::new();
199 arg.push("-Cprofile-generate=");
200 arg.push(path.as_ref());
201 self.cmd.arg(&arg);
202 self
203 }
204
205 /// Specify directory path used for profile usage
206 pub fn profile_use<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
207 let mut arg = OsString::new();
208 arg.push("-Cprofile-use=");
209 arg.push(path.as_ref());
210 self.cmd.arg(&arg);
211 self
212 }
213
214 /// Specify error format to use
215 pub fn error_format(&mut self, format: &str) -> &mut Self {
216 self.cmd.arg(format!("--error-format={format}"));
217 self
218 }
219
220 /// Specify json messages printed by the compiler
221 pub fn json(&mut self, items: &str) -> &mut Self {
222 self.cmd.arg(format!("--json={items}"));
223 self
224 }
225
226 /// Specify the target triple, or a path to a custom target json spec file.
227 pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
228 let target = target.as_ref();
229 self.cmd.arg(format!("--target={target}"));
230 self
231 }
232
233 /// Specify the crate type.
234 pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
235 self.cmd.arg("--crate-type");
236 self.cmd.arg(crate_type);
237 self
238 }
239
240 /// Add a directory to the library search path. Equivalent to `-L` in rustc.
241 pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
242 self.cmd.arg("-L");
243 self.cmd.arg(path.as_ref());
244 self
245 }
246
247 /// Add a directory to the library search path with a restriction, where `kind` is a dependency
248 /// type. Equivalent to `-L KIND=PATH` in rustc.
249 pub fn specific_library_search_path<P: AsRef<Path>>(
250 &mut self,
251 kind: &str,
252 path: P,
253 ) -> &mut Self {
254 assert!(["dependency", "native", "all", "framework", "crate"].contains(&kind));
255 let path = path.as_ref().to_string_lossy();
256 self.cmd.arg(format!("-L{kind}={path}"));
257 self
258 }
259
260 /// Override the system root. Equivalent to `--sysroot` in rustc.
261 pub fn sysroot<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
262 self.cmd.arg("--sysroot");
263 self.cmd.arg(path.as_ref());
264 self
265 }
266
267 /// Specify the edition year.
268 pub fn edition(&mut self, edition: &str) -> &mut Self {
269 self.cmd.arg("--edition");
270 self.cmd.arg(edition);
271 self
272 }
273
274 /// Specify the print request.
275 pub fn print(&mut self, request: &str) -> &mut Self {
276 self.cmd.arg("--print");
277 self.cmd.arg(request);
278 self
279 }
280
281 /// Add an extra argument to the linker invocation, via `-Clink-arg`.
282 pub fn link_arg(&mut self, link_arg: &str) -> &mut Self {
283 self.cmd.arg(format!("-Clink-arg={link_arg}"));
284 self
285 }
286
287 /// Add multiple extra arguments to the linker invocation, via `-Clink-args`.
288 pub fn link_args(&mut self, link_args: &str) -> &mut Self {
289 self.cmd.arg(format!("-Clink-args={link_args}"));
290 self
291 }
292
293 /// Specify a stdin input
294 pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
295 self.cmd.stdin(input);
296 self
297 }
298
299 /// Specify the crate name.
300 pub fn crate_name<S: AsRef<OsStr>>(&mut self, name: S) -> &mut Self {
301 self.cmd.arg("--crate-name");
302 self.cmd.arg(name.as_ref());
303 self
304 }
305
306 /// Specify the linker
307 pub fn linker(&mut self, linker: &str) -> &mut Self {
308 self.cmd.arg(format!("-Clinker={linker}"));
309 self
310 }
311
312 /// Specify the linker flavor
313 pub fn linker_flavor(&mut self, linker_flavor: &str) -> &mut Self {
314 self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
315 self
316 }
317}
src/tools/run-make-support/src/external_deps/rustdoc.rs created+142
......@@ -0,0 +1,142 @@
1use std::ffi::OsStr;
2use std::path::Path;
3
4use crate::command::Command;
5use crate::env::{env_var, env_var_os};
6use crate::util::set_host_rpath;
7
8/// Construct a plain `rustdoc` invocation with no flags set.
9#[track_caller]
10pub fn bare_rustdoc() -> Rustdoc {
11 Rustdoc::bare()
12}
13
14/// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
15#[track_caller]
16pub fn rustdoc() -> Rustdoc {
17 Rustdoc::new()
18}
19
20#[derive(Debug)]
21#[must_use]
22pub struct Rustdoc {
23 cmd: Command,
24}
25
26crate::macros::impl_common_helpers!(Rustdoc);
27
28#[track_caller]
29fn setup_common() -> Command {
30 let rustdoc = env_var("RUSTDOC");
31 let mut cmd = Command::new(rustdoc);
32 set_host_rpath(&mut cmd);
33 cmd
34}
35
36impl Rustdoc {
37 /// Construct a bare `rustdoc` invocation.
38 #[track_caller]
39 pub fn bare() -> Self {
40 let cmd = setup_common();
41 Self { cmd }
42 }
43
44 /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
45 #[track_caller]
46 pub fn new() -> Self {
47 let mut cmd = setup_common();
48 let target_rpath_dir = env_var_os("TARGET_RPATH_DIR");
49 cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
50 Self { cmd }
51 }
52
53 /// Specify where an external library is located.
54 pub fn extern_<P: AsRef<Path>>(&mut self, crate_name: &str, path: P) -> &mut Self {
55 assert!(
56 !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'),
57 "crate name cannot contain whitespace or path separators"
58 );
59
60 let path = path.as_ref().to_string_lossy();
61
62 self.cmd.arg("--extern");
63 self.cmd.arg(format!("{crate_name}={path}"));
64
65 self
66 }
67
68 /// Specify path to the input file.
69 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
70 self.cmd.arg(path.as_ref());
71 self
72 }
73
74 /// Specify path to the output folder.
75 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
76 self.cmd.arg("-o");
77 self.cmd.arg(path.as_ref());
78 self
79 }
80
81 /// Specify output directory.
82 pub fn out_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
83 self.cmd.arg("--out-dir").arg(path.as_ref());
84 self
85 }
86
87 /// Given a `path`, pass `@{path}` to `rustdoc` as an
88 /// [arg file](https://doc.rust-lang.org/rustdoc/command-line-arguments.html#path-load-command-line-flags-from-a-path).
89 pub fn arg_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
90 self.cmd.arg(format!("@{}", path.as_ref().display()));
91 self
92 }
93
94 /// Specify a stdin input
95 pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
96 self.cmd.stdin(input);
97 self
98 }
99
100 /// Specify the edition year.
101 pub fn edition(&mut self, edition: &str) -> &mut Self {
102 self.cmd.arg("--edition");
103 self.cmd.arg(edition);
104 self
105 }
106
107 /// Specify the target triple, or a path to a custom target json spec file.
108 pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
109 let target = target.as_ref();
110 self.cmd.arg(format!("--target={target}"));
111 self
112 }
113
114 /// Specify the crate type.
115 pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
116 self.cmd.arg("--crate-type");
117 self.cmd.arg(crate_type);
118 self
119 }
120
121 /// Specify the crate name.
122 pub fn crate_name<S: AsRef<OsStr>>(&mut self, name: S) -> &mut Self {
123 self.cmd.arg("--crate-name");
124 self.cmd.arg(name.as_ref());
125 self
126 }
127
128 /// Add a directory to the library search path. It corresponds to the `-L`
129 /// rustdoc option.
130 pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
131 self.cmd.arg("-L");
132 self.cmd.arg(path.as_ref());
133 self
134 }
135
136 /// Specify the output format.
137 pub fn output_format(&mut self, format: &str) -> &mut Self {
138 self.cmd.arg("--output-format");
139 self.cmd.arg(format);
140 self
141 }
142}
src/tools/run-make-support/src/fs.rs created+178
......@@ -0,0 +1,178 @@
1use std::io;
2use std::path::Path;
3
4// FIXME(jieyouxu): modify create_symlink to panic on windows.
5
6/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
7#[cfg(target_family = "windows")]
8pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
9 if link.as_ref().exists() {
10 std::fs::remove_dir(link.as_ref()).unwrap();
11 }
12 std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
13 "failed to create symlink {:?} for {:?}",
14 link.as_ref().display(),
15 original.as_ref().display(),
16 ));
17}
18
19/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
20#[cfg(target_family = "unix")]
21pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
22 if link.as_ref().exists() {
23 std::fs::remove_dir(link.as_ref()).unwrap();
24 }
25 std::os::unix::fs::symlink(original.as_ref(), link.as_ref()).expect(&format!(
26 "failed to create symlink {:?} for {:?}",
27 link.as_ref().display(),
28 original.as_ref().display(),
29 ));
30}
31
32/// Copy a directory into another.
33pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
34 fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
35 let dst = dst.as_ref();
36 if !dst.is_dir() {
37 std::fs::create_dir_all(&dst)?;
38 }
39 for entry in std::fs::read_dir(src)? {
40 let entry = entry?;
41 let ty = entry.file_type()?;
42 if ty.is_dir() {
43 copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
44 } else {
45 std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
46 }
47 }
48 Ok(())
49 }
50
51 if let Err(e) = copy_dir_all_inner(&src, &dst) {
52 // Trying to give more context about what exactly caused the failure
53 panic!(
54 "failed to copy `{}` to `{}`: {:?}",
55 src.as_ref().display(),
56 dst.as_ref().display(),
57 e
58 );
59 }
60}
61
62/// Helper for reading entries in a given directory.
63pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F) {
64 for entry in read_dir(dir) {
65 callback(&entry.unwrap().path());
66 }
67}
68
69/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.
70#[track_caller]
71pub fn remove_file<P: AsRef<Path>>(path: P) {
72 std::fs::remove_file(path.as_ref())
73 .expect(&format!("the file in path \"{}\" could not be removed", path.as_ref().display()));
74}
75
76/// A wrapper around [`std::fs::copy`] which includes the file path in the panic message.
77#[track_caller]
78pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
79 std::fs::copy(from.as_ref(), to.as_ref()).expect(&format!(
80 "the file \"{}\" could not be copied over to \"{}\"",
81 from.as_ref().display(),
82 to.as_ref().display(),
83 ));
84}
85
86/// A wrapper around [`std::fs::File::create`] which includes the file path in the panic message.
87#[track_caller]
88pub fn create_file<P: AsRef<Path>>(path: P) {
89 std::fs::File::create(path.as_ref())
90 .expect(&format!("the file in path \"{}\" could not be created", path.as_ref().display()));
91}
92
93/// A wrapper around [`std::fs::read`] which includes the file path in the panic message.
94#[track_caller]
95pub fn read<P: AsRef<Path>>(path: P) -> Vec<u8> {
96 std::fs::read(path.as_ref())
97 .expect(&format!("the file in path \"{}\" could not be read", path.as_ref().display()))
98}
99
100/// A wrapper around [`std::fs::read_to_string`] which includes the file path in the panic message.
101#[track_caller]
102pub fn read_to_string<P: AsRef<Path>>(path: P) -> String {
103 std::fs::read_to_string(path.as_ref()).expect(&format!(
104 "the file in path \"{}\" could not be read into a String",
105 path.as_ref().display()
106 ))
107}
108
109/// A wrapper around [`std::fs::read_dir`] which includes the file path in the panic message.
110#[track_caller]
111pub fn read_dir<P: AsRef<Path>>(path: P) -> std::fs::ReadDir {
112 std::fs::read_dir(path.as_ref())
113 .expect(&format!("the directory in path \"{}\" could not be read", path.as_ref().display()))
114}
115
116/// A wrapper around [`std::fs::write`] which includes the file path in the panic message.
117#[track_caller]
118pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) {
119 std::fs::write(path.as_ref(), contents.as_ref()).expect(&format!(
120 "the file in path \"{}\" could not be written to",
121 path.as_ref().display()
122 ));
123}
124
125/// A wrapper around [`std::fs::remove_dir_all`] which includes the file path in the panic message.
126#[track_caller]
127pub fn remove_dir_all<P: AsRef<Path>>(path: P) {
128 std::fs::remove_dir_all(path.as_ref()).expect(&format!(
129 "the directory in path \"{}\" could not be removed alongside all its contents",
130 path.as_ref().display(),
131 ));
132}
133
134/// A wrapper around [`std::fs::create_dir`] which includes the file path in the panic message.
135#[track_caller]
136pub fn create_dir<P: AsRef<Path>>(path: P) {
137 std::fs::create_dir(path.as_ref()).expect(&format!(
138 "the directory in path \"{}\" could not be created",
139 path.as_ref().display()
140 ));
141}
142
143/// A wrapper around [`std::fs::create_dir_all`] which includes the file path in the panic message.
144#[track_caller]
145pub fn create_dir_all<P: AsRef<Path>>(path: P) {
146 std::fs::create_dir_all(path.as_ref()).expect(&format!(
147 "the directory (and all its parents) in path \"{}\" could not be created",
148 path.as_ref().display()
149 ));
150}
151
152/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message.
153#[track_caller]
154pub fn metadata<P: AsRef<Path>>(path: P) -> std::fs::Metadata {
155 std::fs::metadata(path.as_ref()).expect(&format!(
156 "the file's metadata in path \"{}\" could not be read",
157 path.as_ref().display()
158 ))
159}
160
161/// A wrapper around [`std::fs::rename`] which includes the file path in the panic message.
162#[track_caller]
163pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
164 std::fs::rename(from.as_ref(), to.as_ref()).expect(&format!(
165 "the file \"{}\" could not be moved over to \"{}\"",
166 from.as_ref().display(),
167 to.as_ref().display(),
168 ));
169}
170
171/// A wrapper around [`std::fs::set_permissions`] which includes the file path in the panic message.
172#[track_caller]
173pub fn set_permissions<P: AsRef<Path>>(path: P, perm: std::fs::Permissions) {
174 std::fs::set_permissions(path.as_ref(), perm).expect(&format!(
175 "the file's permissions in path \"{}\" could not be changed",
176 path.as_ref().display()
177 ));
178}
src/tools/run-make-support/src/fs_wrapper.rs deleted-113
......@@ -1,113 +0,0 @@
1use std::fs;
2use std::path::Path;
3
4/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.
5#[track_caller]
6pub fn remove_file<P: AsRef<Path>>(path: P) {
7 fs::remove_file(path.as_ref())
8 .expect(&format!("the file in path \"{}\" could not be removed", path.as_ref().display()));
9}
10
11/// A wrapper around [`std::fs::copy`] which includes the file path in the panic message.
12#[track_caller]
13pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
14 fs::copy(from.as_ref(), to.as_ref()).expect(&format!(
15 "the file \"{}\" could not be copied over to \"{}\"",
16 from.as_ref().display(),
17 to.as_ref().display(),
18 ));
19}
20
21/// A wrapper around [`std::fs::File::create`] which includes the file path in the panic message.
22#[track_caller]
23pub fn create_file<P: AsRef<Path>>(path: P) {
24 fs::File::create(path.as_ref())
25 .expect(&format!("the file in path \"{}\" could not be created", path.as_ref().display()));
26}
27
28/// A wrapper around [`std::fs::read`] which includes the file path in the panic message.
29#[track_caller]
30pub fn read<P: AsRef<Path>>(path: P) -> Vec<u8> {
31 fs::read(path.as_ref())
32 .expect(&format!("the file in path \"{}\" could not be read", path.as_ref().display()))
33}
34
35/// A wrapper around [`std::fs::read_to_string`] which includes the file path in the panic message.
36#[track_caller]
37pub fn read_to_string<P: AsRef<Path>>(path: P) -> String {
38 fs::read_to_string(path.as_ref()).expect(&format!(
39 "the file in path \"{}\" could not be read into a String",
40 path.as_ref().display()
41 ))
42}
43
44/// A wrapper around [`std::fs::read_dir`] which includes the file path in the panic message.
45#[track_caller]
46pub fn read_dir<P: AsRef<Path>>(path: P) -> fs::ReadDir {
47 fs::read_dir(path.as_ref())
48 .expect(&format!("the directory in path \"{}\" could not be read", path.as_ref().display()))
49}
50
51/// A wrapper around [`std::fs::write`] which includes the file path in the panic message.
52#[track_caller]
53pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) {
54 fs::write(path.as_ref(), contents.as_ref()).expect(&format!(
55 "the file in path \"{}\" could not be written to",
56 path.as_ref().display()
57 ));
58}
59
60/// A wrapper around [`std::fs::remove_dir_all`] which includes the file path in the panic message.
61#[track_caller]
62pub fn remove_dir_all<P: AsRef<Path>>(path: P) {
63 fs::remove_dir_all(path.as_ref()).expect(&format!(
64 "the directory in path \"{}\" could not be removed alongside all its contents",
65 path.as_ref().display(),
66 ));
67}
68
69/// A wrapper around [`std::fs::create_dir`] which includes the file path in the panic message.
70#[track_caller]
71pub fn create_dir<P: AsRef<Path>>(path: P) {
72 fs::create_dir(path.as_ref()).expect(&format!(
73 "the directory in path \"{}\" could not be created",
74 path.as_ref().display()
75 ));
76}
77
78/// A wrapper around [`std::fs::create_dir_all`] which includes the file path in the panic message.
79#[track_caller]
80pub fn create_dir_all<P: AsRef<Path>>(path: P) {
81 fs::create_dir_all(path.as_ref()).expect(&format!(
82 "the directory (and all its parents) in path \"{}\" could not be created",
83 path.as_ref().display()
84 ));
85}
86
87/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message.
88#[track_caller]
89pub fn metadata<P: AsRef<Path>>(path: P) -> fs::Metadata {
90 fs::metadata(path.as_ref()).expect(&format!(
91 "the file's metadata in path \"{}\" could not be read",
92 path.as_ref().display()
93 ))
94}
95
96/// A wrapper around [`std::fs::rename`] which includes the file path in the panic message.
97#[track_caller]
98pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
99 fs::rename(from.as_ref(), to.as_ref()).expect(&format!(
100 "the file \"{}\" could not be moved over to \"{}\"",
101 from.as_ref().display(),
102 to.as_ref().display(),
103 ));
104}
105
106/// A wrapper around [`std::fs::set_permissions`] which includes the file path in the panic message.
107#[track_caller]
108pub fn set_permissions<P: AsRef<Path>>(path: P, perm: fs::Permissions) {
109 fs::set_permissions(path.as_ref(), perm).expect(&format!(
110 "the file's permissions in path \"{}\" could not be changed",
111 path.as_ref().display()
112 ));
113}
src/tools/run-make-support/src/lib.rs+52-619
......@@ -3,651 +3,84 @@
33//! notably is built via cargo: this means that if your test wants some non-trivial utility, such
44//! as `object` or `wasmparser`, they can be re-exported and be made available through this library.
55
6pub mod cc;
7pub mod clang;
86mod command;
7mod macros;
8mod util;
9
10pub mod artifact_names;
11pub mod assertion_helpers;
912pub mod diff;
10pub mod fs_wrapper;
11pub mod llvm;
13pub mod env;
14pub mod external_deps;
15pub mod path_helpers;
1216pub mod run;
13pub mod rustc;
14pub mod rustdoc;
17pub mod scoped_run;
18pub mod string;
19pub mod targets;
20
21mod fs;
1522
16use std::env;
17use std::ffi::OsString;
18use std::fs;
19use std::io;
20use std::panic;
21use std::path::{Path, PathBuf};
23/// [`std::fs`] wrappers and assorted filesystem-related helpers. Public to tests as `rfs` to not be
24/// confused with [`std::fs`].
25pub mod rfs {
26 pub use crate::fs::*;
27}
2228
29// Re-exports of third-party library crates.
2330pub use bstr;
2431pub use gimli;
2532pub use object;
2633pub use regex;
2734pub use wasmparser;
2835
36// Re-exports of external dependencies.
37pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
38
39// These rely on external dependencies.
40pub use c_build::build_native_static_lib;
2941pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
3042pub use clang::{clang, Clang};
31pub use diff::{diff, Diff};
43pub use htmldocck::htmldocck;
3244pub use llvm::{
3345 llvm_ar, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmFilecheck,
3446 LlvmObjdump, LlvmProfdata, LlvmReadobj,
3547};
36pub use run::{cmd, run, run_fail, run_with_args};
48pub use python::python_command;
3749pub use rustc::{aux_build, bare_rustc, rustc, Rustc};
3850pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
3951
40#[track_caller]
41#[must_use]
42pub fn env_var(name: &str) -> String {
43 match env::var(name) {
44 Ok(v) => v,
45 Err(err) => panic!("failed to retrieve environment variable {name:?}: {err:?}"),
46 }
47}
48
49#[track_caller]
50#[must_use]
51pub fn env_var_os(name: &str) -> OsString {
52 match env::var_os(name) {
53 Some(v) => v,
54 None => panic!("failed to retrieve environment variable {name:?}"),
55 }
56}
57
58/// `TARGET`
59#[must_use]
60pub fn target() -> String {
61 env_var("TARGET")
62}
63
64/// Check if target is windows-like.
65#[must_use]
66pub fn is_windows() -> bool {
67 target().contains("windows")
68}
69
70/// Check if target uses msvc.
71#[must_use]
72pub fn is_msvc() -> bool {
73 target().contains("msvc")
74}
75
76/// Check if target uses macOS.
77#[must_use]
78pub fn is_darwin() -> bool {
79 target().contains("darwin")
80}
81
82#[track_caller]
83#[must_use]
84pub fn python_command() -> Command {
85 let python_path = env_var("PYTHON");
86 Command::new(python_path)
87}
88
89#[track_caller]
90#[must_use]
91pub fn htmldocck() -> Command {
92 let mut python = python_command();
93 python.arg(source_root().join("src/etc/htmldocck.py"));
94 python
95}
96
97/// Returns the path for a local test file.
98pub fn path<P: AsRef<Path>>(p: P) -> PathBuf {
99 cwd().join(p.as_ref())
100}
101
102/// Path to the root rust-lang/rust source checkout.
103#[must_use]
104pub fn source_root() -> PathBuf {
105 env_var("SOURCE_ROOT").into()
106}
107
108/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
109#[cfg(target_family = "windows")]
110pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
111 if link.as_ref().exists() {
112 std::fs::remove_dir(link.as_ref()).unwrap();
113 }
114 use std::os::windows::fs;
115 fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
116 "failed to create symlink {:?} for {:?}",
117 link.as_ref().display(),
118 original.as_ref().display(),
119 ));
120}
121
122/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
123#[cfg(target_family = "unix")]
124pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
125 if link.as_ref().exists() {
126 std::fs::remove_dir(link.as_ref()).unwrap();
127 }
128 use std::os::unix::fs;
129 fs::symlink(original.as_ref(), link.as_ref()).expect(&format!(
130 "failed to create symlink {:?} for {:?}",
131 link.as_ref().display(),
132 original.as_ref().display(),
133 ));
134}
135
136/// Construct the static library name based on the platform.
137#[must_use]
138pub fn static_lib_name(name: &str) -> String {
139 // See tools.mk (irrelevant lines omitted):
140 //
141 // ```makefile
142 // ifeq ($(UNAME),Darwin)
143 // STATICLIB = $(TMPDIR)/lib$(1).a
144 // else
145 // ifdef IS_WINDOWS
146 // ifdef IS_MSVC
147 // STATICLIB = $(TMPDIR)/$(1).lib
148 // else
149 // STATICLIB = $(TMPDIR)/lib$(1).a
150 // endif
151 // else
152 // STATICLIB = $(TMPDIR)/lib$(1).a
153 // endif
154 // endif
155 // ```
156 assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
157
158 if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
159}
160
161/// Construct the dynamic library name based on the platform.
162#[must_use]
163pub fn dynamic_lib_name(name: &str) -> String {
164 // See tools.mk (irrelevant lines omitted):
165 //
166 // ```makefile
167 // ifeq ($(UNAME),Darwin)
168 // DYLIB = $(TMPDIR)/lib$(1).dylib
169 // else
170 // ifdef IS_WINDOWS
171 // DYLIB = $(TMPDIR)/$(1).dll
172 // else
173 // DYLIB = $(TMPDIR)/lib$(1).so
174 // endif
175 // endif
176 // ```
177 assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
178
179 let extension = dynamic_lib_extension();
180 if is_darwin() {
181 format!("lib{name}.{extension}")
182 } else if is_windows() {
183 format!("{name}.{extension}")
184 } else {
185 format!("lib{name}.{extension}")
186 }
187}
188
189#[must_use]
190pub fn dynamic_lib_extension() -> &'static str {
191 if is_darwin() {
192 "dylib"
193 } else if is_windows() {
194 "dll"
195 } else {
196 "so"
197 }
198}
199
200/// Generate the name a rust library (rlib) would have.
201#[must_use]
202pub fn rust_lib_name(name: &str) -> String {
203 format!("lib{name}.rlib")
204}
205
206/// Construct the binary name based on platform.
207#[must_use]
208pub fn bin_name(name: &str) -> String {
209 if is_windows() { format!("{name}.exe") } else { name.to_string() }
210}
211
212/// Return the current working directory.
213#[must_use]
214pub fn cwd() -> PathBuf {
215 env::current_dir().unwrap()
216}
217
218// FIXME(Oneirical): This will no longer be required after compiletest receives the ability
219// to manipulate read-only files. See https://github.com/rust-lang/rust/issues/126334
220/// Ensure that the path P is read-only while the test runs, and restore original permissions
221/// at the end so compiletest can clean up.
222/// This will panic on Windows if the path is a directory (as it would otherwise do nothing)
223#[track_caller]
224pub fn test_while_readonly<P: AsRef<Path>, F: FnOnce() + std::panic::UnwindSafe>(
225 path: P,
226 closure: F,
227) {
228 let path = path.as_ref();
229 if is_windows() && path.is_dir() {
230 eprintln!("This helper function cannot be used on Windows to make directories readonly.");
231 eprintln!(
232 "See the official documentation:
233 https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.set_readonly"
234 );
235 panic!("`test_while_readonly` on directory detected while on Windows.");
236 }
237 let metadata = fs_wrapper::metadata(&path);
238 let original_perms = metadata.permissions();
239
240 let mut new_perms = original_perms.clone();
241 new_perms.set_readonly(true);
242 fs_wrapper::set_permissions(&path, new_perms);
243
244 let success = std::panic::catch_unwind(closure);
245
246 fs_wrapper::set_permissions(&path, original_perms);
247 success.unwrap();
248}
249
250/// Browse the directory `path` non-recursively and return all files which respect the parameters
251/// outlined by `closure`.
252#[track_caller]
253pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
254 path: P,
255 filter: F,
256) -> Vec<PathBuf> {
257 let mut matching_files = Vec::new();
258 for entry in fs_wrapper::read_dir(path) {
259 let entry = entry.expect("failed to read directory entry.");
260 let path = entry.path();
261
262 if path.is_file() && filter(&path) {
263 matching_files.push(path);
264 }
265 }
266 matching_files
267}
268
269/// Returns true if the filename at `path` starts with `prefix`.
270pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
271 path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
272}
273
274/// Returns true if the filename at `path` has the extension `extension`.
275pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
276 path.as_ref().extension().is_some_and(|ext| ext == extension)
277}
278
279/// Returns true if the filename at `path` does not contain `expected`.
280pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
281 !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
282}
283
284/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
285#[track_caller]
286pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
287 let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
288 let src = format!("{lib_name}.c");
289 let lib_path = static_lib_name(lib_name);
290 if is_msvc() {
291 cc().arg("-c").out_exe(&obj_file).input(src).run();
292 } else {
293 cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
294 };
295 let obj_file = if is_msvc() {
296 PathBuf::from(format!("{lib_name}.obj"))
297 } else {
298 PathBuf::from(format!("{lib_name}.o"))
299 };
300 llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
301 path(lib_path)
302}
303
304/// Returns true if the filename at `path` is not in `expected`.
305pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
306 let expected = expected.as_ref();
307 path.as_ref()
308 .file_name()
309 .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
310}
311
312/// Returns true if the filename at `path` ends with `suffix`.
313pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
314 path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
315}
316
317/// Gathers all files in the current working directory that have the extension `ext`, and counts
318/// the number of lines within that contain a match with the regex pattern `re`.
319pub fn count_regex_matches_in_files_with_extension(re: &regex::Regex, ext: &str) -> usize {
320 let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
321
322 let mut count = 0;
323 for file in fetched_files {
324 let content = fs_wrapper::read_to_string(file);
325 count += content.lines().filter(|line| re.is_match(&line)).count();
326 }
327
328 count
329}
330
331/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
332/// available on the platform!
333#[track_caller]
334#[must_use]
335pub fn cygpath_windows<P: AsRef<Path>>(path: P) -> String {
336 let caller = panic::Location::caller();
337 let mut cygpath = Command::new("cygpath");
338 cygpath.arg("-w");
339 cygpath.arg(path.as_ref());
340 let output = cygpath.run();
341 if !output.status().success() {
342 handle_failed_output(&cygpath, output, caller.line());
343 }
344 // cygpath -w can attach a newline
345 output.stdout_utf8().trim().to_string()
346}
347
348/// Run `uname`. This assumes that `uname` is available on the platform!
349#[track_caller]
350#[must_use]
351pub fn uname() -> String {
352 let caller = panic::Location::caller();
353 let mut uname = Command::new("uname");
354 let output = uname.run();
355 if !output.status().success() {
356 handle_failed_output(&uname, output, caller.line());
357 }
358 output.stdout_utf8()
359}
360
361fn handle_failed_output(cmd: &Command, output: CompletedProcess, caller_line_number: u32) -> ! {
362 if output.status().success() {
363 eprintln!("command unexpectedly succeeded at line {caller_line_number}");
364 } else {
365 eprintln!("command failed at line {caller_line_number}");
366 }
367 eprintln!("{cmd:?}");
368 eprintln!("output status: `{}`", output.status());
369 eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8());
370 eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8());
371 std::process::exit(1)
372}
373
374/// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
375pub fn set_host_rpath(cmd: &mut Command) {
376 let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
377 cmd.env(&ld_lib_path_envvar, {
378 let mut paths = vec![];
379 paths.push(cwd());
380 paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
381 for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
382 paths.push(p.to_path_buf());
383 }
384 env::join_paths(paths.iter()).unwrap()
385 });
386}
387
388/// Read the contents of a file that cannot simply be read by
389/// read_to_string, due to invalid utf8 data, then assert that it contains `expected`.
390#[track_caller]
391pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
392 let buffer = fs_wrapper::read(path.as_ref());
393 let expected = expected.as_ref();
394 if !String::from_utf8_lossy(&buffer).contains(expected) {
395 eprintln!("=== FILE CONTENTS (LOSSY) ===");
396 eprintln!("{}", String::from_utf8_lossy(&buffer));
397 eprintln!("=== SPECIFIED TEXT ===");
398 eprintln!("{}", expected);
399 panic!("specified text was not found in file");
400 }
401}
402
403/// Read the contents of a file that cannot simply be read by
404/// read_to_string, due to invalid utf8 data, then assert that it does not contain `expected`.
405#[track_caller]
406pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
407 let buffer = fs_wrapper::read(path.as_ref());
408 let expected = expected.as_ref();
409 if String::from_utf8_lossy(&buffer).contains(expected) {
410 eprintln!("=== FILE CONTENTS (LOSSY) ===");
411 eprintln!("{}", String::from_utf8_lossy(&buffer));
412 eprintln!("=== SPECIFIED TEXT ===");
413 eprintln!("{}", expected);
414 panic!("specified text was unexpectedly found in file");
415 }
416}
417
418/// Copy a directory into another.
419pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
420 fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
421 let dst = dst.as_ref();
422 if !dst.is_dir() {
423 std::fs::create_dir_all(&dst)?;
424 }
425 for entry in std::fs::read_dir(src)? {
426 let entry = entry?;
427 let ty = entry.file_type()?;
428 if ty.is_dir() {
429 copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
430 } else {
431 std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
432 }
433 }
434 Ok(())
435 }
436
437 if let Err(e) = copy_dir_all_inner(&src, &dst) {
438 // Trying to give more context about what exactly caused the failure
439 panic!(
440 "failed to copy `{}` to `{}`: {:?}",
441 src.as_ref().display(),
442 dst.as_ref().display(),
443 e
444 );
445 }
446}
447
448/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
449pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
450 let dir2 = dir2.as_ref();
451 read_dir(dir1, |entry_path| {
452 let entry_name = entry_path.file_name().unwrap();
453 if entry_path.is_dir() {
454 recursive_diff(&entry_path, &dir2.join(entry_name));
455 } else {
456 let path2 = dir2.join(entry_name);
457 let file1 = fs_wrapper::read(&entry_path);
458 let file2 = fs_wrapper::read(&path2);
459
460 // We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
461 // Why not using String? Because there might be minified files or even potentially
462 // binary ones, so that would display useless output.
463 assert!(
464 file1 == file2,
465 "`{}` and `{}` have different content",
466 entry_path.display(),
467 path2.display(),
468 );
469 }
470 });
471}
472
473pub fn read_dir<F: FnMut(&Path)>(dir: impl AsRef<Path>, mut callback: F) {
474 for entry in fs_wrapper::read_dir(dir) {
475 callback(&entry.unwrap().path());
476 }
477}
478
479/// Check that `actual` is equal to `expected`. Panic otherwise.
480#[track_caller]
481pub fn assert_equals<S1: AsRef<str>, S2: AsRef<str>>(actual: S1, expected: S2) {
482 let actual = actual.as_ref();
483 let expected = expected.as_ref();
484 if actual != expected {
485 eprintln!("=== ACTUAL TEXT ===");
486 eprintln!("{}", actual);
487 eprintln!("=== EXPECTED ===");
488 eprintln!("{}", expected);
489 panic!("expected text was not found in actual text");
490 }
491}
492
493/// Check that `haystack` contains `needle`. Panic otherwise.
494#[track_caller]
495pub fn assert_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
496 let haystack = haystack.as_ref();
497 let needle = needle.as_ref();
498 if !haystack.contains(needle) {
499 eprintln!("=== HAYSTACK ===");
500 eprintln!("{}", haystack);
501 eprintln!("=== NEEDLE ===");
502 eprintln!("{}", needle);
503 panic!("needle was not found in haystack");
504 }
505}
506
507/// Check that `haystack` does not contain `needle`. Panic otherwise.
508#[track_caller]
509pub fn assert_not_contains<S1: AsRef<str>, S2: AsRef<str>>(haystack: S1, needle: S2) {
510 let haystack = haystack.as_ref();
511 let needle = needle.as_ref();
512 if haystack.contains(needle) {
513 eprintln!("=== HAYSTACK ===");
514 eprintln!("{}", haystack);
515 eprintln!("=== NEEDLE ===");
516 eprintln!("{}", needle);
517 panic!("needle was unexpectedly found in haystack");
518 }
519}
520
521/// This function is designed for running commands in a temporary directory
522/// that is cleared after the function ends.
52/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
52353///
524/// What this function does:
525/// 1) Creates a temporary directory (`tmpdir`)
526/// 2) Copies all files from the current directory to `tmpdir`
527/// 3) Changes the current working directory to `tmpdir`
528/// 4) Calls `callback`
529/// 5) Switches working directory back to the original one
530/// 6) Removes `tmpdir`
531pub fn run_in_tmpdir<F: FnOnce()>(callback: F) {
532 let original_dir = cwd();
533 let tmpdir = original_dir.join("../temporary-directory");
534 copy_dir_all(".", &tmpdir);
535
536 env::set_current_dir(&tmpdir).unwrap();
537 callback();
538 env::set_current_dir(original_dir).unwrap();
539 fs::remove_dir_all(tmpdir).unwrap();
540}
541
542/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
543/// containing a `cmd: Command` field. The provided helpers are:
544///
545/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
546/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
547/// new specific helper methods over relying on these generic argument providers.
548/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
549/// methods of the same name on [`Command`].
550/// 3. Output and execution: `run` and `run_fail` are provided. These are
551/// higher-level convenience methods which wait for the command to finish running and assert
552/// that the command successfully ran or failed as expected. They return
553/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed
554/// process.
555///
556/// Example usage:
557///
558/// ```ignore (illustrative)
559/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
560///
561/// crate::impl_common_helpers!(CommandWrapper);
562///
563/// impl CommandWrapper {
564/// // ... additional specific helper methods
565/// }
566/// ```
567macro_rules! impl_common_helpers {
568 ($wrapper: ident) => {
569 impl $wrapper {
570 /// Specify an environment variable.
571 pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
572 where
573 K: AsRef<::std::ffi::OsStr>,
574 V: AsRef<::std::ffi::OsStr>,
575 {
576 self.cmd.env(key, value);
577 self
578 }
579
580 /// Remove an environmental variable.
581 pub fn env_remove<K>(&mut self, key: K) -> &mut Self
582 where
583 K: AsRef<::std::ffi::OsStr>,
584 {
585 self.cmd.env_remove(key);
586 self
587 }
54/// [similar]: https://github.com/mitsuhiko/similar
55pub use diff::{diff, Diff};
58856
589 /// Generic command argument provider. Prefer specific helper methods if possible.
590 /// Note that for some executables, arguments might be platform specific. For C/C++
591 /// compilers, arguments might be platform *and* compiler specific.
592 pub fn arg<S>(&mut self, arg: S) -> &mut Self
593 where
594 S: AsRef<::std::ffi::OsStr>,
595 {
596 self.cmd.arg(arg);
597 self
598 }
57/// Panic-on-fail [`std::env::var`] and [`std::env::var_os`] wrappers.
58pub use env::{env_var, env_var_os};
59959
600 /// Generic command arguments provider. Prefer specific helper methods if possible.
601 /// Note that for some executables, arguments might be platform specific. For C/C++
602 /// compilers, arguments might be platform *and* compiler specific.
603 pub fn args<V, S>(&mut self, args: V) -> &mut Self
604 where
605 V: AsRef<[S]>,
606 S: AsRef<::std::ffi::OsStr>,
607 {
608 self.cmd.args(args.as_ref());
609 self
610 }
60/// Convenience helpers for running binaries and other commands.
61pub use run::{cmd, run, run_fail, run_with_args};
61162
612 /// Inspect what the underlying [`Command`] is up to the
613 /// current construction.
614 pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
615 where
616 I: FnOnce(&::std::process::Command),
617 {
618 self.cmd.inspect(inspector);
619 self
620 }
63/// Helpers for checking target information.
64pub use targets::{is_darwin, is_msvc, is_windows, target, uname};
62165
622 /// Run the constructed command and assert that it is successfully run.
623 #[track_caller]
624 pub fn run(&mut self) -> crate::command::CompletedProcess {
625 self.cmd.run()
626 }
66/// Helpers for building names of output artifacts that are potentially target-specific.
67pub use artifact_names::{
68 bin_name, dynamic_lib_extension, dynamic_lib_name, rust_lib_name, static_lib_name,
69};
62770
628 /// Run the constructed command and assert that it does not successfully run.
629 #[track_caller]
630 pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
631 self.cmd.run_fail()
632 }
71/// Path-related helpers.
72pub use path_helpers::{
73 cwd, filename_not_in_denylist, has_extension, has_prefix, has_suffix, not_contains, path,
74 shallow_find_files, source_root,
75};
63376
634 /// Run the command but do not check its exit status.
635 /// Only use if you explicitly don't care about the exit status.
636 /// Prefer to use [`Self::run`] and [`Self::run_fail`]
637 /// whenever possible.
638 #[track_caller]
639 pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
640 self.cmd.run_unchecked()
641 }
77/// Helpers for scoped test execution where certain properties are attempted to be maintained.
78pub use scoped_run::{run_in_tmpdir, test_while_readonly};
64279
643 /// Set the path where the command will be run.
644 pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
645 self.cmd.current_dir(path);
646 self
647 }
648 }
649 };
650}
80pub use assertion_helpers::{
81 assert_contains, assert_dirs_are_equal, assert_equals, assert_not_contains,
82};
65183
652use crate::command::{Command, CompletedProcess};
653pub(crate) use impl_common_helpers;
84pub use string::{
85 count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains,
86};
src/tools/run-make-support/src/llvm.rs deleted-243
......@@ -1,243 +0,0 @@
1use std::path::{Path, PathBuf};
2
3use crate::{env_var, Command};
4
5/// Construct a new `llvm-readobj` invocation with the `GNU` output style.
6/// This assumes that `llvm-readobj` is available at `$LLVM_BIN_DIR/llvm-readobj`.
7#[track_caller]
8pub fn llvm_readobj() -> LlvmReadobj {
9 LlvmReadobj::new()
10}
11
12/// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available
13/// at `$LLVM_BIN_DIR/llvm-profdata`.
14#[track_caller]
15pub fn llvm_profdata() -> LlvmProfdata {
16 LlvmProfdata::new()
17}
18
19/// Construct a new `llvm-filecheck` invocation. This assumes that `llvm-filecheck` is available
20/// at `$LLVM_FILECHECK`.
21#[track_caller]
22pub fn llvm_filecheck() -> LlvmFilecheck {
23 LlvmFilecheck::new()
24}
25
26/// Construct a new `llvm-objdump` invocation. This assumes that `llvm-objdump` is available
27/// at `$LLVM_BIN_DIR/llvm-objdump`.
28pub fn llvm_objdump() -> LlvmObjdump {
29 LlvmObjdump::new()
30}
31
32/// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available
33/// at `$LLVM_BIN_DIR/llvm-ar`.
34pub fn llvm_ar() -> LlvmAr {
35 LlvmAr::new()
36}
37
38/// A `llvm-readobj` invocation builder.
39#[derive(Debug)]
40#[must_use]
41pub struct LlvmReadobj {
42 cmd: Command,
43}
44
45/// A `llvm-profdata` invocation builder.
46#[derive(Debug)]
47#[must_use]
48pub struct LlvmProfdata {
49 cmd: Command,
50}
51
52/// A `llvm-filecheck` invocation builder.
53#[derive(Debug)]
54#[must_use]
55pub struct LlvmFilecheck {
56 cmd: Command,
57}
58
59/// A `llvm-objdump` invocation builder.
60#[derive(Debug)]
61#[must_use]
62pub struct LlvmObjdump {
63 cmd: Command,
64}
65
66/// A `llvm-ar` invocation builder.
67#[derive(Debug)]
68#[must_use]
69pub struct LlvmAr {
70 cmd: Command,
71}
72
73crate::impl_common_helpers!(LlvmReadobj);
74crate::impl_common_helpers!(LlvmProfdata);
75crate::impl_common_helpers!(LlvmFilecheck);
76crate::impl_common_helpers!(LlvmObjdump);
77crate::impl_common_helpers!(LlvmAr);
78
79/// Generate the path to the bin directory of LLVM.
80#[must_use]
81pub fn llvm_bin_dir() -> PathBuf {
82 let llvm_bin_dir = env_var("LLVM_BIN_DIR");
83 PathBuf::from(llvm_bin_dir)
84}
85
86impl LlvmReadobj {
87 /// Construct a new `llvm-readobj` invocation with the `GNU` output style.
88 /// This assumes that `llvm-readobj` is available at `$LLVM_BIN_DIR/llvm-readobj`.
89 #[track_caller]
90 pub fn new() -> Self {
91 let llvm_readobj = llvm_bin_dir().join("llvm-readobj");
92 let cmd = Command::new(llvm_readobj);
93 let mut readobj = Self { cmd };
94 readobj.elf_output_style("GNU");
95 readobj
96 }
97
98 /// Specify the format of the ELF information.
99 ///
100 /// Valid options are `LLVM` (default), `GNU`, and `JSON`.
101 pub fn elf_output_style(&mut self, style: &str) -> &mut Self {
102 self.cmd.arg("--elf-output-style");
103 self.cmd.arg(style);
104 self
105 }
106
107 /// Provide an input file.
108 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
109 self.cmd.arg(path.as_ref());
110 self
111 }
112
113 /// Pass `--file-header` to display file headers.
114 pub fn file_header(&mut self) -> &mut Self {
115 self.cmd.arg("--file-header");
116 self
117 }
118
119 /// Pass `--program-headers` to display program headers.
120 pub fn program_headers(&mut self) -> &mut Self {
121 self.cmd.arg("--program-headers");
122 self
123 }
124
125 /// Pass `--symbols` to display the symbol.
126 pub fn symbols(&mut self) -> &mut Self {
127 self.cmd.arg("--symbols");
128 self
129 }
130
131 /// Pass `--dynamic-table` to display the dynamic symbol table.
132 pub fn dynamic_table(&mut self) -> &mut Self {
133 self.cmd.arg("--dynamic-table");
134 self
135 }
136
137 /// Specify the section to display.
138 pub fn section(&mut self, section: &str) -> &mut Self {
139 self.cmd.arg("--string-dump");
140 self.cmd.arg(section);
141 self
142 }
143}
144
145impl LlvmProfdata {
146 /// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available
147 /// at `$LLVM_BIN_DIR/llvm-profdata`.
148 #[track_caller]
149 pub fn new() -> Self {
150 let llvm_profdata = llvm_bin_dir().join("llvm-profdata");
151 let cmd = Command::new(llvm_profdata);
152 Self { cmd }
153 }
154
155 /// Provide an input file.
156 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
157 self.cmd.arg(path.as_ref());
158 self
159 }
160
161 /// Specify the output file path.
162 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
163 self.cmd.arg("-o");
164 self.cmd.arg(path.as_ref());
165 self
166 }
167
168 /// Take several profile data files generated by PGO instrumentation and merge them
169 /// together into a single indexed profile data file.
170 pub fn merge(&mut self) -> &mut Self {
171 self.cmd.arg("merge");
172 self
173 }
174}
175
176impl LlvmFilecheck {
177 /// Construct a new `llvm-filecheck` invocation. This assumes that `llvm-filecheck` is available
178 /// at `$LLVM_FILECHECK`.
179 #[track_caller]
180 pub fn new() -> Self {
181 let llvm_filecheck = env_var("LLVM_FILECHECK");
182 let cmd = Command::new(llvm_filecheck);
183 Self { cmd }
184 }
185
186 /// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call.
187 pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
188 self.cmd.stdin(input);
189 self
190 }
191
192 /// Provide the patterns that need to be matched.
193 pub fn patterns<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
194 self.cmd.arg(path.as_ref());
195 self
196 }
197
198 /// `--input-file` option.
199 pub fn input_file<P: AsRef<Path>>(&mut self, input_file: P) -> &mut Self {
200 self.cmd.arg("--input-file");
201 self.cmd.arg(input_file.as_ref());
202 self
203 }
204}
205
206impl LlvmObjdump {
207 /// Construct a new `llvm-objdump` invocation. This assumes that `llvm-objdump` is available
208 /// at `$LLVM_BIN_DIR/llvm-objdump`.
209 pub fn new() -> Self {
210 let llvm_objdump = llvm_bin_dir().join("llvm-objdump");
211 let cmd = Command::new(llvm_objdump);
212 Self { cmd }
213 }
214
215 /// Provide an input file.
216 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
217 self.cmd.arg(path.as_ref());
218 self
219 }
220}
221
222impl LlvmAr {
223 /// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available
224 /// at `$LLVM_BIN_DIR/llvm-ar`.
225 pub fn new() -> Self {
226 let llvm_ar = llvm_bin_dir().join("llvm-ar");
227 let cmd = Command::new(llvm_ar);
228 Self { cmd }
229 }
230
231 pub fn obj_to_ar(&mut self) -> &mut Self {
232 self.cmd.arg("rcus");
233 self
234 }
235
236 /// Provide an output, then an input file. Bundled in one function, as llvm-ar has
237 /// no "--output"-style flag.
238 pub fn output_input(&mut self, out: impl AsRef<Path>, input: impl AsRef<Path>) -> &mut Self {
239 self.cmd.arg(out.as_ref());
240 self.cmd.arg(input.as_ref());
241 self
242 }
243}
src/tools/run-make-support/src/macros.rs created+113
......@@ -0,0 +1,113 @@
1/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
2/// containing a `cmd: Command` field. The provided helpers are:
3///
4/// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
5/// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
6/// new specific helper methods over relying on these generic argument providers.
7/// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to
8/// methods of the same name on [`Command`].
9/// 3. Output and execution: `run` and `run_fail` are provided. These are higher-level convenience
10/// methods which wait for the command to finish running and assert that the command successfully
11/// ran or failed as expected. They return [`CompletedProcess`], which can be used to assert the
12/// stdout/stderr/exit code of the executed process.
13///
14/// Example usage:
15///
16/// ```ignore (illustrative)
17/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
18///
19/// crate::macros::impl_common_helpers!(CommandWrapper);
20///
21/// impl CommandWrapper {
22/// // ... additional specific helper methods
23/// }
24/// ```
25///
26/// [`Command`]: crate::command::Command
27/// [`CompletedProcess`]: crate::command::CompletedProcess
28macro_rules! impl_common_helpers {
29 ($wrapper: ident) => {
30 impl $wrapper {
31 /// Specify an environment variable.
32 pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Self
33 where
34 K: AsRef<::std::ffi::OsStr>,
35 V: AsRef<::std::ffi::OsStr>,
36 {
37 self.cmd.env(key, value);
38 self
39 }
40
41 /// Remove an environmental variable.
42 pub fn env_remove<K>(&mut self, key: K) -> &mut Self
43 where
44 K: AsRef<::std::ffi::OsStr>,
45 {
46 self.cmd.env_remove(key);
47 self
48 }
49
50 /// Generic command argument provider. Prefer specific helper methods if possible.
51 /// Note that for some executables, arguments might be platform specific. For C/C++
52 /// compilers, arguments might be platform *and* compiler specific.
53 pub fn arg<S>(&mut self, arg: S) -> &mut Self
54 where
55 S: AsRef<::std::ffi::OsStr>,
56 {
57 self.cmd.arg(arg);
58 self
59 }
60
61 /// Generic command arguments provider. Prefer specific helper methods if possible.
62 /// Note that for some executables, arguments might be platform specific. For C/C++
63 /// compilers, arguments might be platform *and* compiler specific.
64 pub fn args<V, S>(&mut self, args: V) -> &mut Self
65 where
66 V: AsRef<[S]>,
67 S: AsRef<::std::ffi::OsStr>,
68 {
69 self.cmd.args(args.as_ref());
70 self
71 }
72
73 /// Inspect what the underlying [`Command`] is up to the
74 /// current construction.
75 pub fn inspect<I>(&mut self, inspector: I) -> &mut Self
76 where
77 I: FnOnce(&::std::process::Command),
78 {
79 self.cmd.inspect(inspector);
80 self
81 }
82
83 /// Run the constructed command and assert that it is successfully run.
84 #[track_caller]
85 pub fn run(&mut self) -> crate::command::CompletedProcess {
86 self.cmd.run()
87 }
88
89 /// Run the constructed command and assert that it does not successfully run.
90 #[track_caller]
91 pub fn run_fail(&mut self) -> crate::command::CompletedProcess {
92 self.cmd.run_fail()
93 }
94
95 /// Run the command but do not check its exit status.
96 /// Only use if you explicitly don't care about the exit status.
97 /// Prefer to use [`Self::run`] and [`Self::run_fail`]
98 /// whenever possible.
99 #[track_caller]
100 pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
101 self.cmd.run_unchecked()
102 }
103
104 /// Set the path where the command will be run.
105 pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
106 self.cmd.current_dir(path);
107 self
108 }
109 }
110 };
111}
112
113pub(crate) use impl_common_helpers;
src/tools/run-make-support/src/path_helpers.rs created+80
......@@ -0,0 +1,80 @@
1//! Collection of path-related helpers.
2
3use std::path::{Path, PathBuf};
4
5use crate::env::env_var;
6
7/// Return the current working directory.
8///
9/// This forwards to [`std::env::current_dir`], please see its docs regarding platform-specific
10/// behavior.
11#[must_use]
12pub fn cwd() -> PathBuf {
13 std::env::current_dir().unwrap()
14}
15
16/// Construct a `PathBuf` relative to the current working directory by joining `cwd()` with the
17/// relative path. This is mostly a convenience helper so the test writer does not need to write
18/// `PathBuf::from(path_like_string)`.
19///
20/// # Example
21///
22/// ```rust
23/// let p = path("support_file.txt");
24/// ```
25pub fn path<P: AsRef<Path>>(p: P) -> PathBuf {
26 cwd().join(p.as_ref())
27}
28
29/// Path to the root `rust-lang/rust` source checkout.
30#[must_use]
31pub fn source_root() -> PathBuf {
32 env_var("SOURCE_ROOT").into()
33}
34
35/// Browse the directory `path` non-recursively and return all files which respect the parameters
36/// outlined by `closure`.
37#[track_caller]
38pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
39 path: P,
40 filter: F,
41) -> Vec<PathBuf> {
42 let mut matching_files = Vec::new();
43 for entry in std::fs::read_dir(path).unwrap() {
44 let entry = entry.expect("failed to read directory entry.");
45 let path = entry.path();
46
47 if path.is_file() && filter(&path) {
48 matching_files.push(path);
49 }
50 }
51 matching_files
52}
53
54/// Returns true if the filename at `path` does not contain `expected`.
55pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
56 !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
57}
58
59/// Returns true if the filename at `path` is not in `expected`.
60pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
61 let expected = expected.as_ref();
62 path.as_ref()
63 .file_name()
64 .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
65}
66
67/// Returns true if the filename at `path` starts with `prefix`.
68pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
69 path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
70}
71
72/// Returns true if the filename at `path` has the extension `extension`.
73pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
74 path.as_ref().extension().is_some_and(|ext| ext == extension)
75}
76
77/// Returns true if the filename at `path` ends with `suffix`.
78pub fn has_suffix<P: AsRef<Path>>(path: P, suffix: &str) -> bool {
79 path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().ends_with(suffix))
80}
src/tools/run-make-support/src/run.rs+2-3
......@@ -4,9 +4,8 @@ use std::panic;
44use std::path::{Path, PathBuf};
55
66use crate::command::{Command, CompletedProcess};
7use crate::{cwd, env_var, is_windows, set_host_rpath};
8
9use super::handle_failed_output;
7use crate::util::{handle_failed_output, set_host_rpath};
8use crate::{cwd, env_var, is_windows};
109
1110#[track_caller]
1211fn run_common(name: &str, args: Option<&[&str]>) -> Command {
src/tools/run-make-support/src/rustc.rs deleted-315
......@@ -1,315 +0,0 @@
1use command::Command;
2use std::ffi::{OsStr, OsString};
3use std::path::Path;
4
5use crate::{command, cwd, env_var, set_host_rpath};
6
7/// Construct a new `rustc` invocation. This will automatically set the library
8/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
9#[track_caller]
10pub fn rustc() -> Rustc {
11 Rustc::new()
12}
13
14/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_rpath`]
15/// still presets the environment variable `HOST_RPATH_DIR` by default.
16#[track_caller]
17pub fn bare_rustc() -> Rustc {
18 Rustc::bare()
19}
20
21/// Construct a new `rustc` aux-build invocation.
22#[track_caller]
23pub fn aux_build() -> Rustc {
24 Rustc::new_aux_build()
25}
26
27/// A `rustc` invocation builder.
28#[derive(Debug)]
29#[must_use]
30pub struct Rustc {
31 cmd: Command,
32}
33
34crate::impl_common_helpers!(Rustc);
35
36#[track_caller]
37fn setup_common() -> Command {
38 let rustc = env_var("RUSTC");
39 let mut cmd = Command::new(rustc);
40 set_host_rpath(&mut cmd);
41 cmd
42}
43
44impl Rustc {
45 // `rustc` invocation constructor methods
46
47 /// Construct a new `rustc` invocation. This will automatically set the library
48 /// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
49 #[track_caller]
50 pub fn new() -> Self {
51 let mut cmd = setup_common();
52 cmd.arg("-L").arg(cwd());
53 Self { cmd }
54 }
55
56 /// Construct a bare `rustc` invocation with no flags set.
57 #[track_caller]
58 pub fn bare() -> Self {
59 let cmd = setup_common();
60 Self { cmd }
61 }
62
63 /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
64 #[track_caller]
65 pub fn new_aux_build() -> Self {
66 let mut cmd = setup_common();
67 cmd.arg("--crate-type=lib");
68 Self { cmd }
69 }
70
71 // Argument provider methods
72
73 /// Configure the compilation environment.
74 pub fn cfg(&mut self, s: &str) -> &mut Self {
75 self.cmd.arg("--cfg");
76 self.cmd.arg(s);
77 self
78 }
79
80 /// Specify default optimization level `-O` (alias for `-C opt-level=2`).
81 pub fn opt(&mut self) -> &mut Self {
82 self.cmd.arg("-O");
83 self
84 }
85
86 /// Specify a specific optimization level.
87 pub fn opt_level(&mut self, option: &str) -> &mut Self {
88 self.cmd.arg(format!("-Copt-level={option}"));
89 self
90 }
91
92 /// Incorporate a hashed string to mangled symbols.
93 pub fn metadata(&mut self, meta: &str) -> &mut Self {
94 self.cmd.arg(format!("-Cmetadata={meta}"));
95 self
96 }
97
98 /// Add a suffix in each output filename.
99 pub fn extra_filename(&mut self, suffix: &str) -> &mut Self {
100 self.cmd.arg(format!("-Cextra-filename={suffix}"));
101 self
102 }
103
104 /// Specify type(s) of output files to generate.
105 pub fn emit<S: AsRef<str>>(&mut self, kinds: S) -> &mut Self {
106 let kinds = kinds.as_ref();
107 self.cmd.arg(format!("--emit={kinds}"));
108 self
109 }
110
111 /// Specify where an external library is located.
112 pub fn extern_<P: AsRef<Path>>(&mut self, crate_name: &str, path: P) -> &mut Self {
113 assert!(
114 !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'),
115 "crate name cannot contain whitespace or path separators"
116 );
117
118 let path = path.as_ref().to_string_lossy();
119
120 self.cmd.arg("--extern");
121 self.cmd.arg(format!("{crate_name}={path}"));
122
123 self
124 }
125
126 /// Remap source path prefixes in all output.
127 pub fn remap_path_prefix<P: AsRef<Path>, P2: AsRef<Path>>(
128 &mut self,
129 from: P,
130 to: P2,
131 ) -> &mut Self {
132 let from = from.as_ref().to_string_lossy();
133 let to = to.as_ref().to_string_lossy();
134
135 self.cmd.arg("--remap-path-prefix");
136 self.cmd.arg(format!("{from}={to}"));
137
138 self
139 }
140
141 /// Specify path to the input file.
142 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
143 self.cmd.arg(path.as_ref());
144 self
145 }
146
147 //Adjust the backtrace level, displaying more detailed information at higher levels.
148 pub fn set_backtrace_level<R: AsRef<OsStr>>(&mut self, level: R) -> &mut Self {
149 self.cmd.env("RUST_BACKTRACE", level);
150 self
151 }
152
153 /// Specify path to the output file. Equivalent to `-o`` in rustc.
154 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
155 self.cmd.arg("-o");
156 self.cmd.arg(path.as_ref());
157 self
158 }
159
160 /// Specify path to the output directory. Equivalent to `--out-dir`` in rustc.
161 pub fn out_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
162 self.cmd.arg("--out-dir");
163 self.cmd.arg(path.as_ref());
164 self
165 }
166
167 /// This flag defers LTO optimizations to the linker.
168 pub fn linker_plugin_lto(&mut self, option: &str) -> &mut Self {
169 self.cmd.arg(format!("-Clinker-plugin-lto={option}"));
170 self
171 }
172
173 /// Specify what happens when the code panics.
174 pub fn panic(&mut self, option: &str) -> &mut Self {
175 self.cmd.arg(format!("-Cpanic={option}"));
176 self
177 }
178
179 /// Specify number of codegen units
180 pub fn codegen_units(&mut self, units: usize) -> &mut Self {
181 self.cmd.arg(format!("-Ccodegen-units={units}"));
182 self
183 }
184
185 /// Specify directory path used for incremental cache
186 pub fn incremental<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
187 let mut arg = OsString::new();
188 arg.push("-Cincremental=");
189 arg.push(path.as_ref());
190 self.cmd.arg(&arg);
191 self
192 }
193
194 /// Specify directory path used for profile generation
195 pub fn profile_generate<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
196 let mut arg = OsString::new();
197 arg.push("-Cprofile-generate=");
198 arg.push(path.as_ref());
199 self.cmd.arg(&arg);
200 self
201 }
202
203 /// Specify directory path used for profile usage
204 pub fn profile_use<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
205 let mut arg = OsString::new();
206 arg.push("-Cprofile-use=");
207 arg.push(path.as_ref());
208 self.cmd.arg(&arg);
209 self
210 }
211
212 /// Specify error format to use
213 pub fn error_format(&mut self, format: &str) -> &mut Self {
214 self.cmd.arg(format!("--error-format={format}"));
215 self
216 }
217
218 /// Specify json messages printed by the compiler
219 pub fn json(&mut self, items: &str) -> &mut Self {
220 self.cmd.arg(format!("--json={items}"));
221 self
222 }
223
224 /// Specify the target triple, or a path to a custom target json spec file.
225 pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
226 let target = target.as_ref();
227 self.cmd.arg(format!("--target={target}"));
228 self
229 }
230
231 /// Specify the crate type.
232 pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
233 self.cmd.arg("--crate-type");
234 self.cmd.arg(crate_type);
235 self
236 }
237
238 /// Add a directory to the library search path. Equivalent to `-L` in rustc.
239 pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
240 self.cmd.arg("-L");
241 self.cmd.arg(path.as_ref());
242 self
243 }
244
245 /// Add a directory to the library search path with a restriction, where `kind` is a dependency
246 /// type. Equivalent to `-L KIND=PATH` in rustc.
247 pub fn specific_library_search_path<P: AsRef<Path>>(
248 &mut self,
249 kind: &str,
250 path: P,
251 ) -> &mut Self {
252 assert!(["dependency", "native", "all", "framework", "crate"].contains(&kind));
253 let path = path.as_ref().to_string_lossy();
254 self.cmd.arg(format!("-L{kind}={path}"));
255 self
256 }
257
258 /// Override the system root. Equivalent to `--sysroot` in rustc.
259 pub fn sysroot<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
260 self.cmd.arg("--sysroot");
261 self.cmd.arg(path.as_ref());
262 self
263 }
264
265 /// Specify the edition year.
266 pub fn edition(&mut self, edition: &str) -> &mut Self {
267 self.cmd.arg("--edition");
268 self.cmd.arg(edition);
269 self
270 }
271
272 /// Specify the print request.
273 pub fn print(&mut self, request: &str) -> &mut Self {
274 self.cmd.arg("--print");
275 self.cmd.arg(request);
276 self
277 }
278
279 /// Add an extra argument to the linker invocation, via `-Clink-arg`.
280 pub fn link_arg(&mut self, link_arg: &str) -> &mut Self {
281 self.cmd.arg(format!("-Clink-arg={link_arg}"));
282 self
283 }
284
285 /// Add multiple extra arguments to the linker invocation, via `-Clink-args`.
286 pub fn link_args(&mut self, link_args: &str) -> &mut Self {
287 self.cmd.arg(format!("-Clink-args={link_args}"));
288 self
289 }
290
291 /// Specify a stdin input
292 pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
293 self.cmd.stdin(input);
294 self
295 }
296
297 /// Specify the crate name.
298 pub fn crate_name<S: AsRef<OsStr>>(&mut self, name: S) -> &mut Self {
299 self.cmd.arg("--crate-name");
300 self.cmd.arg(name.as_ref());
301 self
302 }
303
304 /// Specify the linker
305 pub fn linker(&mut self, linker: &str) -> &mut Self {
306 self.cmd.arg(format!("-Clinker={linker}"));
307 self
308 }
309
310 /// Specify the linker flavor
311 pub fn linker_flavor(&mut self, linker_flavor: &str) -> &mut Self {
312 self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
313 self
314 }
315}
src/tools/run-make-support/src/rustdoc.rs deleted-141
......@@ -1,141 +0,0 @@
1use std::ffi::OsStr;
2use std::path::Path;
3
4use crate::command::Command;
5use crate::{env_var, env_var_os, set_host_rpath};
6
7/// Construct a plain `rustdoc` invocation with no flags set.
8#[track_caller]
9pub fn bare_rustdoc() -> Rustdoc {
10 Rustdoc::bare()
11}
12
13/// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
14#[track_caller]
15pub fn rustdoc() -> Rustdoc {
16 Rustdoc::new()
17}
18
19#[derive(Debug)]
20#[must_use]
21pub struct Rustdoc {
22 cmd: Command,
23}
24
25crate::impl_common_helpers!(Rustdoc);
26
27#[track_caller]
28fn setup_common() -> Command {
29 let rustdoc = env_var("RUSTDOC");
30 let mut cmd = Command::new(rustdoc);
31 set_host_rpath(&mut cmd);
32 cmd
33}
34
35impl Rustdoc {
36 /// Construct a bare `rustdoc` invocation.
37 #[track_caller]
38 pub fn bare() -> Self {
39 let cmd = setup_common();
40 Self { cmd }
41 }
42
43 /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
44 #[track_caller]
45 pub fn new() -> Self {
46 let mut cmd = setup_common();
47 let target_rpath_dir = env_var_os("TARGET_RPATH_DIR");
48 cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
49 Self { cmd }
50 }
51
52 /// Specify where an external library is located.
53 pub fn extern_<P: AsRef<Path>>(&mut self, crate_name: &str, path: P) -> &mut Self {
54 assert!(
55 !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'),
56 "crate name cannot contain whitespace or path separators"
57 );
58
59 let path = path.as_ref().to_string_lossy();
60
61 self.cmd.arg("--extern");
62 self.cmd.arg(format!("{crate_name}={path}"));
63
64 self
65 }
66
67 /// Specify path to the input file.
68 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
69 self.cmd.arg(path.as_ref());
70 self
71 }
72
73 /// Specify path to the output folder.
74 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
75 self.cmd.arg("-o");
76 self.cmd.arg(path.as_ref());
77 self
78 }
79
80 /// Specify output directory.
81 pub fn out_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
82 self.cmd.arg("--out-dir").arg(path.as_ref());
83 self
84 }
85
86 /// Given a `path`, pass `@{path}` to `rustdoc` as an
87 /// [arg file](https://doc.rust-lang.org/rustdoc/command-line-arguments.html#path-load-command-line-flags-from-a-path).
88 pub fn arg_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
89 self.cmd.arg(format!("@{}", path.as_ref().display()));
90 self
91 }
92
93 /// Specify a stdin input
94 pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
95 self.cmd.stdin(input);
96 self
97 }
98
99 /// Specify the edition year.
100 pub fn edition(&mut self, edition: &str) -> &mut Self {
101 self.cmd.arg("--edition");
102 self.cmd.arg(edition);
103 self
104 }
105
106 /// Specify the target triple, or a path to a custom target json spec file.
107 pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
108 let target = target.as_ref();
109 self.cmd.arg(format!("--target={target}"));
110 self
111 }
112
113 /// Specify the crate type.
114 pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
115 self.cmd.arg("--crate-type");
116 self.cmd.arg(crate_type);
117 self
118 }
119
120 /// Specify the crate name.
121 pub fn crate_name<S: AsRef<OsStr>>(&mut self, name: S) -> &mut Self {
122 self.cmd.arg("--crate-name");
123 self.cmd.arg(name.as_ref());
124 self
125 }
126
127 /// Add a directory to the library search path. It corresponds to the `-L`
128 /// rustdoc option.
129 pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
130 self.cmd.arg("-L");
131 self.cmd.arg(path.as_ref());
132 self
133 }
134
135 /// Specify the output format.
136 pub fn output_format(&mut self, format: &str) -> &mut Self {
137 self.cmd.arg("--output-format");
138 self.cmd.arg(format);
139 self
140 }
141}
src/tools/run-make-support/src/scoped_run.rs created+69
......@@ -0,0 +1,69 @@
1//! Collection of helpers that try to maintain certain properties while running a test closure.
2
3use std::path::Path;
4
5use crate::fs;
6use crate::path_helpers::cwd;
7use crate::targets::is_windows;
8
9/// Ensure that the path P is read-only while the test runs, and restore original permissions at the
10/// end so compiletest can clean up. This will panic on Windows if the path is a directory (as it
11/// would otherwise do nothing)
12///
13/// # Pitfalls
14///
15/// - Some CI runners are ran as root which may bypass read-only permission restrictions. Unclear
16/// exactly when such scenarios occur.
17///
18/// # FIXME
19///
20/// FIXME(Oneirical): This will no longer be required after compiletest receives the ability to
21/// manipulate read-only files. See <https://github.com/rust-lang/rust/issues/126334>.
22#[track_caller]
23pub fn test_while_readonly<P, F>(path: P, closure: F)
24where
25 P: AsRef<Path>,
26 F: FnOnce() + std::panic::UnwindSafe,
27{
28 let path = path.as_ref();
29 if is_windows() && path.is_dir() {
30 eprintln!("This helper function cannot be used on Windows to make directories readonly.");
31 eprintln!(
32 "See the official documentation:
33 https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.set_readonly"
34 );
35 panic!("`test_while_readonly` on directory detected while on Windows.");
36 }
37 let metadata = fs::metadata(&path);
38 let original_perms = metadata.permissions();
39
40 let mut new_perms = original_perms.clone();
41 new_perms.set_readonly(true);
42 fs::set_permissions(&path, new_perms);
43
44 let success = std::panic::catch_unwind(closure);
45
46 fs::set_permissions(&path, original_perms);
47 success.unwrap();
48}
49
50/// This function is designed for running commands in a temporary directory that is cleared after
51/// the function ends.
52///
53/// What this function does:
54/// 1. Creates a temporary directory (`tmpdir`)
55/// 2. Copies all files from the current directory to `tmpdir`
56/// 3. Changes the current working directory to `tmpdir`
57/// 4. Calls `callback`
58/// 5. Switches working directory back to the original one
59/// 6. Removes `tmpdir`
60pub fn run_in_tmpdir<F: FnOnce()>(callback: F) {
61 let original_dir = cwd();
62 let tmpdir = original_dir.join("../temporary-directory");
63 fs::copy_dir_all(".", &tmpdir);
64
65 std::env::set_current_dir(&tmpdir).unwrap();
66 callback();
67 std::env::set_current_dir(original_dir).unwrap();
68 fs::remove_dir_all(tmpdir);
69}
src/tools/run-make-support/src/string.rs created+50
......@@ -0,0 +1,50 @@
1use std::path::Path;
2
3use crate::fs;
4use crate::path_helpers::{cwd, has_extension, shallow_find_files};
5
6/// Gathers all files in the current working directory that have the extension `ext`, and counts
7/// the number of lines within that contain a match with the regex pattern `re`.
8pub fn count_regex_matches_in_files_with_extension(re: &regex::Regex, ext: &str) -> usize {
9 let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext));
10
11 let mut count = 0;
12 for file in fetched_files {
13 let content = fs::read_to_string(file);
14 count += content.lines().filter(|line| re.is_match(&line)).count();
15 }
16
17 count
18}
19
20/// Read the contents of a file that cannot simply be read by
21/// [`read_to_string`][crate::fs::read_to_string], due to invalid UTF-8 data, then assert
22/// that it contains `expected`.
23#[track_caller]
24pub fn invalid_utf8_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
25 let buffer = fs::read(path.as_ref());
26 let expected = expected.as_ref();
27 if !String::from_utf8_lossy(&buffer).contains(expected) {
28 eprintln!("=== FILE CONTENTS (LOSSY) ===");
29 eprintln!("{}", String::from_utf8_lossy(&buffer));
30 eprintln!("=== SPECIFIED TEXT ===");
31 eprintln!("{}", expected);
32 panic!("specified text was not found in file");
33 }
34}
35
36/// Read the contents of a file that cannot simply be read by
37/// [`read_to_string`][crate::fs::read_to_string], due to invalid UTF-8 data, then assert
38/// that it does not contain `expected`.
39#[track_caller]
40pub fn invalid_utf8_not_contains<P: AsRef<Path>, S: AsRef<str>>(path: P, expected: S) {
41 let buffer = fs::read(path.as_ref());
42 let expected = expected.as_ref();
43 if String::from_utf8_lossy(&buffer).contains(expected) {
44 eprintln!("=== FILE CONTENTS (LOSSY) ===");
45 eprintln!("{}", String::from_utf8_lossy(&buffer));
46 eprintln!("=== SPECIFIED TEXT ===");
47 eprintln!("{}", expected);
48 panic!("specified text was unexpectedly found in file");
49 }
50}
src/tools/run-make-support/src/targets.rs created+42
......@@ -0,0 +1,42 @@
1use std::panic;
2
3use crate::command::Command;
4use crate::env_var;
5use crate::util::handle_failed_output;
6
7/// `TARGET`
8#[must_use]
9pub fn target() -> String {
10 env_var("TARGET")
11}
12
13/// Check if target is windows-like.
14#[must_use]
15pub fn is_windows() -> bool {
16 target().contains("windows")
17}
18
19/// Check if target uses msvc.
20#[must_use]
21pub fn is_msvc() -> bool {
22 target().contains("msvc")
23}
24
25/// Check if target uses macOS.
26#[must_use]
27pub fn is_darwin() -> bool {
28 target().contains("darwin")
29}
30
31/// Run `uname`. This assumes that `uname` is available on the platform!
32#[track_caller]
33#[must_use]
34pub fn uname() -> String {
35 let caller = panic::Location::caller();
36 let mut uname = Command::new("uname");
37 let output = uname.run();
38 if !output.status().success() {
39 handle_failed_output(&uname, output, caller.line());
40 }
41 output.stdout_utf8()
42}
src/tools/run-make-support/src/util.rs created+39
......@@ -0,0 +1,39 @@
1use std::path::PathBuf;
2
3use crate::command::{Command, CompletedProcess};
4use crate::env::env_var;
5use crate::path_helpers::cwd;
6
7/// If a given [`Command`] failed (as indicated by its [`CompletedProcess`]), verbose print the
8/// executed command, failure location, output status and stdout/stderr, and abort the process with
9/// exit code `1`.
10pub(crate) fn handle_failed_output(
11 cmd: &Command,
12 output: CompletedProcess,
13 caller_line_number: u32,
14) -> ! {
15 if output.status().success() {
16 eprintln!("command unexpectedly succeeded at line {caller_line_number}");
17 } else {
18 eprintln!("command failed at line {caller_line_number}");
19 }
20 eprintln!("{cmd:?}");
21 eprintln!("output status: `{}`", output.status());
22 eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8());
23 eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8());
24 std::process::exit(1)
25}
26
27/// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
28pub(crate) fn set_host_rpath(cmd: &mut Command) {
29 let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
30 cmd.env(&ld_lib_path_envvar, {
31 let mut paths = vec![];
32 paths.push(cwd());
33 paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
34 for p in std::env::split_paths(&env_var(&ld_lib_path_envvar)) {
35 paths.push(p.to_path_buf());
36 }
37 std::env::join_paths(paths.iter()).unwrap()
38 });
39}
tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs+2-2
......@@ -5,14 +5,14 @@
55
66use std::path::PathBuf;
77
8use run_make_support::{aux_build, fs_wrapper, rustc, source_root};
8use run_make_support::{aux_build, rfs, rustc, source_root};
99
1010fn main() {
1111 aux_build().input("stable.rs").emit("metadata").run();
1212
1313 let output =
1414 rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run();
15 let version = fs_wrapper::read_to_string(source_root().join("src/version"));
15 let version = rfs::read_to_string(source_root().join("src/version"));
1616 let expected_string = format!("stable since {}", version.trim());
1717 output.assert_stderr_contains(expected_string);
1818}
tests/run-make/c-link-to-rust-dylib/rmake.rs+3-5
......@@ -3,9 +3,7 @@
33
44//@ ignore-cross-compile
55
6use run_make_support::{
7 cc, cwd, dynamic_lib_extension, fs_wrapper, is_msvc, read_dir, run, run_fail, rustc,
8};
6use run_make_support::{cc, cwd, dynamic_lib_extension, is_msvc, rfs, run, run_fail, rustc};
97
108fn main() {
119 rustc().input("foo.rs").run();
......@@ -21,14 +19,14 @@ fn main() {
2119 run("bar");
2220
2321 let expected_extension = dynamic_lib_extension();
24 read_dir(cwd(), |path| {
22 rfs::read_dir_entries(cwd(), |path| {
2523 if path.is_file()
2624 && path.extension().is_some_and(|ext| ext == expected_extension)
2725 && path.file_name().and_then(|name| name.to_str()).is_some_and(|name| {
2826 name.ends_with(".so") || name.ends_with(".dll") || name.ends_with(".dylib")
2927 })
3028 {
31 fs_wrapper::remove_file(path);
29 rfs::remove_file(path);
3230 }
3331 });
3432 run_fail("bar");
tests/run-make/c-link-to-rust-staticlib/rmake.rs+1-1
......@@ -3,7 +3,7 @@
33
44//@ ignore-cross-compile
55
6use run_make_support::fs_wrapper::remove_file;
6use run_make_support::rfs::remove_file;
77use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name};
88use std::fs;
99
tests/run-make/cdylib/rmake.rs+2-2
......@@ -10,7 +10,7 @@
1010
1111//@ ignore-cross-compile
1212
13use run_make_support::{cc, cwd, dynamic_lib_name, fs_wrapper, is_msvc, run, rustc};
13use run_make_support::{cc, cwd, dynamic_lib_name, is_msvc, rfs, run, rustc};
1414
1515fn main() {
1616 rustc().input("bar.rs").run();
......@@ -23,7 +23,7 @@ fn main() {
2323 }
2424
2525 run("foo");
26 fs_wrapper::remove_file(dynamic_lib_name("foo"));
26 rfs::remove_file(dynamic_lib_name("foo"));
2727
2828 rustc().input("foo.rs").arg("-Clto").run();
2929 run("foo");
tests/run-make/comment-section/rmake.rs+3-2
......@@ -10,8 +10,9 @@
1010use std::path::PathBuf;
1111
1212use run_make_support::llvm_readobj;
13use run_make_support::rfs;
1314use run_make_support::rustc;
14use run_make_support::{cwd, env_var, read_dir, run_in_tmpdir};
15use run_make_support::{cwd, env_var, run_in_tmpdir};
1516
1617fn main() {
1718 let target = env_var("TARGET");
......@@ -33,7 +34,7 @@ fn main() {
3334
3435 // Check all object files (including temporary outputs) have a `.comment`
3536 // section with the expected content.
36 read_dir(cwd(), |f| {
37 rfs::read_dir_entries(cwd(), |f| {
3738 if !f.extension().is_some_and(|ext| ext == "o") {
3839 return;
3940 }
tests/run-make/compiler-builtins/rmake.rs+1-1
......@@ -14,12 +14,12 @@
1414
1515#![deny(warnings)]
1616
17use run_make_support::fs_wrapper::{read, read_dir};
1817use run_make_support::object::read::archive::ArchiveFile;
1918use run_make_support::object::read::Object;
2019use run_make_support::object::ObjectSection;
2120use run_make_support::object::ObjectSymbol;
2221use run_make_support::object::RelocationTarget;
22use run_make_support::rfs::{read, read_dir};
2323use run_make_support::{cmd, env_var, object};
2424use std::collections::HashSet;
2525use std::path::PathBuf;
tests/run-make/compiler-lookup-paths/rmake.rs+7-7
......@@ -9,16 +9,16 @@
99//@ ignore-wasm64
1010// Reason: a C compiler is required for build_native_static_lib
1111
12use run_make_support::{build_native_static_lib, fs_wrapper, rustc, static_lib_name};
12use run_make_support::{build_native_static_lib, rfs, rustc, static_lib_name};
1313
1414fn main() {
1515 build_native_static_lib("native");
1616 let lib_native = static_lib_name("native");
17 fs_wrapper::create_dir_all("crate");
18 fs_wrapper::create_dir_all("native");
19 fs_wrapper::rename(&lib_native, format!("native/{}", &lib_native));
17 rfs::create_dir_all("crate");
18 rfs::create_dir_all("native");
19 rfs::rename(&lib_native, format!("native/{}", &lib_native));
2020 rustc().input("a.rs").run();
21 fs_wrapper::rename("liba.rlib", "crate/liba.rlib");
21 rfs::rename("liba.rlib", "crate/liba.rlib");
2222 rustc().input("b.rs").specific_library_search_path("native", "crate").run_fail();
2323 rustc().input("b.rs").specific_library_search_path("dependency", "crate").run_fail();
2424 rustc().input("b.rs").specific_library_search_path("crate", "crate").run();
......@@ -35,8 +35,8 @@ fn main() {
3535 rustc().input("d.rs").specific_library_search_path("all", "native").run();
3636
3737 // Deduplication tests.
38 fs_wrapper::create_dir_all("e1");
39 fs_wrapper::create_dir_all("e2");
38 rfs::create_dir_all("e1");
39 rfs::create_dir_all("e2");
4040
4141 rustc().input("e.rs").output("e1/libe.rlib").run();
4242 rustc().input("e.rs").output("e2/libe.rlib").run();
tests/run-make/const-prop-lint/rmake.rs+2-2
......@@ -1,11 +1,11 @@
11// Tests that const prop lints interrupting codegen don't leave `.o` files around.
22
3use run_make_support::{cwd, fs_wrapper, rustc};
3use run_make_support::{cwd, rfs, rustc};
44
55fn main() {
66 rustc().input("input.rs").run_fail().assert_exit_code(1);
77
8 for entry in fs_wrapper::read_dir(cwd()) {
8 for entry in rfs::read_dir(cwd()) {
99 let entry = entry.unwrap();
1010 let path = entry.path();
1111
tests/run-make/crate-name-priority/rmake.rs+5-5
......@@ -4,15 +4,15 @@
44// and the compiler flags, and checks that the flag is favoured each time.
55// See https://github.com/rust-lang/rust/pull/15518
66
7use run_make_support::{bin_name, fs_wrapper, rustc};
7use run_make_support::{bin_name, rfs, rustc};
88
99fn main() {
1010 rustc().input("foo.rs").run();
11 fs_wrapper::remove_file(bin_name("foo"));
11 rfs::remove_file(bin_name("foo"));
1212 rustc().input("foo.rs").crate_name("bar").run();
13 fs_wrapper::remove_file(bin_name("bar"));
13 rfs::remove_file(bin_name("bar"));
1414 rustc().input("foo1.rs").run();
15 fs_wrapper::remove_file(bin_name("foo"));
15 rfs::remove_file(bin_name("foo"));
1616 rustc().input("foo1.rs").output(bin_name("bar1")).run();
17 fs_wrapper::remove_file(bin_name("bar1"));
17 rfs::remove_file(bin_name("bar1"));
1818}
tests/run-make/doctests-keep-binaries/rmake.rs+1-1
......@@ -1,7 +1,7 @@
11// Check that valid binaries are persisted by running them, regardless of whether the
22// --run or --no-run option is used.
33
4use run_make_support::fs_wrapper::{create_dir, remove_dir_all};
4use run_make_support::rfs::{create_dir, remove_dir_all};
55use run_make_support::{run, rustc, rustdoc};
66use std::path::Path;
77
tests/run-make/doctests-runtool/rmake.rs+1-1
......@@ -1,6 +1,6 @@
11// Tests behavior of rustdoc `--runtool`.
22
3use run_make_support::fs_wrapper::{create_dir, remove_dir_all};
3use run_make_support::rfs::{create_dir, remove_dir_all};
44use run_make_support::{rustc, rustdoc};
55use std::path::PathBuf;
66
tests/run-make/dump-mono-stats/rmake.rs+2-2
......@@ -4,7 +4,7 @@
44// a specific expected string.
55// See https://github.com/rust-lang/rust/pull/105481
66
7use run_make_support::{cwd, fs_wrapper, rustc};
7use run_make_support::{cwd, rfs, rustc};
88
99fn main() {
1010 rustc()
......@@ -13,5 +13,5 @@ fn main() {
1313 .arg(format!("-Zdump-mono-stats={}", cwd().display()))
1414 .arg("-Zdump-mono-stats-format=json")
1515 .run();
16 assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains(r#""name":"bar""#));
16 assert!(rfs::read_to_string("foo.mono_items.json").contains(r#""name":"bar""#));
1717}
tests/run-make/dylib-chain/rmake.rs+4-4
......@@ -8,7 +8,7 @@
88//@ ignore-cross-compile
99// Reason: the compiled binary is executed
1010
11use run_make_support::{dynamic_lib_name, fs_wrapper, run, run_fail, rustc};
11use run_make_support::{dynamic_lib_name, rfs, run, run_fail, rustc};
1212
1313fn main() {
1414 rustc().input("m1.rs").arg("-Cprefer-dynamic").run();
......@@ -16,8 +16,8 @@ fn main() {
1616 rustc().input("m3.rs").arg("-Cprefer-dynamic").run();
1717 rustc().input("m4.rs").run();
1818 run("m4");
19 fs_wrapper::remove_file(dynamic_lib_name("m1"));
20 fs_wrapper::remove_file(dynamic_lib_name("m2"));
21 fs_wrapper::remove_file(dynamic_lib_name("m3"));
19 rfs::remove_file(dynamic_lib_name("m1"));
20 rfs::remove_file(dynamic_lib_name("m2"));
21 rfs::remove_file(dynamic_lib_name("m3"));
2222 run_fail("m4");
2323}
tests/run-make/emit-named-files/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11use std::path::Path;
22
3use run_make_support::{fs_wrapper, rustc};
3use run_make_support::{rfs, rustc};
44
55fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) {
66 let out_file = out_dir.join(out_file);
......@@ -11,7 +11,7 @@ fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) {
1111fn main() {
1212 let out_dir = Path::new("emit");
1313
14 fs_wrapper::create_dir(&out_dir);
14 rfs::create_dir(&out_dir);
1515
1616 emit_and_check(&out_dir, "libfoo.s", "asm");
1717 emit_and_check(&out_dir, "libfoo.bc", "llvm-bc");
tests/run-make/emit-path-unhashed/rmake.rs+5-5
......@@ -6,13 +6,13 @@
66// adding a new output type (in this test, metadata).
77// See https://github.com/rust-lang/rust/issues/86044
88
9use run_make_support::{diff, fs_wrapper, rustc};
9use run_make_support::{diff, rfs, rustc};
1010
1111fn main() {
12 fs_wrapper::create_dir("emit");
13 fs_wrapper::create_dir("emit/a");
14 fs_wrapper::create_dir("emit/b");
15 fs_wrapper::create_dir("emit/c");
12 rfs::create_dir("emit");
13 rfs::create_dir("emit/a");
14 rfs::create_dir("emit/b");
15 rfs::create_dir("emit/c");
1616 // The default output name.
1717 rustc().emit("link").input("foo.rs").run();
1818 // The output is named with the output flag.
tests/run-make/extern-flag-pathless/rmake.rs+9-9
......@@ -8,21 +8,21 @@
88//@ ignore-cross-compile
99// Reason: the compiled binary is executed
1010
11use run_make_support::{dynamic_lib_name, fs_wrapper, run, run_fail, rust_lib_name, rustc};
11use run_make_support::{dynamic_lib_name, rfs, run, run_fail, rust_lib_name, rustc};
1212
1313fn main() {
1414 rustc().input("bar.rs").crate_type("rlib").crate_type("dylib").arg("-Cprefer-dynamic").run();
1515
1616 // By default, the rlib has priority over the dylib.
1717 rustc().input("foo.rs").arg("--extern").arg("bar").run();
18 fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
18 rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
1919 run("foo");
20 fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
20 rfs::rename("bar.tmp", dynamic_lib_name("bar"));
2121
2222 rustc().input("foo.rs").extern_("bar", rust_lib_name("bar")).arg("--extern").arg("bar").run();
23 fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
23 rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
2424 run("foo");
25 fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
25 rfs::rename("bar.tmp", dynamic_lib_name("bar"));
2626
2727 // The first explicit usage of extern overrides the second pathless --extern bar.
2828 rustc()
......@@ -31,13 +31,13 @@ fn main() {
3131 .arg("--extern")
3232 .arg("bar")
3333 .run();
34 fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
34 rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
3535 run_fail("foo");
36 fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
36 rfs::rename("bar.tmp", dynamic_lib_name("bar"));
3737
3838 // With prefer-dynamic, execution fails as it refuses to use the rlib.
3939 rustc().input("foo.rs").arg("--extern").arg("bar").arg("-Cprefer-dynamic").run();
40 fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp");
40 rfs::rename(dynamic_lib_name("bar"), "bar.tmp");
4141 run_fail("foo");
42 fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar"));
42 rfs::rename("bar.tmp", dynamic_lib_name("bar"));
4343}
tests/run-make/extra-filename-with-temp-outputs/rmake.rs+3-5
......@@ -6,9 +6,7 @@
66// are named as expected.
77// See https://github.com/rust-lang/rust/pull/15686
88
9use run_make_support::{
10 bin_name, cwd, fs_wrapper, has_prefix, has_suffix, rustc, shallow_find_files,
11};
9use run_make_support::{bin_name, cwd, has_prefix, has_suffix, rfs, rustc, shallow_find_files};
1210
1311fn main() {
1412 rustc().extra_filename("bar").input("foo.rs").arg("-Csave-temps").run();
......@@ -16,6 +14,6 @@ fn main() {
1614 has_prefix(path, "foobar.foo") && has_suffix(path, "0.rcgu.o")
1715 });
1816 let object_file = object_files.get(0).unwrap();
19 fs_wrapper::remove_file(object_file);
20 fs_wrapper::remove_file(bin_name("foobar"));
17 rfs::remove_file(object_file);
18 rfs::remove_file(bin_name("foobar"));
2119}
tests/run-make/ice-dep-cannot-find-dep/rmake.rs+1-1
......@@ -16,7 +16,7 @@
1616// If we used `rustc` the additional '-L rmake_out' option would allow rustc to
1717// actually find the crate.
1818
19use run_make_support::{bare_rustc, fs_wrapper, rust_lib_name, rustc};
19use run_make_support::{bare_rustc, rfs, rust_lib_name, rustc};
2020
2121fn main() {
2222 rustc().crate_name("a").crate_type("rlib").input("a.rs").arg("--verbose").run();
tests/run-make/inaccessible-temp-dir/rmake.rs+2-2
......@@ -24,11 +24,11 @@
2424// Reason: `set_readonly` has no effect on directories
2525// and does not prevent modification.
2626
27use run_make_support::{fs_wrapper, rustc, test_while_readonly};
27use run_make_support::{rfs, rustc, test_while_readonly};
2828
2929fn main() {
3030 // Create an inaccessible directory.
31 fs_wrapper::create_dir("inaccessible");
31 rfs::create_dir("inaccessible");
3232 test_while_readonly("inaccessible", || {
3333 // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one,
3434 // so that it can't create `tmp`.
tests/run-make/incr-prev-body-beyond-eof/rmake.rs+5-5
......@@ -13,14 +13,14 @@
1313//@ ignore-nvptx64-nvidia-cuda
1414// FIXME: can't find crate for `std`
1515
16use run_make_support::fs_wrapper as fs;
16use run_make_support::rfs;
1717use run_make_support::rustc;
1818
1919fn main() {
20 fs::create_dir("src");
21 fs::create_dir("incr");
22 fs::copy("a.rs", "src/main.rs");
20 rfs::create_dir("src");
21 rfs::create_dir("incr");
22 rfs::copy("a.rs", "src/main.rs");
2323 rustc().incremental("incr").input("src/main.rs").run();
24 fs::copy("b.rs", "src/main.rs");
24 rfs::copy("b.rs", "src/main.rs");
2525 rustc().incremental("incr").input("src/main.rs").run();
2626}
tests/run-make/incr-test-moved-file/rmake.rs+6-6
......@@ -14,14 +14,14 @@
1414//@ ignore-nvptx64-nvidia-cuda
1515// FIXME: can't find crate for 'std'
1616
17use run_make_support::{fs_wrapper, rust_lib_name, rustc};
17use run_make_support::{rfs, rust_lib_name, rustc};
1818
1919fn main() {
20 fs_wrapper::create_dir("incr");
21 fs_wrapper::create_dir("src");
22 fs_wrapper::create_dir("src/mydir");
23 fs_wrapper::copy("main.rs", "src/main.rs");
20 rfs::create_dir("incr");
21 rfs::create_dir("src");
22 rfs::create_dir("src/mydir");
23 rfs::copy("main.rs", "src/main.rs");
2424 rustc().input("src/main.rs").incremental("incr").arg("--test").run();
25 fs_wrapper::rename("src/main.rs", "src/mydir/main.rs");
25 rfs::rename("src/main.rs", "src/mydir/main.rs");
2626 rustc().input("src/mydir/main.rs").incremental("incr").arg("--test").run();
2727}
tests/run-make/incremental-debugger-visualizer/rmake.rs+11-11
......@@ -2,14 +2,14 @@
22// (in this case, foo.py and foo.natvis) are picked up when compiling incrementally.
33// See https://github.com/rust-lang/rust/pull/111641
44
5use run_make_support::{fs_wrapper, invalid_utf8_contains, invalid_utf8_not_contains, rustc};
5use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rfs, rustc};
66use std::io::Read;
77
88fn main() {
9 fs_wrapper::create_file("foo.py");
10 fs_wrapper::write("foo.py", "GDB script v1");
11 fs_wrapper::create_file("foo.natvis");
12 fs_wrapper::write("foo.natvis", "Natvis v1");
9 rfs::create_file("foo.py");
10 rfs::write("foo.py", "GDB script v1");
11 rfs::create_file("foo.natvis");
12 rfs::write("foo.natvis", "Natvis v1");
1313 rustc()
1414 .input("foo.rs")
1515 .crate_type("rlib")
......@@ -22,9 +22,9 @@ fn main() {
2222 invalid_utf8_contains("libfoo.rmeta", "Natvis v1");
2323
2424 // Change only the GDB script and check that the change has been picked up
25 fs_wrapper::remove_file("foo.py");
26 fs_wrapper::create_file("foo.py");
27 fs_wrapper::write("foo.py", "GDB script v2");
25 rfs::remove_file("foo.py");
26 rfs::create_file("foo.py");
27 rfs::write("foo.py", "GDB script v2");
2828 rustc()
2929 .input("foo.rs")
3030 .crate_type("rlib")
......@@ -38,9 +38,9 @@ fn main() {
3838 invalid_utf8_contains("libfoo.rmeta", "Natvis v1");
3939
4040 // Now change the Natvis version and check that the change has been picked up
41 fs_wrapper::remove_file("foo.natvis");
42 fs_wrapper::create_file("foo.natvis");
43 fs_wrapper::write("foo.natvis", "Natvis v2");
41 rfs::remove_file("foo.natvis");
42 rfs::create_file("foo.natvis");
43 rfs::write("foo.natvis", "Natvis v2");
4444 rustc()
4545 .input("foo.rs")
4646 .crate_type("rlib")
tests/run-make/incremental-session-fail/rmake.rs+2-2
......@@ -4,10 +4,10 @@
44// the ensuing compilation failure is not an ICE.
55// See https://github.com/rust-lang/rust/pull/85698
66
7use run_make_support::{fs_wrapper, rustc};
7use run_make_support::{rfs, rustc};
88
99fn main() {
10 fs_wrapper::create_file("session");
10 rfs::create_file("session");
1111 // rustc should fail to create the session directory here.
1212 let out = rustc().input("foo.rs").crate_type("rlib").incremental("session").run_fail();
1313 out.assert_stderr_contains("could not create incremental compilation crate directory");
tests/run-make/inline-always-many-cgu/rmake.rs+4-4
......@@ -1,6 +1,6 @@
1use run_make_support::fs_wrapper::read_to_string;
21use run_make_support::regex::Regex;
3use run_make_support::{read_dir, rustc};
2use run_make_support::rfs;
3use run_make_support::rustc;
44
55use std::ffi::OsStr;
66
......@@ -8,9 +8,9 @@ fn main() {
88 rustc().input("foo.rs").emit("llvm-ir").codegen_units(2).run();
99 let re = Regex::new(r"\bcall\b").unwrap();
1010 let mut nb_ll = 0;
11 read_dir(".", |path| {
11 rfs::read_dir_entries(".", |path| {
1212 if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("ll")) {
13 assert!(!re.is_match(&read_to_string(path)));
13 assert!(!re.is_match(&rfs::read_to_string(path)));
1414 nb_ll += 1;
1515 }
1616 });
tests/run-make/intrinsic-unreachable/rmake.rs+3-3
......@@ -8,13 +8,13 @@
88//@ ignore-windows
99// Reason: Because of Windows exception handling, the code is not necessarily any shorter.
1010
11use run_make_support::{fs_wrapper, rustc};
11use run_make_support::{rfs, rustc};
1212
1313fn main() {
1414 rustc().opt().emit("asm").input("exit-ret.rs").run();
1515 rustc().opt().emit("asm").input("exit-unreachable.rs").run();
1616 assert!(
17 fs_wrapper::read_to_string("exit-unreachable.s").lines().count()
18 < fs_wrapper::read_to_string("exit-ret.s").lines().count()
17 rfs::read_to_string("exit-unreachable.s").lines().count()
18 < rfs::read_to_string("exit-ret.s").lines().count()
1919 );
2020}
tests/run-make/invalid-library/rmake.rs+2-2
......@@ -4,11 +4,11 @@
44// one appearing in stderr in this scenario.
55// See https://github.com/rust-lang/rust/pull/12645
66
7use run_make_support::fs_wrapper::create_file;
7use run_make_support::rfs;
88use run_make_support::{llvm_ar, rustc};
99
1010fn main() {
11 create_file("lib.rmeta");
11 rfs::create_file("lib.rmeta");
1212 llvm_ar().obj_to_ar().output_input("libfoo-ffffffff-1.0.rlib", "lib.rmeta").run();
1313 rustc().input("foo.rs").run_fail().assert_stderr_contains("found invalid metadata");
1414}
tests/run-make/invalid-so/rmake.rs+2-2
......@@ -4,10 +4,10 @@
44// explains that the file exists, but that its metadata is incorrect.
55// See https://github.com/rust-lang/rust/pull/88368
66
7use run_make_support::{dynamic_lib_name, fs_wrapper, rustc};
7use run_make_support::{dynamic_lib_name, rfs, rustc};
88
99fn main() {
10 fs_wrapper::create_file(dynamic_lib_name("foo"));
10 rfs::create_file(dynamic_lib_name("foo"));
1111 rustc()
1212 .crate_type("lib")
1313 .extern_("foo", dynamic_lib_name("foo"))
tests/run-make/invalid-staticlib/rmake.rs+2-2
......@@ -4,10 +4,10 @@
44// an internal compiler error (ICE).
55// See https://github.com/rust-lang/rust/pull/28673
66
7use run_make_support::{fs_wrapper, rustc, static_lib_name};
7use run_make_support::{rfs, rustc, static_lib_name};
88
99fn main() {
10 fs_wrapper::create_file(static_lib_name("foo"));
10 rfs::create_file(static_lib_name("foo"));
1111 rustc()
1212 .arg("-")
1313 .crate_type("rlib")
tests/run-make/issue-107495-archive-permissions/rmake.rs+2-2
......@@ -3,7 +3,7 @@
33#[cfg(unix)]
44extern crate libc;
55
6use run_make_support::{aux_build, fs_wrapper};
6use run_make_support::{aux_build, rfs};
77
88#[cfg(unix)]
99use std::os::unix::fs::PermissionsExt;
......@@ -20,7 +20,7 @@ fn main() {
2020}
2121
2222fn verify(path: &Path) {
23 let perm = fs_wrapper::metadata(path).permissions();
23 let perm = rfs::metadata(path).permissions();
2424
2525 assert!(!perm.readonly());
2626
tests/run-make/ls-metadata/rmake.rs+2-2
......@@ -6,12 +6,12 @@
66
77//@ ignore-cross-compile
88
9use run_make_support::fs_wrapper;
9use run_make_support::rfs;
1010use run_make_support::rustc;
1111
1212fn main() {
1313 rustc().input("foo.rs").run();
1414 rustc().arg("-Zls=root").input("foo").run();
15 fs_wrapper::create_file("bar");
15 rfs::create_file("bar");
1616 rustc().arg("-Zls=root").input("bar").run();
1717}
tests/run-make/lto-readonly-lib/rmake.rs+1-1
......@@ -7,7 +7,7 @@
77
88//@ ignore-cross-compile
99
10use run_make_support::fs_wrapper;
10use run_make_support::rfs;
1111use run_make_support::{run, rust_lib_name, rustc, test_while_readonly};
1212
1313fn main() {
tests/run-make/many-crates-but-no-match/rmake.rs+4-4
......@@ -4,12 +4,12 @@
44// what should be done to fix the issue.
55// See https://github.com/rust-lang/rust/issues/13266
66
7use run_make_support::{fs_wrapper, rustc};
7use run_make_support::{rfs, rustc};
88
99fn main() {
10 fs_wrapper::create_dir("a1");
11 fs_wrapper::create_dir("a2");
12 fs_wrapper::create_dir("a3");
10 rfs::create_dir("a1");
11 rfs::create_dir("a2");
12 rfs::create_dir("a3");
1313 rustc().crate_type("rlib").out_dir("a1").input("crateA1.rs").run();
1414 rustc().crate_type("rlib").library_search_path("a1").input("crateB.rs").run();
1515 rustc().crate_type("rlib").out_dir("a2").input("crateA2.rs").run();
tests/run-make/mixing-libs/rmake.rs+2-2
......@@ -6,7 +6,7 @@
66
77//@ ignore-cross-compile
88
9use run_make_support::{dynamic_lib_name, fs_wrapper, rustc};
9use run_make_support::{dynamic_lib_name, rfs, rustc};
1010
1111fn main() {
1212 rustc().input("rlib.rs").crate_type("rlib").crate_type("dylib").run();
......@@ -16,6 +16,6 @@ fn main() {
1616
1717 // librlib's dynamic version needs to be removed here to prevent prog.rs from fetching
1818 // the wrong one.
19 fs_wrapper::remove_file(dynamic_lib_name("rlib"));
19 rfs::remove_file(dynamic_lib_name("rlib"));
2020 rustc().input("prog.rs").run_fail();
2121}
tests/run-make/moved-src-dir-fingerprint-ice/rmake.rs+7-7
......@@ -17,20 +17,20 @@
1717//@ ignore-nvptx64-nvidia-cuda
1818// FIXME: can't find crate for 'std'
1919
20use run_make_support::{fs_wrapper, rust_lib_name, rustc};
20use run_make_support::{rfs, rust_lib_name, rustc};
2121
2222fn main() {
23 fs_wrapper::create_dir("incr");
24 fs_wrapper::create_dir("first_src");
25 fs_wrapper::create_dir("output");
26 fs_wrapper::rename("my_lib.rs", "first_src/my_lib.rs");
27 fs_wrapper::rename("main.rs", "first_src/main.rs");
23 rfs::create_dir("incr");
24 rfs::create_dir("first_src");
25 rfs::create_dir("output");
26 rfs::rename("my_lib.rs", "first_src/my_lib.rs");
27 rfs::rename("main.rs", "first_src/main.rs");
2828 // Build from "first_src"
2929 std::env::set_current_dir("first_src").unwrap();
3030 rustc().input("my_lib.rs").incremental("incr").crate_type("lib").run();
3131 rustc().input("main.rs").incremental("incr").extern_("my_lib", rust_lib_name("my_lib")).run();
3232 std::env::set_current_dir("..").unwrap();
33 fs_wrapper::rename("first_src", "second_src");
33 rfs::rename("first_src", "second_src");
3434 std::env::set_current_dir("second_src").unwrap();
3535 // Build from "second_src" - the output and incremental directory remain identical
3636 rustc().input("my_lib.rs").incremental("incr").crate_type("lib").run();
tests/run-make/non-unicode-env/rmake.rs+2-2
......@@ -1,4 +1,4 @@
1use run_make_support::fs_wrapper;
1use run_make_support::rfs;
22use run_make_support::rustc;
33
44fn main() {
......@@ -7,6 +7,6 @@ fn main() {
77 #[cfg(windows)]
88 let non_unicode: std::ffi::OsString = std::os::windows::ffi::OsStringExt::from_wide(&[0xD800]);
99 let output = rustc().input("non_unicode_env.rs").env("NON_UNICODE_VAR", non_unicode).run_fail();
10 let expected = fs_wrapper::read_to_string("non_unicode_env.stderr");
10 let expected = rfs::read_to_string("non_unicode_env.stderr");
1111 output.assert_stderr_equals(expected);
1212}
tests/run-make/non-unicode-in-incremental-dir/rmake.rs+3-3
......@@ -1,4 +1,4 @@
1use run_make_support::{fs_wrapper, rustc};
1use run_make_support::{rfs, rustc};
22
33fn main() {
44 #[cfg(unix)]
......@@ -17,8 +17,8 @@ fn main() {
1717 }
1818 let incr_dir = "incr-dir";
1919 rustc().input("foo.rs").incremental(&incr_dir).run();
20 for crate_dir in fs_wrapper::read_dir(&incr_dir) {
21 fs_wrapper::create_dir(crate_dir.unwrap().path().join(&non_unicode));
20 for crate_dir in rfs::read_dir(&incr_dir) {
21 rfs::create_dir(crate_dir.unwrap().path().join(&non_unicode));
2222 }
2323 rustc().input("foo.rs").incremental(&incr_dir).run();
2424}
tests/run-make/obey-crate-type-flag/rmake.rs+2-2
......@@ -6,7 +6,7 @@
66//@ ignore-cross-compile
77
88use run_make_support::{
9 cwd, dynamic_lib_name, fs_wrapper, has_extension, rust_lib_name, rustc, shallow_find_files,
9 cwd, dynamic_lib_name, has_extension, rfs, rust_lib_name, rustc, shallow_find_files,
1010};
1111use std::path::Path;
1212
......@@ -15,7 +15,7 @@ fn main() {
1515 assert!(Path::new(&dynamic_lib_name("test")).exists());
1616 assert!(Path::new(&rust_lib_name("test")).exists());
1717
18 fs_wrapper::remove_file(rust_lib_name("test"));
18 rfs::remove_file(rust_lib_name("test"));
1919 rustc().crate_type("dylib").input("test.rs").run();
2020 assert!(shallow_find_files(cwd(), |path| { has_extension(path, "rlib") }).is_empty());
2121}
tests/run-make/output-filename-conflicts-with-directory/rmake.rs+2-2
......@@ -4,10 +4,10 @@
44// potentially-confusing linker error.
55// See https://github.com/rust-lang/rust/pull/47203
66
7use run_make_support::{fs_wrapper, rustc};
7use run_make_support::{rfs, rustc};
88
99fn main() {
10 fs_wrapper::create_dir("foo");
10 rfs::create_dir("foo");
1111 rustc().input("foo.rs").output("foo").run_fail().assert_stderr_contains(
1212 r#"the generated executable for the input file "foo.rs" conflicts with the existing directory "foo""#,
1313 );
tests/run-make/output-filename-overwrites-input/rmake.rs+3-3
......@@ -4,14 +4,14 @@
44
55//@ ignore-cross-compile
66
7use run_make_support::{fs_wrapper, rustc};
7use run_make_support::{rfs, rustc};
88
99fn main() {
10 fs_wrapper::copy("foo.rs", "foo");
10 rfs::copy("foo.rs", "foo");
1111 rustc().input("foo").output("foo").run_fail().assert_stderr_contains(
1212 r#"the input file "foo" would be overwritten by the generated executable"#,
1313 );
14 fs_wrapper::copy("bar.rs", "bar.rlib");
14 rfs::copy("bar.rs", "bar.rlib");
1515 rustc().input("bar.rlib").output("bar.rlib").run_fail().assert_stderr_contains(
1616 r#"the input file "bar.rlib" would be overwritten by the generated executable"#,
1717 );
tests/run-make/output-type-permutations/rmake.rs+5-8
......@@ -5,7 +5,7 @@
55// See https://github.com/rust-lang/rust/pull/12020
66
77use run_make_support::{
8 bin_name, dynamic_lib_name, filename_not_in_denylist, fs_wrapper, rust_lib_name, rustc,
8 bin_name, dynamic_lib_name, filename_not_in_denylist, rfs, rust_lib_name, rustc,
99 shallow_find_files, static_lib_name,
1010};
1111use std::path::PathBuf;
......@@ -20,10 +20,10 @@ fn assert_expected_output_files(expectations: Expectations, rustc_invocation: im
2020 let Expectations { expected_files: must_exist, allowed_files: can_exist, test_dir: dir } =
2121 expectations;
2222
23 fs_wrapper::create_dir(&dir);
23 rfs::create_dir(&dir);
2424 rustc_invocation();
2525 for file in must_exist {
26 fs_wrapper::remove_file(PathBuf::from(&dir).join(&file));
26 rfs::remove_file(PathBuf::from(&dir).join(&file));
2727 }
2828 let actual_output_files =
2929 shallow_find_files(dir, |path| filename_not_in_denylist(path, &can_exist));
......@@ -526,17 +526,14 @@ fn main() {
526526 test_dir: "rlib-emits".to_string(),
527527 },
528528 || {
529 fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc");
529 rfs::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc");
530530 rustc()
531531 .input("foo.rs")
532532 .emit("llvm-bc,link")
533533 .crate_type("rlib")
534534 .out_dir("rlib-emits")
535535 .run();
536 assert_eq!(
537 fs_wrapper::read("rlib-emits/foo.bc"),
538 fs_wrapper::read("rlib-emits/bar.bc")
539 );
536 assert_eq!(rfs::read("rlib-emits/foo.bc"), rfs::read("rlib-emits/bar.bc"));
540537 },
541538 );
542539}
tests/run-make/parallel-rustc-no-overwrite/rmake.rs+2-2
......@@ -5,12 +5,12 @@
55// conflicts. This test uses this flag and checks for successful compilation.
66// See https://github.com/rust-lang/rust/pull/83846
77
8use run_make_support::{fs_wrapper, rustc};
8use run_make_support::{rfs, rustc};
99use std::sync::{Arc, Barrier};
1010use std::thread;
1111
1212fn main() {
13 fs_wrapper::create_file("lib.rs");
13 rfs::create_file("lib.rs");
1414 let barrier = Arc::new(Barrier::new(2));
1515 let handle = {
1616 let barrier = Arc::clone(&barrier);
tests/run-make/pgo-branch-weights/rmake.rs+3-6
......@@ -10,14 +10,14 @@
1010//@ needs-profiler-support
1111//@ ignore-cross-compile
1212
13use run_make_support::{fs_wrapper, llvm_filecheck, llvm_profdata, run_with_args, rustc};
13use run_make_support::{llvm_filecheck, llvm_profdata, rfs, run_with_args, rustc};
1414use std::path::Path;
1515
1616fn main() {
1717 let path_prof_data_dir = Path::new("prof_data_dir");
1818 let path_merged_profdata = path_prof_data_dir.join("merged.profdata");
1919 rustc().input("opaque.rs").run();
20 fs_wrapper::create_dir_all(&path_prof_data_dir);
20 rfs::create_dir_all(&path_prof_data_dir);
2121 rustc()
2222 .input("interesting.rs")
2323 .profile_generate(&path_prof_data_dir)
......@@ -34,8 +34,5 @@ fn main() {
3434 .codegen_units(1)
3535 .emit("llvm-ir")
3636 .run();
37 llvm_filecheck()
38 .patterns("filecheck-patterns.txt")
39 .stdin(fs_wrapper::read("interesting.ll"))
40 .run();
37 llvm_filecheck().patterns("filecheck-patterns.txt").stdin(rfs::read("interesting.ll")).run();
4138}
tests/run-make/pgo-use/rmake.rs+3-3
......@@ -9,8 +9,8 @@
99//@ ignore-cross-compile
1010
1111use run_make_support::{
12 cwd, fs_wrapper, has_extension, has_prefix, llvm_filecheck, llvm_profdata, run_with_args,
13 rustc, shallow_find_files,
12 cwd, has_extension, has_prefix, llvm_filecheck, llvm_profdata, rfs, run_with_args, rustc,
13 shallow_find_files,
1414};
1515
1616fn main() {
......@@ -47,7 +47,7 @@ fn main() {
4747 // line with the function name before the line with the function attributes.
4848 // FileCheck only supports checking that something matches on the next line,
4949 // but not if something matches on the previous line.
50 let ir = fs_wrapper::read_to_string("main.ll");
50 let ir = rfs::read_to_string("main.ll");
5151 let lines: Vec<_> = ir.lines().rev().collect();
5252 let mut reversed_ir = lines.join("\n");
5353 reversed_ir.push('\n');
tests/run-make/prefer-dylib/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ ignore-cross-compile
22
3use run_make_support::{cwd, dynamic_lib_name, fs_wrapper, read_dir, run, run_fail, rustc};
3use run_make_support::{dynamic_lib_name, rfs, run, run_fail, rustc};
44
55fn main() {
66 rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").arg("-Cprefer-dynamic").run();
......@@ -8,7 +8,7 @@ fn main() {
88
99 run("foo");
1010
11 fs_wrapper::remove_file(dynamic_lib_name("bar"));
11 rfs::remove_file(dynamic_lib_name("bar"));
1212 // This time the command should fail.
1313 run_fail("foo");
1414}
tests/run-make/prefer-rlib/rmake.rs+3-3
......@@ -3,13 +3,13 @@
33
44//@ ignore-cross-compile
55
6use run_make_support::{dynamic_lib_name, fs_wrapper, path, run, rust_lib_name, rustc};
6use run_make_support::{dynamic_lib_name, path, rfs, run, rust_lib_name, rustc};
77
88fn main() {
99 rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").run();
1010 assert!(path(rust_lib_name("bar")).exists());
1111 rustc().input("foo.rs").run();
12 fs_wrapper::remove_file(rust_lib_name("bar"));
13 fs_wrapper::remove_file(dynamic_lib_name("bar"));
12 rfs::remove_file(rust_lib_name("bar"));
13 rfs::remove_file(dynamic_lib_name("bar"));
1414 run("foo");
1515}
tests/run-make/pretty-print-with-dep-file/rmake.rs+2-2
......@@ -5,13 +5,13 @@
55// does not get an unexpected dep-info file.
66// See https://github.com/rust-lang/rust/issues/112898
77
8use run_make_support::{fs_wrapper, invalid_utf8_contains, rustc};
8use run_make_support::{invalid_utf8_contains, rfs, rustc};
99use std::path::Path;
1010
1111fn main() {
1212 rustc().emit("dep-info").arg("-Zunpretty=expanded").input("with-dep.rs").run();
1313 invalid_utf8_contains("with-dep.d", "with-dep.rs");
14 fs_wrapper::remove_file("with-dep.d");
14 rfs::remove_file("with-dep.d");
1515 rustc().emit("dep-info").arg("-Zunpretty=normal").input("with-dep.rs").run();
1616 assert!(!Path::new("with-dep.d").exists());
1717}
tests/run-make/print-cfg/rmake.rs+2-2
......@@ -10,7 +10,7 @@ use std::ffi::OsString;
1010use std::iter::FromIterator;
1111use std::path::PathBuf;
1212
13use run_make_support::{fs_wrapper, rustc};
13use run_make_support::{rfs, rustc};
1414
1515struct PrintCfg {
1616 target: &'static str,
......@@ -96,7 +96,7 @@ fn check(PrintCfg { target, includes, disallow }: PrintCfg) {
9696
9797 rustc().target(target).arg(print_arg).run();
9898
99 let output = fs_wrapper::read_to_string(&tmp_path);
99 let output = rfs::read_to_string(&tmp_path);
100100
101101 check_(&output, includes, disallow);
102102 }
tests/run-make/print-to-output/rmake.rs+2-2
......@@ -4,7 +4,7 @@
44use std::ffi::OsString;
55use std::path::PathBuf;
66
7use run_make_support::{fs_wrapper, rustc, target};
7use run_make_support::{rfs, rustc, target};
88
99struct Option<'a> {
1010 target: &'a str,
......@@ -49,7 +49,7 @@ fn check(args: Option) {
4949
5050 rustc().target(args.target).arg(print_arg).run();
5151
52 fs_wrapper::read_to_string(&tmp_path)
52 rfs::read_to_string(&tmp_path)
5353 };
5454
5555 check_(&stdout, args.includes);
tests/run-make/remap-path-prefix/rmake.rs+5-11
......@@ -4,7 +4,7 @@
44// See https://github.com/rust-lang/rust/pull/85344
55
66use run_make_support::bstr::ByteSlice;
7use run_make_support::{bstr, fs_wrapper, is_darwin, rustc};
7use run_make_support::{bstr, is_darwin, rfs, rustc};
88
99fn main() {
1010 let mut out_simple = rustc();
......@@ -60,12 +60,9 @@ fn main() {
6060// helper functions.
6161fn rmeta_contains(expected: &str) {
6262 // Normalize to account for path differences in Windows.
63 if !bstr::BString::from(fs_wrapper::read("liblib.rmeta"))
64 .replace(b"\\", b"/")
65 .contains_str(expected)
66 {
63 if !bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) {
6764 eprintln!("=== FILE CONTENTS (LOSSY) ===");
68 eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta")));
65 eprintln!("{}", String::from_utf8_lossy(&rfs::read("liblib.rmeta")));
6966 eprintln!("=== SPECIFIED TEXT ===");
7067 eprintln!("{}", expected);
7168 panic!("specified text was not found in file");
......@@ -74,12 +71,9 @@ fn rmeta_contains(expected: &str) {
7471
7572fn rmeta_not_contains(expected: &str) {
7673 // Normalize to account for path differences in Windows.
77 if bstr::BString::from(fs_wrapper::read("liblib.rmeta"))
78 .replace(b"\\", b"/")
79 .contains_str(expected)
80 {
74 if bstr::BString::from(rfs::read("liblib.rmeta")).replace(b"\\", b"/").contains_str(expected) {
8175 eprintln!("=== FILE CONTENTS (LOSSY) ===");
82 eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta")));
76 eprintln!("{}", String::from_utf8_lossy(&rfs::read("liblib.rmeta")));
8377 eprintln!("=== SPECIFIED TEXT ===");
8478 eprintln!("{}", expected);
8579 panic!("specified text was not found in file");
tests/run-make/repr128-dwarf/rmake.rs+2-2
......@@ -3,7 +3,7 @@
33
44use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian};
55use object::{Object, ObjectSection};
6use run_make_support::{fs_wrapper, gimli, object, rustc};
6use run_make_support::{gimli, object, rfs, rustc};
77use std::collections::HashMap;
88use std::path::PathBuf;
99use std::rc::Rc;
......@@ -19,7 +19,7 @@ fn main() {
1919 .join("DWARF")
2020 .join("repr128");
2121 let output =
22 fs_wrapper::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output });
22 rfs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output });
2323 let obj = object::File::parse(output.as_slice()).unwrap();
2424 let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big };
2525 let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> {
tests/run-make/reset-codegen-1/rmake.rs+1-1
......@@ -7,7 +7,7 @@
77
88//@ ignore-cross-compile
99
10use run_make_support::{bin_name, fs_wrapper, rustc};
10use run_make_support::{bin_name, rfs, rustc};
1111use std::path::Path;
1212
1313fn compile(output_file: &str, emit: Option<&str>) {
tests/run-make/resolve-rename/rmake.rs+2-2
......@@ -5,12 +5,12 @@
55// the renamed library.
66// See https://github.com/rust-lang/rust/pull/49253
77
8use run_make_support::fs_wrapper;
8use run_make_support::rfs;
99use run_make_support::rustc;
1010
1111fn main() {
1212 rustc().extra_filename("-hash").input("foo.rs").run();
1313 rustc().input("bar.rs").run();
14 fs_wrapper::rename("libfoo-hash.rlib", "libfoo-another-hash.rlib");
14 rfs::rename("libfoo-hash.rlib", "libfoo-another-hash.rlib");
1515 rustc().input("baz.rs").run();
1616}
tests/run-make/rlib-chain/rmake.rs+4-4
......@@ -8,7 +8,7 @@
88//@ ignore-cross-compile
99// Reason: the compiled binary is executed
1010
11use run_make_support::{fs_wrapper, run, rust_lib_name, rustc};
11use run_make_support::{rfs, run, rust_lib_name, rustc};
1212
1313fn main() {
1414 rustc().input("m1.rs").run();
......@@ -16,8 +16,8 @@ fn main() {
1616 rustc().input("m3.rs").run();
1717 rustc().input("m4.rs").run();
1818 run("m4");
19 fs_wrapper::remove_file(rust_lib_name("m1"));
20 fs_wrapper::remove_file(rust_lib_name("m2"));
21 fs_wrapper::remove_file(rust_lib_name("m3"));
19 rfs::remove_file(rust_lib_name("m1"));
20 rfs::remove_file(rust_lib_name("m2"));
21 rfs::remove_file(rust_lib_name("m3"));
2222 run("m4");
2323}
tests/run-make/rustdoc-scrape-examples-remap/scrape.rs+2-2
......@@ -1,10 +1,10 @@
1use run_make_support::{fs_wrapper, htmldocck, rustc, rustdoc, source_root};
1use run_make_support::{htmldocck, rfs, rustc, rustdoc, source_root};
22use std::path::Path;
33
44pub fn scrape(extra_args: &[&str]) {
55 let out_dir = Path::new("rustdoc");
66 let crate_name = "foobar";
7 let deps = fs_wrapper::read_dir("examples")
7 let deps = rfs::read_dir("examples")
88 .filter_map(|entry| entry.ok().map(|e| e.path()))
99 .filter(|path| path.is_file() && path.extension().is_some_and(|ext| ext == "rs"))
1010 .collect::<Vec<_>>();
tests/run-make/rustdoc-test-args/rmake.rs+2-2
......@@ -1,10 +1,10 @@
1use run_make_support::{fs_wrapper, rustdoc};
1use run_make_support::{rfs, rustdoc};
22use std::iter;
33use std::path::Path;
44
55fn generate_a_lot_of_cfgs(path: &Path) {
66 let content = iter::repeat("--cfg=a\n").take(100_000).collect::<String>();
7 fs_wrapper::write(path, content.as_bytes());
7 rfs::write(path, content.as_bytes());
88}
99
1010fn main() {
tests/run-make/rustdoc-themes/rmake.rs+5-6
......@@ -1,15 +1,14 @@
11// Test that rustdoc will properly load in a theme file and display it in the theme selector.
22
3use run_make_support::{fs_wrapper, htmldocck, rustdoc, source_root};
3use run_make_support::{htmldocck, rfs, rustdoc, source_root};
44use std::path::Path;
55
66fn main() {
77 let out_dir = Path::new("rustdoc-themes");
88 let test_css = "test.css";
99
10 let no_script = fs_wrapper::read_to_string(
11 source_root().join("src/librustdoc/html/static/css/noscript.css"),
12 );
10 let no_script =
11 rfs::read_to_string(source_root().join("src/librustdoc/html/static/css/noscript.css"));
1312
1413 let mut test_content = String::new();
1514 let mut found_begin_light = false;
......@@ -24,8 +23,8 @@ fn main() {
2423 }
2524 }
2625 assert!(!test_content.is_empty());
27 fs_wrapper::create_dir_all(&out_dir);
28 fs_wrapper::write(&test_css, test_content);
26 rfs::create_dir_all(&out_dir);
27 rfs::write(&test_css, test_content);
2928
3029 rustdoc().output(&out_dir).input("foo.rs").arg("--theme").arg(&test_css).run();
3130 htmldocck().arg(out_dir).arg("foo.rs").run();
tests/run-make/rustdoc-verify-output-files/rmake.rs+5-5
......@@ -1,7 +1,7 @@
1use run_make_support::fs_wrapper::copy;
1use run_make_support::rfs;
22use std::path::{Path, PathBuf};
33
4use run_make_support::{copy_dir_all, recursive_diff, rustdoc};
4use run_make_support::{assert_dirs_are_equal, rustdoc};
55
66#[derive(PartialEq)]
77enum JsonOutput {
......@@ -26,7 +26,7 @@ fn main() {
2626 generate_docs(&out_dir, JsonOutput::No);
2727
2828 // Copy first output for to check if it's exactly same after second compilation.
29 copy_dir_all(&out_dir, &tmp_out_dir);
29 rfs::copy_dir_all(&out_dir, &tmp_out_dir);
3030
3131 // Generate html docs once again on same output.
3232 generate_docs(&out_dir, JsonOutput::No);
......@@ -38,12 +38,12 @@ fn main() {
3838 assert!(out_dir.join("foobar.json").is_file());
3939
4040 // Copy first json output to check if it's exactly same after second compilation.
41 copy(out_dir.join("foobar.json"), tmp_out_dir.join("foobar.json"));
41 rfs::copy(out_dir.join("foobar.json"), tmp_out_dir.join("foobar.json"));
4242
4343 // Generate json doc on the same output.
4444 generate_docs(&out_dir, JsonOutput::Yes);
4545
4646 // Check if all docs(including both json and html formats) are still the same after multiple
4747 // compilations.
48 recursive_diff(&out_dir, &tmp_out_dir);
48 assert_dirs_are_equal(&out_dir, &tmp_out_dir);
4949}
tests/run-make/sepcomp-cci-copies/rmake.rs+1-1
......@@ -5,7 +5,7 @@
55// See https://github.com/rust-lang/rust/pull/16367
66
77use run_make_support::{
8 count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc,
8 count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
99 shallow_find_files,
1010};
1111
tests/run-make/sepcomp-inlining/rmake.rs+1-1
......@@ -6,7 +6,7 @@
66// See https://github.com/rust-lang/rust/pull/16367
77
88use run_make_support::{
9 count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc,
9 count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
1010 shallow_find_files,
1111};
1212
tests/run-make/sepcomp-separate/rmake.rs+1-1
......@@ -4,7 +4,7 @@
44// See https://github.com/rust-lang/rust/pull/16367
55
66use run_make_support::{
7 count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc,
7 count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
88 shallow_find_files,
99};
1010
tests/run-make/silly-file-names/rmake.rs+5-5
......@@ -11,13 +11,13 @@
1111//@ ignore-windows
1212// Reason: Windows refuses files with < and > in their names
1313
14use run_make_support::{diff, fs_wrapper, run, rustc};
14use run_make_support::{diff, rfs, run, rustc};
1515
1616fn main() {
17 fs_wrapper::create_file("<leading-lt");
18 fs_wrapper::write("<leading-lt", r#""comes from a file with a name that begins with <""#);
19 fs_wrapper::create_file("trailing-gt>");
20 fs_wrapper::write("trailing-gt>", r#""comes from a file with a name that ends with >""#);
17 rfs::create_file("<leading-lt");
18 rfs::write("<leading-lt", r#""comes from a file with a name that begins with <""#);
19 rfs::create_file("trailing-gt>");
20 rfs::write("trailing-gt>", r#""comes from a file with a name that ends with >""#);
2121 rustc().input("silly-file-names.rs").output("silly-file-names").run();
2222 let out = run("silly-file-names").stdout_utf8();
2323 diff().expected_file("silly-file-names.run.stdout").actual_text("actual-stdout", out).run();
tests/run-make/symlinked-extern/rmake.rs+3-3
......@@ -11,12 +11,12 @@
1111//@ ignore-cross-compile
1212//@ needs-symlink
1313
14use run_make_support::{create_symlink, cwd, fs_wrapper, rustc};
14use run_make_support::{cwd, rfs, rustc};
1515
1616fn main() {
1717 rustc().input("foo.rs").run();
18 fs_wrapper::create_dir_all("other");
19 create_symlink("libfoo.rlib", "other");
18 rfs::create_dir_all("other");
19 rfs::create_symlink("libfoo.rlib", "other");
2020 rustc().input("bar.rs").library_search_path(cwd()).run();
2121 rustc().input("baz.rs").extern_("foo", "other").library_search_path(cwd()).run();
2222}
tests/run-make/symlinked-libraries/rmake.rs+3-3
......@@ -8,11 +8,11 @@
88//@ ignore-cross-compile
99//@ needs-symlink
1010
11use run_make_support::{create_symlink, dynamic_lib_name, fs_wrapper, rustc};
11use run_make_support::{dynamic_lib_name, rfs, rustc};
1212
1313fn main() {
1414 rustc().input("foo.rs").arg("-Cprefer-dynamic").run();
15 fs_wrapper::create_dir_all("other");
16 create_symlink(dynamic_lib_name("foo"), "other");
15 rfs::create_dir_all("other");
16 rfs::create_symlink(dynamic_lib_name("foo"), "other");
1717 rustc().input("bar.rs").library_search_path("other").run();
1818}
tests/run-make/symlinked-rlib/rmake.rs+2-2
......@@ -8,10 +8,10 @@
88//@ ignore-cross-compile
99//@ needs-symlink
1010
11use run_make_support::{create_symlink, cwd, rustc};
11use run_make_support::{cwd, rfs, rustc};
1212
1313fn main() {
1414 rustc().input("foo.rs").crate_type("rlib").output("foo.xxx").run();
15 create_symlink("foo.xxx", "libfoo.rlib");
15 rfs::create_symlink("foo.xxx", "libfoo.rlib");
1616 rustc().input("bar.rs").library_search_path(cwd()).run();
1717}
tests/run-make/target-specs/rmake.rs+4-4
......@@ -5,11 +5,11 @@
55// using them correctly, or fails with the right error message when using them improperly.
66// See https://github.com/rust-lang/rust/pull/16156
77
8use run_make_support::{diff, fs_wrapper, rustc};
8use run_make_support::{diff, rfs, rustc};
99
1010fn main() {
1111 rustc().input("foo.rs").target("my-awesome-platform.json").crate_type("lib").emit("asm").run();
12 assert!(!fs_wrapper::read_to_string("foo.s").contains("morestack"));
12 assert!(!rfs::read_to_string("foo.s").contains("morestack"));
1313 rustc()
1414 .input("foo.rs")
1515 .target("my-invalid-platform.json")
......@@ -40,8 +40,8 @@ fn main() {
4040 .print("target-spec-json")
4141 .run()
4242 .stdout_utf8();
43 fs_wrapper::create_file("test-platform.json");
44 fs_wrapper::write("test-platform.json", test_platform.as_bytes());
43 rfs::create_file("test-platform.json");
44 rfs::write("test-platform.json", test_platform.as_bytes());
4545 let test_platform_2 = rustc()
4646 .arg("-Zunstable-options")
4747 .target("test-platform.json")
tests/run-make/track-path-dep-info/rmake.rs+2-2
......@@ -4,10 +4,10 @@
44// output successfully added the file as a dependency.
55// See https://github.com/rust-lang/rust/pull/84029
66
7use run_make_support::{fs_wrapper, rustc};
7use run_make_support::{rfs, rustc};
88
99fn main() {
1010 rustc().input("macro_def.rs").run();
1111 rustc().env("EXISTING_PROC_MACRO_ENV", "1").emit("dep-info").input("macro_use.rs").run();
12 assert!(fs_wrapper::read_to_string("macro_use.d").contains("emojis.txt:"));
12 assert!(rfs::read_to_string("macro_use.d").contains("emojis.txt:"));
1313}
tests/run-make/track-pgo-dep-info/rmake.rs+2-2
......@@ -8,7 +8,7 @@
88// Reason: the binary is executed
99//@ needs-profiler-support
1010
11use run_make_support::{fs_wrapper, llvm_profdata, run, rustc};
11use run_make_support::{llvm_profdata, rfs, run, rustc};
1212
1313fn main() {
1414 // Generate the profile-guided-optimization (PGO) profiles
......@@ -19,5 +19,5 @@ fn main() {
1919 // Use the profiles in compilation
2020 rustc().profile_use("merged.profdata").emit("dep-info").input("main.rs").run();
2121 // Check that the profile file is in the dep-info emit file
22 assert!(fs_wrapper::read_to_string("main.d").contains("merged.profdata"));
22 assert!(rfs::read_to_string("main.d").contains("merged.profdata"));
2323}
tests/run-make/volatile-intrinsics/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ ignore-cross-compile
22
3use run_make_support::fs_wrapper::read;
3use run_make_support::rfs;
44use run_make_support::{assert_contains, run, rustc};
55
66fn main() {
......@@ -11,7 +11,7 @@ fn main() {
1111 // ... and the loads/stores must not be optimized out.
1212 rustc().input("main.rs").emit("llvm-ir").run();
1313
14 let raw_llvm_ir = read("main.ll");
14 let raw_llvm_ir = rfs::read("main.ll");
1515 let llvm_ir = String::from_utf8_lossy(&raw_llvm_ir);
1616 assert_contains(&llvm_ir, "load volatile");
1717 assert_contains(&llvm_ir, "store volatile");
tests/run-make/wasm-custom-section/rmake.rs+2-2
......@@ -1,13 +1,13 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::collections::HashMap;
55
66fn main() {
77 rustc().input("foo.rs").target("wasm32-wasip1").run();
88 rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
99
10 let file = fs_wrapper::read("bar.wasm");
10 let file = rfs::read("bar.wasm");
1111
1212 let mut custom = HashMap::new();
1313 for payload in wasmparser::Parser::new(0).parse_all(&file) {
tests/run-make/wasm-custom-sections-opt/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::collections::HashMap;
55use std::path::Path;
66
......@@ -12,7 +12,7 @@ fn main() {
1212
1313fn verify(path: &Path) {
1414 eprintln!("verify {path:?}");
15 let file = fs_wrapper::read(&path);
15 let file = rfs::read(&path);
1616
1717 let mut custom = HashMap::new();
1818 for payload in wasmparser::Parser::new(0).parse_all(&file) {
tests/run-make/wasm-export-all-symbols/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::collections::HashMap;
55use std::path::Path;
66use wasmparser::ExternalKind::*;
......@@ -33,7 +33,7 @@ fn test(args: &[&str]) {
3333
3434fn verify_exports(path: &Path, exports: &[(&str, wasmparser::ExternalKind)]) {
3535 println!("verify {path:?}");
36 let file = fs_wrapper::read(path);
36 let file = rfs::read(path);
3737 let mut wasm_exports = HashMap::new();
3838 for payload in wasmparser::Parser::new(0).parse_all(&file) {
3939 let payload = payload.unwrap();
tests/run-make/wasm-import-module/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::collections::HashMap;
55use wasmparser::TypeRef::Func;
66
......@@ -8,7 +8,7 @@ fn main() {
88 rustc().input("foo.rs").target("wasm32-wasip1").run();
99 rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
1010
11 let file = fs_wrapper::read("bar.wasm");
11 let file = rfs::read("bar.wasm");
1212
1313 let mut imports = HashMap::new();
1414 for payload in wasmparser::Parser::new(0).parse_all(&file) {
tests/run-make/wasm-panic-small/rmake.rs+2-2
......@@ -1,7 +1,7 @@
11//@ only-wasm32-wasip1
22#![deny(warnings)]
33
4use run_make_support::{fs_wrapper, rustc};
4use run_make_support::{rfs, rustc};
55
66fn main() {
77 test("a");
......@@ -15,7 +15,7 @@ fn test(cfg: &str) {
1515
1616 rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().cfg(cfg).run();
1717
18 let bytes = fs_wrapper::read("foo.wasm");
18 let bytes = rfs::read("foo.wasm");
1919 println!("{}", bytes.len());
2020 assert!(bytes.len() < 40_000);
2121}
tests/run-make/wasm-spurious-import/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::collections::HashMap;
55
66fn main() {
......@@ -13,7 +13,7 @@ fn main() {
1313 .arg("-Copt-level=z")
1414 .run();
1515
16 let file = fs_wrapper::read("main.wasm");
16 let file = rfs::read("main.wasm");
1717
1818 let mut imports = HashMap::new();
1919 for payload in wasmparser::Parser::new(0).parse_all(&file) {
tests/run-make/wasm-stringify-ints-small/rmake.rs+2-2
......@@ -1,12 +1,12 @@
11//@ only-wasm32-wasip1
22#![deny(warnings)]
33
4use run_make_support::{fs_wrapper, rustc};
4use run_make_support::{rfs, rustc};
55
66fn main() {
77 rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
88
9 let bytes = fs_wrapper::read("foo.wasm");
9 let bytes = rfs::read("foo.wasm");
1010 println!("{}", bytes.len());
1111 assert!(bytes.len() < 50_000);
1212}
tests/run-make/wasm-symbols-different-module/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::collections::{HashMap, HashSet};
55use std::path::Path;
66
......@@ -23,7 +23,7 @@ fn test(file: &str, args: &[&str], expected_imports: &[(&str, &[&str])]) {
2323
2424 rustc().input(file).target("wasm32-wasip1").args(args).run();
2525
26 let file = fs_wrapper::read(Path::new(file).with_extension("wasm"));
26 let file = rfs::read(Path::new(file).with_extension("wasm"));
2727
2828 let mut imports = HashMap::new();
2929 for payload in wasmparser::Parser::new(0).parse_all(&file) {
tests/run-make/wasm-symbols-not-exported/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::path::Path;
55
66fn main() {
......@@ -17,7 +17,7 @@ fn main() {
1717
1818fn verify_symbols(path: &Path) {
1919 eprintln!("verify {path:?}");
20 let file = fs_wrapper::read(&path);
20 let file = rfs::read(&path);
2121
2222 for payload in wasmparser::Parser::new(0).parse_all(&file) {
2323 let payload = payload.unwrap();
tests/run-make/wasm-symbols-not-imported/rmake.rs+2-2
......@@ -1,6 +1,6 @@
11//@ only-wasm32-wasip1
22
3use run_make_support::{fs_wrapper, rustc, wasmparser};
3use run_make_support::{rfs, rustc, wasmparser};
44use std::path::Path;
55
66fn main() {
......@@ -16,7 +16,7 @@ fn main() {
1616
1717fn verify_symbols(path: &Path) {
1818 eprintln!("verify {path:?}");
19 let file = fs_wrapper::read(&path);
19 let file = rfs::read(&path);
2020
2121 for payload in wasmparser::Parser::new(0).parse_all(&file) {
2222 let payload = payload.unwrap();
tests/run-make/weird-output-filenames/rmake.rs+3-3
......@@ -1,17 +1,17 @@
1use run_make_support::fs_wrapper::copy;
21use run_make_support::regex::Regex;
2use run_make_support::rfs;
33use run_make_support::{cwd, rustc};
44
55fn main() {
66 let invalid_characters = [".foo.rs", ".foo.bar", "+foo+bar.rs"];
77 let re = Regex::new(r"invalid character.*in crate name:").unwrap();
88 for f in invalid_characters {
9 copy("foo.rs", f);
9 rfs::copy("foo.rs", f);
1010 let stderr = rustc().input(f).run_fail().stderr_utf8();
1111 assert!(re.is_match(&stderr));
1212 }
1313
14 copy("foo.rs", "-foo.rs");
14 rfs::copy("foo.rs", "-foo.rs");
1515 rustc()
1616 .input(cwd().join("-foo.rs"))
1717 .run_fail()
tests/run-make/windows-ws2_32/rmake.rs+2-2
......@@ -3,7 +3,7 @@
33// Tests that WS2_32.dll is not unnecessarily linked, see issue #85441
44
55use run_make_support::object::{self, read::Object};
6use run_make_support::{fs_wrapper, rustc};
6use run_make_support::{rfs, rustc};
77
88fn main() {
99 rustc().input("empty.rs").run();
......@@ -14,7 +14,7 @@ fn main() {
1414}
1515
1616fn links_ws2_32(exe: &str) -> bool {
17 let binary_data = fs_wrapper::read(exe);
17 let binary_data = rfs::read(exe);
1818 let file = object::File::parse(&*binary_data).unwrap();
1919 for import in file.imports().unwrap() {
2020 if import.library().eq_ignore_ascii_case(b"WS2_32.dll") {