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