xargo_lib/
xargo.rs

1use std::env;
2use std::mem;
3use std::path::Path;
4use std::path::{Display, PathBuf};
5use std::process::{Command, ExitStatus};
6
7use anyhow::{Context, Result};
8use rustc_version::VersionMeta;
9
10use crate::cargo::Rustflags;
11use crate::cli::Args;
12use crate::config::Config;
13use crate::extensions::CommandExt;
14use crate::flock::{FileLock, Filesystem};
15use crate::CompilationMode;
16
17pub fn run(
18    args: &Args,
19    cmode: &CompilationMode,
20    rustflags: Rustflags,
21    home: &Home,
22    meta: &VersionMeta,
23    command_name: &str,
24    verbose: bool,
25) -> Result<ExitStatus> {
26    let cargo = std::env::var("CARGO").unwrap_or("cargo".to_string());
27    let mut cmd = Command::new(cargo);
28    cmd.arg(command_name);
29    cmd.args(args.all());
30
31    let flags = rustflags.for_xargo(home)?;
32    if verbose {
33        eprintln!("+ RUSTFLAGS={:?}", flags);
34        eprintln!("+ RUSTDOCFLAGS={:?}", flags);
35    }
36    cmd.env("RUSTFLAGS", &flags);
37    cmd.env("RUSTDOCFLAGS", &flags);
38
39    let locks = (home.lock_ro(&meta.host), home.lock_ro(cmode.triple()));
40
41    let status = cmd.run_and_get_status(verbose)?;
42
43    mem::drop(locks);
44
45    Ok(status)
46}
47
48pub struct Home {
49    path: Filesystem,
50}
51
52impl Home {
53    pub fn display(&self) -> Display {
54        self.path.display()
55    }
56
57    fn path(&self, triple: &str) -> Filesystem {
58        self.path.join("lib").join("rustlib").join(triple)
59    }
60
61    pub fn lock_ro(&self, triple: &str) -> Result<FileLock> {
62        let fs = self.path(triple);
63
64        fs.open_ro(".sentinel", &format!("{}'s sysroot", triple))
65            .with_context(|| format!("couldn't lock {}'s sysroot as read-only", triple))
66    }
67
68    pub fn lock_rw(&self, triple: &str) -> Result<FileLock> {
69        let fs = self.path(triple);
70
71        fs.open_rw(".sentinel", &format!("{}'s sysroot", triple))
72            .with_context(|| {
73                format!(
74                    "couldn't lock {}'s sysroot in {} as read-write",
75                    triple,
76                    fs.display()
77                )
78            })
79    }
80}
81
82pub fn home(root: &Path, config: &Config, quiet: bool) -> Result<Home> {
83    let path = if let Ok(path) = env::var("XBUILD_SYSROOT_PATH") {
84        PathBuf::from(path)
85    } else {
86        let mut path = PathBuf::from(root);
87        path.push(&config.sysroot_path);
88        path
89    };
90
91    Ok(Home {
92        path: Filesystem::new(path, quiet),
93    })
94}