rust/compiler/rustc_session/src/filesearch.rs

126 lines
4.3 KiB
Rust
Raw Normal View History

2021-08-31 16:31:29 +00:00
//! A module for searching for libraries
std: Add a new `env` module This is an implementation of [RFC 578][rfc] which adds a new `std::env` module to replace most of the functionality in the current `std::os` module. More details can be found in the RFC itself, but as a summary the following methods have all been deprecated: [rfc]: https://github.com/rust-lang/rfcs/pull/578 * `os::args_as_bytes` => `env::args` * `os::args` => `env::args` * `os::consts` => `env::consts` * `os::dll_filename` => no replacement, use `env::consts` directly * `os::page_size` => `env::page_size` * `os::make_absolute` => use `env::current_dir` + `join` instead * `os::getcwd` => `env::current_dir` * `os::change_dir` => `env::set_current_dir` * `os::homedir` => `env::home_dir` * `os::tmpdir` => `env::temp_dir` * `os::join_paths` => `env::join_paths` * `os::split_paths` => `env::split_paths` * `os::self_exe_name` => `env::current_exe` * `os::self_exe_path` => use `env::current_exe` + `pop` * `os::set_exit_status` => `env::set_exit_status` * `os::get_exit_status` => `env::get_exit_status` * `os::env` => `env::vars` * `os::env_as_bytes` => `env::vars` * `os::getenv` => `env::var` or `env::var_string` * `os::getenv_as_bytes` => `env::var` * `os::setenv` => `env::set_var` * `os::unsetenv` => `env::remove_var` Many function signatures have also been tweaked for various purposes, but the main changes were: * `Vec`-returning APIs now all return iterators instead * All APIs are now centered around `OsString` instead of `Vec<u8>` or `String`. There is currently on convenience API, `env::var_string`, which can be used to get the value of an environment variable as a unicode `String`. All old APIs are `#[deprecated]` in-place and will remain for some time to allow for migrations. The semantics of the APIs have been tweaked slightly with regard to dealing with invalid unicode (panic instead of replacement). The new `std::env` module is all contained within the `env` feature, so crates must add the following to access the new APIs: #![feature(env)] [breaking-change]
2015-01-27 20:20:58 +00:00
use std::env;
use std::fs;
use std::iter::FromIterator;
use std::path::{Path, PathBuf};
use crate::search_paths::{PathKind, SearchPath};
2019-12-22 22:42:04 +00:00
use rustc_fs_util::fix_windows_verbatim_for_gcc;
2020-08-14 06:05:01 +00:00
use tracing::debug;
2015-03-30 13:38:44 +00:00
#[derive(Copy, Clone)]
pub enum FileMatch {
FileMatches,
FileDoesntMatch,
}
#[derive(Clone)]
2014-03-09 12:24:58 +00:00
pub struct FileSearch<'a> {
sysroot: &'a Path,
triple: &'a str,
search_paths: &'a [SearchPath],
tlib_path: &'a SearchPath,
kind: PathKind,
}
2014-03-09 12:24:58 +00:00
impl<'a> FileSearch<'a> {
pub fn search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
let kind = self.kind;
2019-12-22 22:42:04 +00:00
self.search_paths
.iter()
.filter(move |sp| sp.kind.matches(kind))
.chain(std::iter::once(self.tlib_path))
}
pub fn get_lib_path(&self) -> PathBuf {
make_target_lib_path(self.sysroot, self.triple)
}
2020-06-22 17:56:56 +00:00
pub fn get_self_contained_lib_path(&self) -> PathBuf {
self.get_lib_path().join("self-contained")
}
2019-12-22 22:42:04 +00:00
pub fn new(
sysroot: &'a Path,
triple: &'a str,
search_paths: &'a [SearchPath],
2019-12-22 22:42:04 +00:00
tlib_path: &'a SearchPath,
kind: PathKind,
) -> FileSearch<'a> {
debug!("using sysroot = {}, triple = {}", sysroot.display(), triple);
2019-12-22 22:42:04 +00:00
FileSearch { sysroot, triple, search_paths, tlib_path, kind }
}
2021-08-31 16:31:29 +00:00
/// Returns just the directories within the search paths.
pub fn search_path_dirs(&self) -> Vec<PathBuf> {
2019-12-22 22:42:04 +00:00
self.search_paths().map(|sp| sp.dir.to_path_buf()).collect()
}
}
pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
let rustlib_path = rustc_target::target_rustlib_path(sysroot, target_triple);
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
}
2021-08-31 16:31:29 +00:00
/// This function checks if sysroot is found using env::args().next(), and if it
/// is not found, uses env::current_exe() to imply sysroot.
pub fn get_or_default_sysroot() -> PathBuf {
// Follow symlinks. If the resolved path is relative, make it absolute.
fn canonicalize(path: PathBuf) -> PathBuf {
let path = fs::canonicalize(&path).unwrap_or(path);
// See comments on this target function, but the gist is that
// gcc chokes on verbatim paths which fs::canonicalize generates
// so we try to avoid those kinds of paths.
fix_windows_verbatim_for_gcc(&path)
}
// Use env::current_exe() to get the path of the executable following
// symlinks/canonicalizing components.
fn from_current_exe() -> PathBuf {
match env::current_exe() {
Ok(exe) => {
let mut p = canonicalize(exe);
p.pop();
p.pop();
p
}
Err(e) => panic!("failed to get current_exe: {e}"),
}
}
// Use env::args().next() to get the path of the executable without
// following symlinks/canonicalizing any component. This makes the rustc
// binary able to locate Rust libraries in systems using content-addressable
// storage (CAS).
fn from_env_args_next() -> Option<PathBuf> {
match env::args_os().next() {
Some(first_arg) => {
let mut p = PathBuf::from(first_arg);
// Check if sysroot is found using env::args().next() only if the rustc in argv[0]
// is a symlink (see #79253). We might want to change/remove it to conform with
// https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the
// future.
if fs::read_link(&p).is_err() {
// Path is not a symbolic link or does not exist.
return None;
}
// Pop off `bin/rustc`, obtaining the suspected sysroot.
p.pop();
p.pop();
// Look for the target rustlib directory in the suspected sysroot.
let mut rustlib_path = rustc_target::target_rustlib_path(&p, "dummy");
rustlib_path.pop(); // pop off the dummy target.
if rustlib_path.exists() { Some(p) } else { None }
}
None => None,
}
}
// Check if sysroot is found using env::args().next(), and if is not found,
// use env::current_exe() to imply sysroot.
2021-02-25 01:13:42 +00:00
from_env_args_next().unwrap_or_else(from_current_exe)
2011-11-10 16:41:42 +00:00
}