Use std::path::absolute
in bootstrap
This commit is contained in:
parent
7ac6c2fc68
commit
78d4802448
@ -10,7 +10,7 @@
|
|||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::IsTerminal;
|
use std::io::IsTerminal;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{absolute, Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
@ -1437,7 +1437,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
|
|||||||
// To avoid writing to random places on the file system, `config.out` needs to be an absolute path.
|
// To avoid writing to random places on the file system, `config.out` needs to be an absolute path.
|
||||||
if !config.out.is_absolute() {
|
if !config.out.is_absolute() {
|
||||||
// `canonicalize` requires the path to already exist. Use our vendored copy of `absolute` instead.
|
// `canonicalize` requires the path to already exist. Use our vendored copy of `absolute` instead.
|
||||||
config.out = crate::utils::helpers::absolute(&config.out);
|
config.out = absolute(&config.out).expect("can't make empty path absolute");
|
||||||
}
|
}
|
||||||
|
|
||||||
config.initial_rustc = if let Some(rustc) = rustc {
|
config.initial_rustc = if let Some(rustc) = rustc {
|
||||||
|
@ -331,115 +331,6 @@ fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copied from `std::path::absolute` until it stabilizes.
|
|
||||||
///
|
|
||||||
/// FIXME: this shouldn't exist.
|
|
||||||
pub(crate) fn absolute(path: &Path) -> PathBuf {
|
|
||||||
if path.as_os_str().is_empty() {
|
|
||||||
panic!("can't make empty path absolute");
|
|
||||||
}
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
t!(absolute_unix(path), format!("could not make path absolute: {}", path.display()))
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
t!(absolute_windows(path), format!("could not make path absolute: {}", path.display()))
|
|
||||||
}
|
|
||||||
#[cfg(not(any(unix, windows)))]
|
|
||||||
{
|
|
||||||
println!("WARNING: bootstrap is not supported on non-unix platforms");
|
|
||||||
t!(std::fs::canonicalize(t!(std::env::current_dir()))).join(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
/// Make a POSIX path absolute without changing its semantics.
|
|
||||||
fn absolute_unix(path: &Path) -> io::Result<PathBuf> {
|
|
||||||
// This is mostly a wrapper around collecting `Path::components`, with
|
|
||||||
// exceptions made where this conflicts with the POSIX specification.
|
|
||||||
// See 4.13 Pathname Resolution, IEEE Std 1003.1-2017
|
|
||||||
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
|
||||||
|
|
||||||
use std::os::unix::prelude::OsStrExt;
|
|
||||||
let mut components = path.components();
|
|
||||||
let path_os = path.as_os_str().as_bytes();
|
|
||||||
|
|
||||||
let mut normalized = if path.is_absolute() {
|
|
||||||
// "If a pathname begins with two successive <slash> characters, the
|
|
||||||
// first component following the leading <slash> characters may be
|
|
||||||
// interpreted in an implementation-defined manner, although more than
|
|
||||||
// two leading <slash> characters shall be treated as a single <slash>
|
|
||||||
// character."
|
|
||||||
if path_os.starts_with(b"//") && !path_os.starts_with(b"///") {
|
|
||||||
components.next();
|
|
||||||
PathBuf::from("//")
|
|
||||||
} else {
|
|
||||||
PathBuf::new()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
env::current_dir()?
|
|
||||||
};
|
|
||||||
normalized.extend(components);
|
|
||||||
|
|
||||||
// "Interfaces using pathname resolution may specify additional constraints
|
|
||||||
// when a pathname that does not name an existing directory contains at
|
|
||||||
// least one non- <slash> character and contains one or more trailing
|
|
||||||
// <slash> characters".
|
|
||||||
// A trailing <slash> is also meaningful if "a symbolic link is
|
|
||||||
// encountered during pathname resolution".
|
|
||||||
|
|
||||||
if path_os.ends_with(b"/") {
|
|
||||||
normalized.push("");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(normalized)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn absolute_windows(path: &std::path::Path) -> std::io::Result<std::path::PathBuf> {
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::io::Error;
|
|
||||||
use std::os::windows::ffi::{OsStrExt, OsStringExt};
|
|
||||||
use std::ptr::null_mut;
|
|
||||||
#[link(name = "kernel32")]
|
|
||||||
extern "system" {
|
|
||||||
fn GetFullPathNameW(
|
|
||||||
lpFileName: *const u16,
|
|
||||||
nBufferLength: u32,
|
|
||||||
lpBuffer: *mut u16,
|
|
||||||
lpFilePart: *mut *const u16,
|
|
||||||
) -> u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
// encode the path as UTF-16
|
|
||||||
let path: Vec<u16> = path.as_os_str().encode_wide().chain([0]).collect();
|
|
||||||
let mut buffer = Vec::new();
|
|
||||||
// Loop until either success or failure.
|
|
||||||
loop {
|
|
||||||
// Try to get the absolute path
|
|
||||||
let len = GetFullPathNameW(
|
|
||||||
path.as_ptr(),
|
|
||||||
buffer.len().try_into().unwrap(),
|
|
||||||
buffer.as_mut_ptr(),
|
|
||||||
null_mut(),
|
|
||||||
);
|
|
||||||
match len as usize {
|
|
||||||
// Failure
|
|
||||||
0 => return Err(Error::last_os_error()),
|
|
||||||
// Buffer is too small, resize.
|
|
||||||
len if len > buffer.len() => buffer.resize(len, 0),
|
|
||||||
// Success!
|
|
||||||
len => {
|
|
||||||
buffer.truncate(len);
|
|
||||||
return Ok(OsString::from_wide(&buffer).into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adapted from <https://github.com/llvm/llvm-project/blob/782e91224601e461c019e0a4573bbccc6094fbcd/llvm/cmake/modules/HandleLLVMOptions.cmake#L1058-L1079>
|
/// Adapted from <https://github.com/llvm/llvm-project/blob/782e91224601e461c019e0a4573bbccc6094fbcd/llvm/cmake/modules/HandleLLVMOptions.cmake#L1058-L1079>
|
||||||
///
|
///
|
||||||
/// When `clang-cl` is used with instrumentation, we need to add clang's runtime library resource
|
/// When `clang-cl` is used with instrumentation, we need to add clang's runtime library resource
|
||||||
|
@ -25,27 +25,6 @@ fn test_make() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
#[test]
|
|
||||||
fn test_absolute_unix() {
|
|
||||||
use crate::utils::helpers::absolute_unix;
|
|
||||||
|
|
||||||
// Test an absolute path
|
|
||||||
let path = PathBuf::from("/home/user/file.txt");
|
|
||||||
assert_eq!(absolute_unix(&path).unwrap(), PathBuf::from("/home/user/file.txt"));
|
|
||||||
|
|
||||||
// Test an absolute path with double leading slashes
|
|
||||||
let path = PathBuf::from("//root//file.txt");
|
|
||||||
assert_eq!(absolute_unix(&path).unwrap(), PathBuf::from("//root/file.txt"));
|
|
||||||
|
|
||||||
// Test a relative path
|
|
||||||
let path = PathBuf::from("relative/path");
|
|
||||||
assert_eq!(
|
|
||||||
absolute_unix(&path).unwrap(),
|
|
||||||
std::env::current_dir().unwrap().join("relative/path")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_beta_rev_parsing() {
|
fn test_beta_rev_parsing() {
|
||||||
// single digit revision
|
// single digit revision
|
||||||
|
Loading…
Reference in New Issue
Block a user