Skip to content

Commit

Permalink
Significantly simplify sysroot configuration (#342)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomcc authored Jun 21, 2023
1 parent 9d74dba commit 30abdea
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 122 deletions.
19 changes: 0 additions & 19 deletions plrustc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,3 @@ The use of `RUSTC_BOOTSTRAP` here is unfortunate, but at the moment things are t

Similar to `rustc`, `plrustc` is usually not invoked directly, but instead through `cargo`.

## Details

Some additional details are provided for users who intend to run PL/Rust and plrustc under restricted environments via seccomp and/or SELinux. These details are subject to change, although if that occurs it will be noted in the changelog.

### Sysroot configuration

To locate the Rust sysroot (which should have the installation of `postgrestd`), the following algorithm is used. It is very similar to the algorithm used by clippy, miri, etc. We stop at the first of these that provides a value.

1. If a `--sysroot` argument is provided via normal program arguments, then that value is used.
2. The runtime environment is checked.
1. First, for `PLRUSTC_SYSROOT` and `SYSROOT` in that order of preference.
2. Then, for rustup: If both `RUSTUP_HOME` and `RUSTUP_TOOLCHAIN` are set, then we will use the path `$RUSTUP_HOME/toolchains/$RUSTUP_TOOLCHAIN` as the sysroot.
3. If `rustc` is on the path, then `rustc --print sysroot` is invoked and that value is used.
4. The compile-time environment is checked.
1. First, for `PLRUSTC_SYSROOT` and `SYSROOT` in that order of preference.
2. Then, for rustup, if both `RUSTUP_HOME` and `RUSTUP_TOOLCHAIN` are set in the environment at runtime, then we will use the path `$RUSTUP_HOME/toolchains/$RUSTUP_TOOLCHAIN` as the sysroot.
5. If none of these were successful, an error is emitted and compilation will fail.

It's likely that a future version of plrustc will refine this to allow more control. In the short term this is impossible, howsever.
109 changes: 6 additions & 103 deletions plrustc/plrustc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ use rustc_session::early_error;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::FileLoader;
use rustc_span::Symbol;
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::path::Path;

const PLRUSTC_USER_CRATE_NAME: &str = "PLRUSTC_USER_CRATE_NAME";
const PLRUSTC_USER_CRATE_ALLOWED_SOURCE_PATHS: &str = "PLRUSTC_USER_CRATE_ALLOWED_SOURCE_PATHS";
Expand Down Expand Up @@ -52,6 +51,8 @@ impl Callbacks for PlrustcCallbacks {
}
}

// TODO: eventually we can replace this with:
// rustc_driver::install_ice_hook("https://github.com/tcdi/plrust/issues/new", |_| ());
fn install_ice_hook() {
fn report_plrustc_ice(info: &std::panic::PanicInfo<'_>, bug_report_url: &str) {
// Invoke the default panic handler to print the message and (possibly) a back trace
Expand Down Expand Up @@ -108,45 +109,14 @@ fn main() {
install_ice_hook();
rustc_driver::init_rustc_env_logger();
std::process::exit(rustc_driver::catch_with_exit_code(move || {
let orig_args: Vec<String> = std::env::args().collect();
let orig_args = rustc_driver::args::arg_expand_all(&orig_args);

let sysroot_arg = arg_value(&orig_args, "--sysroot");
let have_sysroot_arg = sysroot_arg.is_some();
let sysroot = sysroot_arg
.map(ToString::to_string)
.or_else(|| sysroot().map(|p| p.display().to_string()))
.expect("Failed to find sysroot");

let mut args: Vec<String> = orig_args.clone();

if !have_sysroot_arg {
args.extend(["--sysroot".to_string(), sysroot.to_string()]);
}

let our_exe_filename = std::env::current_exe()
.ok()
.and_then(|p| p.file_stem().map(ToOwned::to_owned))
.unwrap_or_else(|| "plrustc".into());

let wrapper_mode = orig_args
.get(1)
.map(std::path::Path::new)
.and_then(std::path::Path::file_stem)
.map_or(false, |name| {
name == our_exe_filename || name == "plrustc" || name == "rustc"
});

if wrapper_mode {
args.remove(1);
}

let args = rustc_driver::args::arg_expand_all(&std::env::args().collect::<Vec<_>>());
let config = PlrustcConfig::from_env_and_args(&args);
run_compiler(
args,
&mut PlrustcCallbacks {
// FIXME SOMEDAY: check caplints?
lints_enabled: true,
config: PlrustcConfig::from_env_and_args(&orig_args),
config,
},
);
}))
Expand Down Expand Up @@ -332,73 +302,6 @@ impl FileLoader for PlrustcFileLoader {
}
}

/// Get the sysroot, looking from most specific to this invocation to the
/// least.
///
/// - command line `--sysroot` arg (happens in caller)
///
/// - runtime environment
/// - PLRUSTC_SYSROOT
/// - SYSROOT
/// - RUSTUP_HOME, RUSTUP_TOOLCHAIN
///
/// - sysroot from rustc in the path
///
/// - compile-time environment
/// - PLRUSTC_SYSROOT
/// - SYSROOT
/// - RUSTUP_HOME, RUSTUP_TOOLCHAIN
fn sysroot() -> Option<PathBuf> {
fn rustup_sysroot<H: ?Sized + AsRef<OsStr>, T: ?Sized + AsRef<Path>>(
home: &H,
toolchain: &T,
) -> PathBuf {
let mut path = PathBuf::from(home);
path.push("toolchains");
path.push(toolchain);
path
}
fn runtime_rustup_sysroot() -> Option<PathBuf> {
let home = std::env::var_os("RUSTUP_HOME")?;
let toolchain = std::env::var_os("RUSTUP_TOOLCHAIN")?;
Some(rustup_sysroot(&home, &toolchain))
}
fn compiletime_rustup_sysroot() -> Option<PathBuf> {
let home: &str = option_env!("RUSTUP_HOME")?;
let toolchain: &str = option_env!("RUSTUP_TOOLCHAIN")?;
Some(rustup_sysroot(&home, &toolchain))
}
fn rustc_on_path_sysroot() -> Option<PathBuf> {
std::process::Command::new("rustc")
.arg("--print=sysroot")
.output()
.ok()
.and_then(|out| String::from_utf8(out.stdout).ok())
.map(|s| PathBuf::from(s.trim()))
}
fn runtime_explicit_env() -> Option<PathBuf> {
let sysroot =
std::env::var_os("PLRUSTC_SYSROOT").or_else(|| std::env::var_os("SYSROOT"))?;
Some(PathBuf::from(sysroot))
}
fn compiletime_explicit_env() -> Option<PathBuf> {
let plrustc_sysroot: Option<&str> = option_env!("PLRUSTC_SYSROOT");
if let Some(plrustc_sysroot) = plrustc_sysroot {
return Some(plrustc_sysroot.into());
}
let sysroot: Option<&str> = option_env!("SYSROOT");
if let Some(sysroot) = sysroot {
return Some(sysroot.into());
}
None
}
runtime_explicit_env()
.or_else(runtime_rustup_sysroot)
.or_else(rustc_on_path_sysroot)
.or_else(compiletime_explicit_env)
.or_else(compiletime_rustup_sysroot)
}

fn run_compiler(mut args: Vec<String>, callbacks: &mut PlrustcCallbacks) -> ! {
args.splice(1..1, std::iter::once("--cfg=plrustc".to_string()));

Expand Down

0 comments on commit 30abdea

Please sign in to comment.