-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reorganize the run-make-support
library
#127760
Changes from all commits
427cf94
544dda3
a02008e
288c572
f042e72
439c6f6
483328d
dc95315
17212ab
66cef19
f66d3d3
230804d
56cbfa8
88fd1df
e956808
aadd085
b7f7205
a443dc4
13a1751
e1569fd
636be91
0dfecb3
57a2f76
30bdc4a
a00b860
1f1bf4c
d69cc1c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
//! A collection of helpers to construct artifact names, such as names of dynamic or static | ||
//! librarys which are target-dependent. | ||
|
||
use crate::targets::{is_darwin, is_msvc, is_windows}; | ||
|
||
/// Construct the static library name based on the target. | ||
#[must_use] | ||
pub fn static_lib_name(name: &str) -> String { | ||
// See tools.mk (irrelevant lines omitted): | ||
// | ||
// ```makefile | ||
// ifeq ($(UNAME),Darwin) | ||
// STATICLIB = $(TMPDIR)/lib$(1).a | ||
// else | ||
// ifdef IS_WINDOWS | ||
// ifdef IS_MSVC | ||
// STATICLIB = $(TMPDIR)/$(1).lib | ||
// else | ||
// STATICLIB = $(TMPDIR)/lib$(1).a | ||
// endif | ||
// else | ||
// STATICLIB = $(TMPDIR)/lib$(1).a | ||
// endif | ||
// endif | ||
// ``` | ||
assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace"); | ||
|
||
if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") } | ||
} | ||
|
||
/// Construct the dynamic library name based on the target. | ||
#[must_use] | ||
pub fn dynamic_lib_name(name: &str) -> String { | ||
// See tools.mk (irrelevant lines omitted): | ||
// | ||
// ```makefile | ||
// ifeq ($(UNAME),Darwin) | ||
// DYLIB = $(TMPDIR)/lib$(1).dylib | ||
// else | ||
// ifdef IS_WINDOWS | ||
// DYLIB = $(TMPDIR)/$(1).dll | ||
// else | ||
// DYLIB = $(TMPDIR)/lib$(1).so | ||
// endif | ||
// endif | ||
// ``` | ||
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace"); | ||
|
||
let extension = dynamic_lib_extension(); | ||
if is_darwin() { | ||
format!("lib{name}.{extension}") | ||
} else if is_windows() { | ||
format!("{name}.{extension}") | ||
} else { | ||
format!("lib{name}.{extension}") | ||
} | ||
} | ||
|
||
/// Construct the dynamic library extension based on the target. | ||
#[must_use] | ||
pub fn dynamic_lib_extension() -> &'static str { | ||
if is_darwin() { | ||
"dylib" | ||
} else if is_windows() { | ||
"dll" | ||
} else { | ||
"so" | ||
} | ||
} | ||
|
||
/// Construct the name of a rust library (rlib). | ||
#[must_use] | ||
pub fn rust_lib_name(name: &str) -> String { | ||
format!("lib{name}.rlib") | ||
} | ||
|
||
/// Construct the binary (executable) name based on the target. | ||
#[must_use] | ||
pub fn bin_name(name: &str) -> String { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (preexisting) this could use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing that out 👍, I'll address these in a follow-up PR. I want to keep this PR mostly just moving code around. |
||
if is_windows() { format!("{name}.exe") } else { name.to_string() } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
//! Collection of assertions and assertion-related helpers. | ||
|
||
use std::panic; | ||
use std::path::Path; | ||
|
||
use crate::fs; | ||
|
||
/// Assert that `actual` is equal to `expected`. | ||
#[track_caller] | ||
pub fn assert_equals<A: AsRef<str>, E: AsRef<str>>(actual: A, expected: E) { | ||
let actual = actual.as_ref(); | ||
let expected = expected.as_ref(); | ||
if actual != expected { | ||
eprintln!("=== ACTUAL TEXT ==="); | ||
eprintln!("{}", actual); | ||
eprintln!("=== EXPECTED ==="); | ||
eprintln!("{}", expected); | ||
panic!("expected text was not found in actual text"); | ||
} | ||
} | ||
|
||
/// Assert that `haystack` contains `needle`. | ||
#[track_caller] | ||
pub fn assert_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) { | ||
let haystack = haystack.as_ref(); | ||
let needle = needle.as_ref(); | ||
if !haystack.contains(needle) { | ||
eprintln!("=== HAYSTACK ==="); | ||
eprintln!("{}", haystack); | ||
eprintln!("=== NEEDLE ==="); | ||
eprintln!("{}", needle); | ||
panic!("needle was not found in haystack"); | ||
} | ||
} | ||
|
||
/// Assert that `haystack` does not contain `needle`. | ||
#[track_caller] | ||
pub fn assert_not_contains<H: AsRef<str>, N: AsRef<str>>(haystack: H, needle: N) { | ||
let haystack = haystack.as_ref(); | ||
let needle = needle.as_ref(); | ||
if haystack.contains(needle) { | ||
eprintln!("=== HAYSTACK ==="); | ||
eprintln!("{}", haystack); | ||
eprintln!("=== NEEDLE ==="); | ||
eprintln!("{}", needle); | ||
panic!("needle was unexpectedly found in haystack"); | ||
} | ||
} | ||
|
||
/// Assert that all files in `dir1` exist and have the same content in `dir2` | ||
jieyouxu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub fn assert_dirs_are_equal(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) { | ||
let dir2 = dir2.as_ref(); | ||
fs::read_dir_entries(dir1, |entry_path| { | ||
let entry_name = entry_path.file_name().unwrap(); | ||
if entry_path.is_dir() { | ||
assert_dirs_are_equal(&entry_path, &dir2.join(entry_name)); | ||
} else { | ||
let path2 = dir2.join(entry_name); | ||
let file1 = fs::read(&entry_path); | ||
let file2 = fs::read(&path2); | ||
|
||
// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display. | ||
// Why not using String? Because there might be minified files or even potentially | ||
// binary ones, so that would display useless output. | ||
assert!( | ||
file1 == file2, | ||
"`{}` and `{}` have different content", | ||
entry_path.display(), | ||
path2.display(), | ||
); | ||
} | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use std::ffi::OsString; | ||
|
||
#[track_caller] | ||
#[must_use] | ||
pub fn env_var(name: &str) -> String { | ||
match std::env::var(name) { | ||
Ok(v) => v, | ||
Err(err) => panic!("failed to retrieve environment variable {name:?}: {err:?}"), | ||
} | ||
} | ||
|
||
#[track_caller] | ||
#[must_use] | ||
pub fn env_var_os(name: &str) -> OsString { | ||
match std::env::var_os(name) { | ||
Some(v) => v, | ||
None => panic!("failed to retrieve environment variable {name:?}"), | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use std::path::PathBuf; | ||
|
||
use crate::artifact_names::static_lib_name; | ||
use crate::external_deps::cc::cc; | ||
use crate::external_deps::llvm::llvm_ar; | ||
use crate::path_helpers::path; | ||
use crate::targets::is_msvc; | ||
|
||
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name. | ||
#[track_caller] | ||
pub fn build_native_static_lib(lib_name: &str) -> PathBuf { | ||
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") }; | ||
let src = format!("{lib_name}.c"); | ||
let lib_path = static_lib_name(lib_name); | ||
if is_msvc() { | ||
cc().arg("-c").out_exe(&obj_file).input(src).run(); | ||
} else { | ||
cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run(); | ||
}; | ||
let obj_file = if is_msvc() { | ||
PathBuf::from(format!("{lib_name}.obj")) | ||
} else { | ||
PathBuf::from(format!("{lib_name}.o")) | ||
}; | ||
llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run(); | ||
path(lib_path) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use std::panic; | ||
use std::path::Path; | ||
|
||
use crate::command::Command; | ||
use crate::util::handle_failed_output; | ||
|
||
/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is | ||
/// available on the platform! | ||
/// | ||
/// # FIXME | ||
/// | ||
/// FIXME(jieyouxu): we should consider not depending on `cygpath`. | ||
/// | ||
/// > The cygpath program is a utility that converts Windows native filenames to Cygwin POSIX-style | ||
/// > pathnames and vice versa. | ||
/// > | ||
/// > [irrelevant entries omitted...] | ||
/// > | ||
/// > `-w, --windows print Windows form of NAMEs (C:\WINNT)` | ||
/// > | ||
/// > -- *from [cygpath documentation](https://cygwin.com/cygwin-ug-net/cygpath.html)*. | ||
#[track_caller] | ||
#[must_use] | ||
pub fn get_windows_path<P: AsRef<Path>>(path: P) -> String { | ||
let caller = panic::Location::caller(); | ||
let mut cygpath = Command::new("cygpath"); | ||
cygpath.arg("-w"); | ||
cygpath.arg(path.as_ref()); | ||
let output = cygpath.run(); | ||
if !output.status().success() { | ||
handle_failed_output(&cygpath, output, caller.line()); | ||
} | ||
// cygpath -w can attach a newline | ||
output.stdout_utf8().trim().to_string() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
use crate::command::Command; | ||
use crate::source_root; | ||
|
||
use super::python::python_command; | ||
|
||
/// `htmldocck` is a python script which is used for rustdoc test suites, it is assumed to be | ||
/// available at `$SOURCE_ROOT/src/etc/htmldocck.py`. | ||
#[track_caller] | ||
#[must_use] | ||
pub fn htmldocck() -> Command { | ||
let mut python = python_command(); | ||
python.arg(source_root().join("src/etc/htmldocck.py")); | ||
python | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(preexisting) this could be replaced with
std::env::consts::DLL_EXTENSION