From 86a692ebb5b82111f1a104473344341751c3cf82 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 13 Nov 2019 19:02:26 -0500 Subject: [PATCH 01/17] Add `cargo_mode` option to `Xargo.toml` This allows configuring Xargo to run `cargo check` instead of `cargo build` Needed to support https://github.com/rust-lang/miri/pull/1048 --- README.md | 15 +++++++++++++++ src/sysroot.rs | 34 ++++++++++++++++++++++++++++++++-- src/xargo.rs | 5 +++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 65facb0..b3b8f0f 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,21 @@ git = "https://github.com/japaric/steed" stage = 2 ``` +## Cargo mode + +Xaro supports configuring the mode in which `cargo` is invoked. +The current options are `build` (the default), and `check`. This +is used to determine which `cargo` subcommand will be invoked - either +`build` or `check`. + +This is set via the `cargo_mode` entry in `Xargo.toml`: + +``` toml +cargo_mode = "check" +``` + +`build` is almost always what you want. + ## Caveats / gotchas - Xargo won't build a sysroot when used with stable or beta Rust. This is diff --git a/src/sysroot.rs b/src/sysroot.rs index e8a2715..3d3d8c7 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -76,6 +76,9 @@ version = "0.0.0" } } + // Copy `cargo_mode` so that we can access it after + // moving out of `blueprint` + let cargo_mode = blueprint.cargo_mode; for (_, stage) in blueprint.stages { let td = TempDir::new("xargo").chain_err(|| "couldn't create a temporary directory")?; let tdp; @@ -165,7 +168,10 @@ version = "0.0.0" } } - cmd.arg("build"); + match cargo_mode { + CargoMode::Build => cmd.arg("build"), + CargoMode::Check => cmd.arg("check") + }; match () { #[cfg(feature = "dev")] @@ -344,10 +350,19 @@ pub struct Stage { patch: Table, } +/// Which mode to invoke `cargo` in when building the sysroot +/// Can be either `cargo build` or `cargo check` +#[derive(Copy, Clone, Debug)] +enum CargoMode { + Build, + Check +} + /// A sysroot that will be built in "stages" #[derive(Debug)] pub struct Blueprint { stages: BTreeMap, + cargo_mode: CargoMode } trait AsTableMut { @@ -378,6 +393,7 @@ impl Blueprint { fn new() -> Self { Blueprint { stages: BTreeMap::new(), + cargo_mode: CargoMode::Build } } @@ -432,6 +448,21 @@ impl Blueprint { Ok(()) } + let mut blueprint = Blueprint::new(); + + // Get `cargo_mode` from `Xargo.toml` + if let Some(value) = toml.and_then(xargo::Toml::cargo_mode) { + let val = value.as_str() + .ok_or_else(|| format!("`cargo_mode` must be a string"))?; + + let mode = match val { + "check" => CargoMode::Check, + "build" => CargoMode::Build, + _ => Err(format!("`cargo_mode` must be either `check` or `build`"))? + }; + blueprint.cargo_mode = mode; + } + // Compose patch section let mut patch = match toml.and_then(xargo::Toml::patch) { Some(value) => value @@ -514,7 +545,6 @@ impl Blueprint { } }; - let mut blueprint = Blueprint::new(); for (k, v) in deps { if let Value::Table(mut map) = v { let stage = if let Some(value) = map.remove("stage") { diff --git a/src/xargo.rs b/src/xargo.rs index c56d203..5dd65d3 100644 --- a/src/xargo.rs +++ b/src/xargo.rs @@ -118,6 +118,11 @@ impl Toml { pub fn patch(&self) -> Option<&Value> { self.table.lookup("patch") } + + /// Returns the `cargo_mode` part of `Xargo.toml` + pub fn cargo_mode(&self) -> Option<&Value> { + self.table.lookup("cargo_mode") + } } /// Returns the closest directory containing a 'Xargo.toml' and the parsed From 9e3b98e2b9050238d90aa5842ecf890d5bd513c7 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 28 Nov 2019 14:42:43 -0500 Subject: [PATCH 02/17] Switch to new 'xargo-check' binary --- src/main.rs | 221 ------------------------------------------------- src/sysroot.rs | 27 ++---- src/xargo.rs | 5 -- 3 files changed, 6 insertions(+), 247 deletions(-) delete mode 100644 src/main.rs diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 908336d..0000000 --- a/src/main.rs +++ /dev/null @@ -1,221 +0,0 @@ -#![deny(warnings)] - -#[macro_use] -extern crate error_chain; -extern crate fs2; -#[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "macos"))] -extern crate libc; -extern crate rustc_version; -extern crate serde_json; -extern crate tempdir; -extern crate toml; -extern crate walkdir; -extern crate dirs; - -use std::hash::{Hash, Hasher}; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::process::ExitStatus; -use std::{env, io, process}; - -use rustc_version::Channel; - -use errors::*; -use rustc::Target; - -mod cargo; -mod cli; -mod errors; -mod extensions; -mod flock; -mod rustc; -mod sysroot; -mod util; -mod xargo; - -// We use a different sysroot for Native compilation to avoid file locking -// -// Cross compilation requires `lib/rustlib/$HOST` to match `rustc`'s sysroot, -// whereas Native compilation wants to use a custom `lib/rustlib/$HOST`. If each -// mode has its own sysroot then we avoid sharing that directory and thus file -// locking it. -pub enum CompilationMode { - Cross(Target), - Native(String), -} - -impl CompilationMode { - fn hash(&self, hasher: &mut H) -> Result<()> - where - H: Hasher, - { - match *self { - CompilationMode::Cross(ref target) => target.hash(hasher)?, - CompilationMode::Native(ref triple) => triple.hash(hasher), - } - - Ok(()) - } - - fn triple(&self) -> &str { - match *self { - CompilationMode::Cross(ref target) => target.triple(), - CompilationMode::Native(ref triple) => triple, - } - } - - fn is_native(&self) -> bool { - match *self { - CompilationMode::Native(_) => true, - _ => false, - } - } -} - -pub fn main() { - fn show_backtrace() -> bool { - env::var("RUST_BACKTRACE").as_ref().map(|s| &s[..]) == Ok("1") - } - - match run() { - Err(e) => { - let stderr = io::stderr(); - let mut stderr = stderr.lock(); - - writeln!(stderr, "error: {}", e).ok(); - - for e in e.iter().skip(1) { - writeln!(stderr, "caused by: {}", e).ok(); - } - - if show_backtrace() { - if let Some(backtrace) = e.backtrace() { - writeln!(stderr, "{:?}", backtrace).ok(); - } - } else { - writeln!(stderr, "note: run with `RUST_BACKTRACE=1` for a backtrace").ok(); - } - - process::exit(1) - } - Ok(status) => if !status.success() { - process::exit(status.code().unwrap_or(1)) - }, - } -} - -fn run() -> Result { - let args = cli::args(); - let verbose = args.verbose(); - - let meta = rustc::version(); - - if let Some(sc) = args.subcommand() { - if !sc.needs_sysroot() { - return cargo::run(&args, verbose); - } - } else if args.version() { - writeln!( - io::stderr(), - concat!("xargo ", env!("CARGO_PKG_VERSION"), "{}"), - include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt")) - ).ok(); - - return cargo::run(&args, verbose); - } - - let cd = CurrentDirectory::get()?; - - let config = cargo::config()?; - if let Some(root) = cargo::root()? { - // We can't build sysroot with stable or beta due to unstable features - let sysroot = rustc::sysroot(verbose)?; - let src = match meta.channel { - Channel::Dev => rustc::Src::from_env().ok_or( - "The XARGO_RUST_SRC env variable must be set and point to the \ - Rust source directory when working with the 'dev' channel", - )?, - Channel::Nightly => if let Some(src) = rustc::Src::from_env() { - src - } else { - sysroot.src()? - }, - Channel::Stable | Channel::Beta => { - writeln!( - io::stderr(), - "WARNING: the sysroot can't be built for the {:?} channel. \ - Switch to nightly.", - meta.channel - ).ok(); - return cargo::run(&args, verbose); - } - }; - - let cmode = if let Some(triple) = args.target() { - if Path::new(triple).is_file() { - bail!( - "Xargo doesn't support files as an argument to --target. \ - Use `--target foo` instead of `--target foo.json`." - ) - } else if triple == meta.host { - Some(CompilationMode::Native(meta.host.clone())) - } else { - Target::new(triple, &cd, verbose)?.map(CompilationMode::Cross) - } - } else { - if let Some(ref config) = config { - if let Some(triple) = config.target()? { - Target::new(triple, &cd, verbose)?.map(CompilationMode::Cross) - } else { - Some(CompilationMode::Native(meta.host.clone())) - } - } else { - Some(CompilationMode::Native(meta.host.clone())) - } - }; - - if let Some(cmode) = cmode { - let home = xargo::home(&cmode)?; - let rustflags = cargo::rustflags(config.as_ref(), cmode.triple())?; - - sysroot::update( - &cmode, - &home, - &root, - &rustflags, - &meta, - &src, - &sysroot, - verbose, - args.message_format() - )?; - return xargo::run( - &args, - &cmode, - rustflags, - &home, - &meta, - config.as_ref(), - verbose, - ); - } - } - - cargo::run(&args, verbose) -} - -pub struct CurrentDirectory { - path: PathBuf, -} - -impl CurrentDirectory { - fn get() -> Result { - env::current_dir() - .chain_err(|| "couldn't get the current directory") - .map(|cd| CurrentDirectory { path: cd }) - } - - fn path(&self) -> &Path { - &self.path - } -} diff --git a/src/sysroot.rs b/src/sysroot.rs index 3d3d8c7..09c9779 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -38,7 +38,8 @@ fn build( sysroot: &Sysroot, hash: u64, verbose: bool, - message_format: Option<&str> + message_format: Option<&str>, + cargo_mode: CargoMode ) -> Result<()> { const TOML: &'static str = r#" [package] @@ -76,9 +77,6 @@ version = "0.0.0" } } - // Copy `cargo_mode` so that we can access it after - // moving out of `blueprint` - let cargo_mode = blueprint.cargo_mode; for (_, stage) in blueprint.stages { let td = TempDir::new("xargo").chain_err(|| "couldn't create a temporary directory")?; let tdp; @@ -271,7 +269,8 @@ pub fn update( src: &Src, sysroot: &Sysroot, verbose: bool, - message_format: Option<&str> + message_format: Option<&str>, + cargo_mode: CargoMode ) -> Result<()> { let ctoml = cargo::toml(root)?; let (xtoml_parent, xtoml) = xargo::toml(root)?; @@ -298,6 +297,7 @@ pub fn update( hash, verbose, message_format, + cargo_mode )?; } @@ -353,7 +353,7 @@ pub struct Stage { /// Which mode to invoke `cargo` in when building the sysroot /// Can be either `cargo build` or `cargo check` #[derive(Copy, Clone, Debug)] -enum CargoMode { +pub enum CargoMode { Build, Check } @@ -362,7 +362,6 @@ enum CargoMode { #[derive(Debug)] pub struct Blueprint { stages: BTreeMap, - cargo_mode: CargoMode } trait AsTableMut { @@ -393,7 +392,6 @@ impl Blueprint { fn new() -> Self { Blueprint { stages: BTreeMap::new(), - cargo_mode: CargoMode::Build } } @@ -450,19 +448,6 @@ impl Blueprint { let mut blueprint = Blueprint::new(); - // Get `cargo_mode` from `Xargo.toml` - if let Some(value) = toml.and_then(xargo::Toml::cargo_mode) { - let val = value.as_str() - .ok_or_else(|| format!("`cargo_mode` must be a string"))?; - - let mode = match val { - "check" => CargoMode::Check, - "build" => CargoMode::Build, - _ => Err(format!("`cargo_mode` must be either `check` or `build`"))? - }; - blueprint.cargo_mode = mode; - } - // Compose patch section let mut patch = match toml.and_then(xargo::Toml::patch) { Some(value) => value diff --git a/src/xargo.rs b/src/xargo.rs index 5dd65d3..c56d203 100644 --- a/src/xargo.rs +++ b/src/xargo.rs @@ -118,11 +118,6 @@ impl Toml { pub fn patch(&self) -> Option<&Value> { self.table.lookup("patch") } - - /// Returns the `cargo_mode` part of `Xargo.toml` - pub fn cargo_mode(&self) -> Option<&Value> { - self.table.lookup("cargo_mode") - } } /// Returns the closest directory containing a 'Xargo.toml' and the parsed From d1fff25376ee95b96a6fcf8b43bf217ee5ba1f76 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 28 Nov 2019 14:52:35 -0500 Subject: [PATCH 03/17] Update README, add test --- README.md | 21 +++++++++------------ tests/smoke.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b3b8f0f..b6ef2ca 100644 --- a/README.md +++ b/README.md @@ -309,20 +309,17 @@ git = "https://github.com/japaric/steed" stage = 2 ``` -## Cargo mode +## Cargo subcommand -Xaro supports configuring the mode in which `cargo` is invoked. -The current options are `build` (the default), and `check`. This -is used to determine which `cargo` subcommand will be invoked - either -`build` or `check`. +Xargo supports performing a 'check build' of the syroot +via the `xargo-check` command. This command is invoked exactly +like `xargo`, but will invoke `cargo check` instead of `cargo build` +when building the sysroot. -This is set via the `cargo_mode` entry in `Xargo.toml`: - -``` toml -cargo_mode = "check" -``` - -`build` is almost always what you want. +This is only useful for very specialized applicationsm like Miri. +The resulting libstd will *not* be useable in a normal build, since codegen +will not be performed. You should almost always run `xargo check` (note the space), +which will perform a normal sysroot build, followed by a 'check' build of *your application* ## Caveats / gotchas diff --git a/tests/smoke.rs b/tests/smoke.rs index 7610869..9f49894 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -121,6 +121,14 @@ fn xargo() -> Result { Ok(Command::new(p)) } +fn xargo_check() -> Result { + let mut p = env::current_exe().chain_err(|| "couldn't get path to current executable")?; + p.pop(); + p.pop(); + p.push("xargo-check"); + Ok(Command::new(p)) +} + trait CommandExt { fn run(&mut self) -> Result<()>; fn run_and_get_stderr(&mut self) -> Result; @@ -254,6 +262,7 @@ impl Project { Ok(()) } + /// Adds a `Xargo.toml` to the project fn xargo_toml(&self, toml: &str) -> Result<()> { write(&self.td.path().join("Xargo.toml"), false, toml) @@ -336,6 +345,15 @@ impl HProject { fn xargo_toml(&self, toml: &str) -> Result<()> { write(&self.td.path().join("Xargo.toml"), false, toml) } + + fn check(&self) -> Result<()> { + xargo_check()? + .args(&["check"]) + .current_dir(self.td.path()) + .run_and_get_stderr()?; + Ok(()) + } + } impl Drop for HProject { @@ -887,3 +905,16 @@ tag = "1.0.25" run!() } } + +#[cfg(feature = "dev")] +#[test] +fn cargo_check() { + fn run() -> Result<()> { + let project = HProject::new(false)?; + project.check()?; + + Ok(()) + } + + run!() +} From 030c4c1a9210202408f22815230ed43f1290a91c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 28 Nov 2019 14:54:24 -0500 Subject: [PATCH 04/17] Add missing files --- src/bin/xargo-check.rs | 3 + src/bin/xargo.rs | 3 + src/lib.rs | 224 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 src/bin/xargo-check.rs create mode 100644 src/bin/xargo.rs create mode 100644 src/lib.rs diff --git a/src/bin/xargo-check.rs b/src/bin/xargo-check.rs new file mode 100644 index 0000000..ad6507a --- /dev/null +++ b/src/bin/xargo-check.rs @@ -0,0 +1,3 @@ +fn main() { + xargo::main_inner(xargo::CargoMode::Check); +} diff --git a/src/bin/xargo.rs b/src/bin/xargo.rs new file mode 100644 index 0000000..9f238f0 --- /dev/null +++ b/src/bin/xargo.rs @@ -0,0 +1,3 @@ +fn main() { + xargo::main_inner(xargo::CargoMode::Build); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..21e05c2 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,224 @@ +#![deny(warnings)] + +#[macro_use] +extern crate error_chain; +extern crate fs2; +#[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "macos"))] +extern crate libc; +extern crate rustc_version; +extern crate serde_json; +extern crate tempdir; +extern crate toml; +extern crate walkdir; +extern crate dirs; + +use std::hash::{Hash, Hasher}; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::process::ExitStatus; +use std::{env, io, process}; + +use rustc_version::Channel; + +use errors::*; +use rustc::Target; + +mod cargo; +mod cli; +mod errors; +mod extensions; +mod flock; +mod rustc; +mod sysroot; +mod util; +mod xargo; + +pub use sysroot::CargoMode; + +// We use a different sysroot for Native compilation to avoid file locking +// +// Cross compilation requires `lib/rustlib/$HOST` to match `rustc`'s sysroot, +// whereas Native compilation wants to use a custom `lib/rustlib/$HOST`. If each +// mode has its own sysroot then we avoid sharing that directory and thus file +// locking it. +pub enum CompilationMode { + Cross(Target), + Native(String), +} + +impl CompilationMode { + fn hash(&self, hasher: &mut H) -> Result<()> + where + H: Hasher, + { + match *self { + CompilationMode::Cross(ref target) => target.hash(hasher)?, + CompilationMode::Native(ref triple) => triple.hash(hasher), + } + + Ok(()) + } + + fn triple(&self) -> &str { + match *self { + CompilationMode::Cross(ref target) => target.triple(), + CompilationMode::Native(ref triple) => triple, + } + } + + fn is_native(&self) -> bool { + match *self { + CompilationMode::Native(_) => true, + _ => false, + } + } +} + +pub fn main_inner(cargo_mode: CargoMode) { + fn show_backtrace() -> bool { + env::var("RUST_BACKTRACE").as_ref().map(|s| &s[..]) == Ok("1") + } + + match run(cargo_mode) { + Err(e) => { + let stderr = io::stderr(); + let mut stderr = stderr.lock(); + + writeln!(stderr, "error: {}", e).ok(); + + for e in e.iter().skip(1) { + writeln!(stderr, "caused by: {}", e).ok(); + } + + if show_backtrace() { + if let Some(backtrace) = e.backtrace() { + writeln!(stderr, "{:?}", backtrace).ok(); + } + } else { + writeln!(stderr, "note: run with `RUST_BACKTRACE=1` for a backtrace").ok(); + } + + process::exit(1) + } + Ok(status) => if !status.success() { + process::exit(status.code().unwrap_or(1)) + }, + } +} + +fn run(cargo_mode: CargoMode) -> Result { + let args = cli::args(); + let verbose = args.verbose(); + + let meta = rustc::version(); + + if let Some(sc) = args.subcommand() { + if !sc.needs_sysroot() { + return cargo::run(&args, verbose); + } + } else if args.version() { + writeln!( + io::stderr(), + concat!("xargo ", env!("CARGO_PKG_VERSION"), "{}"), + include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt")) + ).ok(); + + return cargo::run(&args, verbose); + } + + let cd = CurrentDirectory::get()?; + + let config = cargo::config()?; + if let Some(root) = cargo::root()? { + // We can't build sysroot with stable or beta due to unstable features + let sysroot = rustc::sysroot(verbose)?; + let src = match meta.channel { + Channel::Dev => rustc::Src::from_env().ok_or( + "The XARGO_RUST_SRC env variable must be set and point to the \ + Rust source directory when working with the 'dev' channel", + )?, + Channel::Nightly => if let Some(src) = rustc::Src::from_env() { + src + } else { + sysroot.src()? + }, + Channel::Stable | Channel::Beta => { + writeln!( + io::stderr(), + "WARNING: the sysroot can't be built for the {:?} channel. \ + Switch to nightly.", + meta.channel + ).ok(); + return cargo::run(&args, verbose); + } + }; + + let cmode = if let Some(triple) = args.target() { + if Path::new(triple).is_file() { + bail!( + "Xargo doesn't support files as an argument to --target. \ + Use `--target foo` instead of `--target foo.json`." + ) + } else if triple == meta.host { + Some(CompilationMode::Native(meta.host.clone())) + } else { + Target::new(triple, &cd, verbose)?.map(CompilationMode::Cross) + } + } else { + if let Some(ref config) = config { + if let Some(triple) = config.target()? { + Target::new(triple, &cd, verbose)?.map(CompilationMode::Cross) + } else { + Some(CompilationMode::Native(meta.host.clone())) + } + } else { + Some(CompilationMode::Native(meta.host.clone())) + } + }; + + if let Some(cmode) = cmode { + let home = xargo::home(&cmode)?; + let rustflags = cargo::rustflags(config.as_ref(), cmode.triple())?; + + sysroot::update( + &cmode, + &home, + &root, + &rustflags, + &meta, + &src, + &sysroot, + verbose, + args.message_format(), + cargo_mode + )?; + return xargo::run( + &args, + &cmode, + rustflags, + &home, + &meta, + config.as_ref(), + verbose, + ); + } + } + + cargo::run(&args, verbose) +} + +pub struct CurrentDirectory { + path: PathBuf, +} + +impl CurrentDirectory { + fn get() -> Result { + env::current_dir() + .chain_err(|| "couldn't get the current directory") + .map(|cd| CurrentDirectory { path: cd }) + } + + fn path(&self) -> &Path { + &self.path + } +} From 7c52b483d2b2e0ce39675e321ce7b351587f4442 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 28 Nov 2019 14:55:45 -0500 Subject: [PATCH 05/17] Undo unnecessary change --- src/sysroot.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sysroot.rs b/src/sysroot.rs index 09c9779..04fd876 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -446,8 +446,6 @@ impl Blueprint { Ok(()) } - let mut blueprint = Blueprint::new(); - // Compose patch section let mut patch = match toml.and_then(xargo::Toml::patch) { Some(value) => value @@ -530,6 +528,7 @@ impl Blueprint { } }; + let mut blueprint = Blueprint::new(); for (k, v) in deps { if let Value::Table(mut map) = v { let stage = if let Some(value) = map.remove("stage") { From 14844cebd64545ca06c94647588360ea165e4906 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 28 Nov 2019 22:21:08 -0500 Subject: [PATCH 06/17] Add 'default-run' to Cargo.toml --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 10b1f72..d7883cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ license = "MIT OR Apache-2.0" name = "xargo" repository = "https://github.com/japaric/xargo" version = "0.3.18" +default-run = "xargo" [dependencies] error-chain = "0.7.2" From 32bad3f28315c0245a40f5840a3647a55ad00899 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 3 Dec 2019 13:40:04 -0500 Subject: [PATCH 07/17] Apply nits Co-Authored-By: Ralf Jung --- src/lib.rs | 2 +- src/sysroot.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 21e05c2..ea22cc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -190,7 +190,7 @@ fn run(cargo_mode: CargoMode) -> Result { &sysroot, verbose, args.message_format(), - cargo_mode + cargo_mode, )?; return xargo::run( &args, diff --git a/src/sysroot.rs b/src/sysroot.rs index 04fd876..cd7f944 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -39,7 +39,7 @@ fn build( hash: u64, verbose: bool, message_format: Option<&str>, - cargo_mode: CargoMode + cargo_mode: CargoMode, ) -> Result<()> { const TOML: &'static str = r#" [package] @@ -270,7 +270,7 @@ pub fn update( sysroot: &Sysroot, verbose: bool, message_format: Option<&str>, - cargo_mode: CargoMode + cargo_mode: CargoMode, ) -> Result<()> { let ctoml = cargo::toml(root)?; let (xtoml_parent, xtoml) = xargo::toml(root)?; @@ -297,7 +297,7 @@ pub fn update( hash, verbose, message_format, - cargo_mode + cargo_mode, )?; } @@ -355,7 +355,7 @@ pub struct Stage { #[derive(Copy, Clone, Debug)] pub enum CargoMode { Build, - Check + Check, } /// A sysroot that will be built in "stages" From 2ee22cef0ff557cae2675ee51b9e0baf6d04ad20 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 3 Dec 2019 13:42:17 -0500 Subject: [PATCH 08/17] Improve README section title --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b6ef2ca..6402e39 100644 --- a/README.md +++ b/README.md @@ -309,7 +309,7 @@ git = "https://github.com/japaric/steed" stage = 2 ``` -## Cargo subcommand +## Check-only sysroot build Xargo supports performing a 'check build' of the syroot via the `xargo-check` command. This command is invoked exactly From 560823ad6fa435d8292074a28b86e1e520162f34 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 3 Dec 2019 13:42:26 -0500 Subject: [PATCH 09/17] Rename test helper method --- tests/smoke.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/smoke.rs b/tests/smoke.rs index 9f49894..0dc2bd7 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -346,7 +346,8 @@ impl HProject { write(&self.td.path().join("Xargo.toml"), false, toml) } - fn check(&self) -> Result<()> { + /// Runs `xargo-check check` + fn xargo_check_check(&self) -> Result<()> { xargo_check()? .args(&["check"]) .current_dir(self.td.path()) @@ -911,7 +912,7 @@ tag = "1.0.25" fn cargo_check() { fn run() -> Result<()> { let project = HProject::new(false)?; - project.check()?; + project.xargo_check_check()?; Ok(()) } From 2a2b40a01be7abfcb7eb71824ea4adb234717a53 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 3 Dec 2019 13:50:00 -0500 Subject: [PATCH 10/17] Test `xargo-check` both with and without arguments --- tests/smoke.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/smoke.rs b/tests/smoke.rs index 0dc2bd7..697ac06 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -346,10 +346,13 @@ impl HProject { write(&self.td.path().join("Xargo.toml"), false, toml) } - /// Runs `xargo-check check` - fn xargo_check_check(&self) -> Result<()> { - xargo_check()? - .args(&["check"]) + /// Runs `xargo-check` with the specified subcommand + fn xargo_check_subcommand(&self, subcommand: Option<&str>) -> Result<()> { + let mut cmd = xargo_check()?; + if let Some(subcommand) = subcommand { + cmd.args(&[subcommand]); + } + cmd .current_dir(self.td.path()) .run_and_get_stderr()?; Ok(()) @@ -909,13 +912,24 @@ tag = "1.0.25" #[cfg(feature = "dev")] #[test] -fn cargo_check() { +fn cargo_check_plain() { fn run() -> Result<()> { let project = HProject::new(false)?; - project.xargo_check_check()?; + project.xargo_check_subcommand(None)?; Ok(()) } + run!() +} + +#[cfg(feature = "dev")] +#[test] +fn cargo_check_check() { + fn run() -> Result<()> { + let project = HProject::new(false)?; + project.xargo_check_subcommand(Some("check"))?; + Ok(()) + } run!() } From 4dc6bd89383af7c4a9db6043fb097cbd0450826b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 23 Dec 2019 00:04:43 -0500 Subject: [PATCH 11/17] Allow running 'xargo-check' when no Cargo.toml is present --- src/cargo.rs | 10 ++++++++-- src/lib.rs | 2 +- src/sysroot.rs | 28 +++++++++++++++++++++------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/cargo.rs b/src/cargo.rs index b347bce..6135a63 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -10,6 +10,7 @@ use cli::Args; use errors::*; use extensions::CommandExt; use util; +use sysroot::CargoMode; use xargo::Home; pub struct Rustflags { @@ -247,10 +248,15 @@ impl Root { } } -pub fn root() -> Result> { +pub fn root(mode: CargoMode) -> Result> { + // Don't require a 'Cargo.toml' to exist when 'xargo-check' is used + let name = match mode { + CargoMode::Build => "Cargo.toml", + CargoMode::Check => "Xargo.toml" + }; let cd = env::current_dir().chain_err(|| "couldn't get the current directory")?; - Ok(util::search(&cd, "Cargo.toml").map(|p| Root { path: p.to_owned() })) + Ok(util::search(&cd, name).map(|p| Root { path: p.to_owned() })) } #[derive(Clone, Copy, PartialEq)] diff --git a/src/lib.rs b/src/lib.rs index ea22cc0..4332e47 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,7 +129,7 @@ fn run(cargo_mode: CargoMode) -> Result { let cd = CurrentDirectory::get()?; let config = cargo::config()?; - if let Some(root) = cargo::root()? { + if let Some(root) = cargo::root(cargo_mode)? { // We can't build sysroot with stable or beta due to unstable features let sysroot = rustc::sysroot(verbose)?; let src = match meta.channel { diff --git a/src/sysroot.rs b/src/sysroot.rs index cd7f944..04168ee 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -31,7 +31,7 @@ fn profile() -> &'static str { fn build( cmode: &CompilationMode, blueprint: Blueprint, - ctoml: &cargo::Toml, + ctoml: &Option, home: &Home, rustflags: &Rustflags, src: &Src, @@ -97,8 +97,10 @@ version = "0.0.0" stoml.push_str(&Value::Table(map).to_string()); } - if let Some(profile) = ctoml.profile() { - stoml.push_str(&profile.to_string()) + if let Some(ctoml) = ctoml { + if let Some(profile) = ctoml.profile() { + stoml.push_str(&profile.to_string()) + } } // rust-src comes with a lockfile for libstd. Use it. @@ -238,7 +240,7 @@ fn hash( cmode: &CompilationMode, blueprint: &Blueprint, rustflags: &Rustflags, - ctoml: &cargo::Toml, + ctoml: &Option, meta: &VersionMeta, ) -> Result { let mut hasher = DefaultHasher::new(); @@ -249,8 +251,10 @@ fn hash( cmode.hash(&mut hasher)?; - if let Some(profile) = ctoml.profile() { - profile.hash(&mut hasher); + if let Some(ctoml) = ctoml { + if let Some(profile) = ctoml.profile() { + profile.hash(&mut hasher); + } } if let Some(ref hash) = meta.commit_hash { @@ -272,7 +276,17 @@ pub fn update( message_format: Option<&str>, cargo_mode: CargoMode, ) -> Result<()> { - let ctoml = cargo::toml(root)?; + let ctoml = match cargo_mode { + CargoMode::Build => Some(cargo::toml(root)?), + CargoMode::Check => { + if root.path().join("Cargo.toml").exists() { + Some(cargo::toml(root)?) + } else { + None + } + } + }; + let (xtoml_parent, xtoml) = xargo::toml(root)?; // As paths in the 'Xargo.toml' can be relative to the directory containing From 5d0a993528a5b642f3936c286ad3139ffc0f1810 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 23 Dec 2019 00:18:07 -0500 Subject: [PATCH 12/17] Test that running 'xargo-check' with just an Xargo.toml works --- tests/smoke.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/smoke.rs b/tests/smoke.rs index 697ac06..77e6738 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -347,15 +347,14 @@ impl HProject { } /// Runs `xargo-check` with the specified subcommand - fn xargo_check_subcommand(&self, subcommand: Option<&str>) -> Result<()> { + fn xargo_check_subcommand(&self, subcommand: Option<&str>) -> Result { let mut cmd = xargo_check()?; if let Some(subcommand) = subcommand { cmd.args(&[subcommand]); } cmd .current_dir(self.td.path()) - .run_and_get_stderr()?; - Ok(()) + .run_and_get_stderr() } } @@ -933,3 +932,20 @@ fn cargo_check_check() { } run!() } + +#[cfg(feature = "dev")] +#[test] +fn cargo_check_check_no_ctoml() { + fn run() -> Result<()> { + let project = HProject::new(false)?; + project.xargo_toml("")?; + std::fs::remove_file(project.td.path().join("Cargo.toml")) + .chain_err(|| format!("Could not remove Cargo.toml"))?; + + let stderr = project.xargo_check_subcommand(None)?; + assert!(stderr.contains("Checking core")); + + Ok(()) + } + run!() +} From 265015098a8bc527602ed340f68b22011b935d6b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 28 Dec 2019 00:14:30 -0500 Subject: [PATCH 13/17] Don't show help message with no-args 'xargo-check' --- src/lib.rs | 36 +++++++++++++++++++++--------------- src/sysroot.rs | 2 +- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4332e47..c8a791b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,13 +100,14 @@ pub fn main_inner(cargo_mode: CargoMode) { process::exit(1) } - Ok(status) => if !status.success() { + Ok(Some(status)) => if !status.success() { process::exit(status.code().unwrap_or(1)) }, + Ok(None) => {} } } -fn run(cargo_mode: CargoMode) -> Result { +fn run(cargo_mode: CargoMode) -> Result> { let args = cli::args(); let verbose = args.verbose(); @@ -114,7 +115,7 @@ fn run(cargo_mode: CargoMode) -> Result { if let Some(sc) = args.subcommand() { if !sc.needs_sysroot() { - return cargo::run(&args, verbose); + return cargo::run(&args, verbose).map(Some); } } else if args.version() { writeln!( @@ -123,7 +124,7 @@ fn run(cargo_mode: CargoMode) -> Result { include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt")) ).ok(); - return cargo::run(&args, verbose); + return cargo::run(&args, verbose).map(Some); } let cd = CurrentDirectory::get()?; @@ -149,7 +150,7 @@ fn run(cargo_mode: CargoMode) -> Result { Switch to nightly.", meta.channel ).ok(); - return cargo::run(&args, verbose); + return cargo::run(&args, verbose).map(Some); } }; @@ -192,19 +193,24 @@ fn run(cargo_mode: CargoMode) -> Result { args.message_format(), cargo_mode, )?; - return xargo::run( - &args, - &cmode, - rustflags, - &home, - &meta, - config.as_ref(), - verbose, - ); + + if args.subcommand().is_some() || cargo_mode == CargoMode::Build { + return xargo::run( + &args, + &cmode, + rustflags, + &home, + &meta, + config.as_ref(), + verbose, + ).map(Some); + } else { + return Ok(None) + } } } - cargo::run(&args, verbose) + cargo::run(&args, verbose).map(Some) } pub struct CurrentDirectory { diff --git a/src/sysroot.rs b/src/sysroot.rs index 04168ee..febc9a9 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -366,7 +366,7 @@ pub struct Stage { /// Which mode to invoke `cargo` in when building the sysroot /// Can be either `cargo build` or `cargo check` -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum CargoMode { Build, Check, From 68cbf2dae891b2ce6bcbc036e861dffffe6e154d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 28 Dec 2019 19:02:32 -0500 Subject: [PATCH 14/17] Some cleanup --- tests/smoke.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/smoke.rs b/tests/smoke.rs index 77e6738..0c72e3c 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -909,18 +909,6 @@ tag = "1.0.25" } } -#[cfg(feature = "dev")] -#[test] -fn cargo_check_plain() { - fn run() -> Result<()> { - let project = HProject::new(false)?; - project.xargo_check_subcommand(None)?; - - Ok(()) - } - run!() -} - #[cfg(feature = "dev")] #[test] fn cargo_check_check() { @@ -938,6 +926,7 @@ fn cargo_check_check() { fn cargo_check_check_no_ctoml() { fn run() -> Result<()> { let project = HProject::new(false)?; + // Make sure that 'Xargo.toml` exists project.xargo_toml("")?; std::fs::remove_file(project.td.path().join("Cargo.toml")) .chain_err(|| format!("Could not remove Cargo.toml"))?; From bb2f384af707104685cbc0e311f786cfaf848727 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 28 Dec 2019 19:04:22 -0500 Subject: [PATCH 15/17] Rename CargoMode to XargoMode --- src/bin/xargo-check.rs | 2 +- src/bin/xargo.rs | 2 +- src/cargo.rs | 8 ++++---- src/lib.rs | 10 +++++----- src/sysroot.rs | 14 +++++++------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/bin/xargo-check.rs b/src/bin/xargo-check.rs index ad6507a..619c12e 100644 --- a/src/bin/xargo-check.rs +++ b/src/bin/xargo-check.rs @@ -1,3 +1,3 @@ fn main() { - xargo::main_inner(xargo::CargoMode::Check); + xargo::main_inner(xargo::XargoMode::Check); } diff --git a/src/bin/xargo.rs b/src/bin/xargo.rs index 9f238f0..663421e 100644 --- a/src/bin/xargo.rs +++ b/src/bin/xargo.rs @@ -1,3 +1,3 @@ fn main() { - xargo::main_inner(xargo::CargoMode::Build); + xargo::main_inner(xargo::XargoMode::Build); } diff --git a/src/cargo.rs b/src/cargo.rs index 6135a63..d7fbdcf 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -10,7 +10,7 @@ use cli::Args; use errors::*; use extensions::CommandExt; use util; -use sysroot::CargoMode; +use sysroot::XargoMode; use xargo::Home; pub struct Rustflags { @@ -248,11 +248,11 @@ impl Root { } } -pub fn root(mode: CargoMode) -> Result> { +pub fn root(mode: XargoMode) -> Result> { // Don't require a 'Cargo.toml' to exist when 'xargo-check' is used let name = match mode { - CargoMode::Build => "Cargo.toml", - CargoMode::Check => "Xargo.toml" + XargoMode::Build => "Cargo.toml", + XargoMode::Check => "Xargo.toml" }; let cd = env::current_dir().chain_err(|| "couldn't get the current directory")?; diff --git a/src/lib.rs b/src/lib.rs index c8a791b..883bb67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,7 @@ mod sysroot; mod util; mod xargo; -pub use sysroot::CargoMode; +pub use sysroot::XargoMode; // We use a different sysroot for Native compilation to avoid file locking // @@ -74,12 +74,12 @@ impl CompilationMode { } } -pub fn main_inner(cargo_mode: CargoMode) { +pub fn main_inner(xargo_mode: XargoMode) { fn show_backtrace() -> bool { env::var("RUST_BACKTRACE").as_ref().map(|s| &s[..]) == Ok("1") } - match run(cargo_mode) { + match run(xargo_mode) { Err(e) => { let stderr = io::stderr(); let mut stderr = stderr.lock(); @@ -107,7 +107,7 @@ pub fn main_inner(cargo_mode: CargoMode) { } } -fn run(cargo_mode: CargoMode) -> Result> { +fn run(cargo_mode: XargoMode) -> Result> { let args = cli::args(); let verbose = args.verbose(); @@ -194,7 +194,7 @@ fn run(cargo_mode: CargoMode) -> Result> { cargo_mode, )?; - if args.subcommand().is_some() || cargo_mode == CargoMode::Build { + if args.subcommand().is_some() || cargo_mode == XargoMode::Build { return xargo::run( &args, &cmode, diff --git a/src/sysroot.rs b/src/sysroot.rs index febc9a9..418b437 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -39,7 +39,7 @@ fn build( hash: u64, verbose: bool, message_format: Option<&str>, - cargo_mode: CargoMode, + cargo_mode: XargoMode, ) -> Result<()> { const TOML: &'static str = r#" [package] @@ -169,8 +169,8 @@ version = "0.0.0" } match cargo_mode { - CargoMode::Build => cmd.arg("build"), - CargoMode::Check => cmd.arg("check") + XargoMode::Build => cmd.arg("build"), + XargoMode::Check => cmd.arg("check") }; match () { @@ -274,11 +274,11 @@ pub fn update( sysroot: &Sysroot, verbose: bool, message_format: Option<&str>, - cargo_mode: CargoMode, + cargo_mode: XargoMode, ) -> Result<()> { let ctoml = match cargo_mode { - CargoMode::Build => Some(cargo::toml(root)?), - CargoMode::Check => { + XargoMode::Build => Some(cargo::toml(root)?), + XargoMode::Check => { if root.path().join("Cargo.toml").exists() { Some(cargo::toml(root)?) } else { @@ -367,7 +367,7 @@ pub struct Stage { /// Which mode to invoke `cargo` in when building the sysroot /// Can be either `cargo build` or `cargo check` #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum CargoMode { +pub enum XargoMode { Build, Check, } From e399fc940f0dfae4e0f1712350db3100de74de4a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 29 Dec 2019 15:56:17 -0500 Subject: [PATCH 16/17] Remove 'default-run' from Cargo.toml on CI --- ci/script.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ci/script.sh b/ci/script.sh index edee9f0..db5e780 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -3,8 +3,12 @@ set -euxo pipefail beginswith() { case $2 in "$1"*) true;; *) false;; esac; } main() { + # We test against Cargo versions that don't support 'default-run' + # As a workaround, we remove 'default-run' from the Cargo.toml + # on CI + sed -i 's/default-run = "xargo"//g' Cargo.toml cross build --target $TARGET --locked - cross run --target $TARGET -- -V + cross run --bin xargo --target $TARGET -- -V if beginswith nightly $TRAVIS_RUST_VERSION; then cargo test --features dev --target $TARGET From 3d63a181c8bc78286f201189325937b6fe235b47 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 30 Dec 2019 23:05:35 -0500 Subject: [PATCH 17/17] Repalce 'sed -i' with 'sed' + 'mv' --- ci/script.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/script.sh b/ci/script.sh index db5e780..83fe957 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -6,7 +6,9 @@ main() { # We test against Cargo versions that don't support 'default-run' # As a workaround, we remove 'default-run' from the Cargo.toml # on CI - sed -i 's/default-run = "xargo"//g' Cargo.toml + # Unfortunately, we can't use 'sed -i', as this doesn't work on OS X + sed 's/default-run = "xargo"//g' Cargo.toml > Cargo.toml.new + mv Cargo.toml.new Cargo.toml cross build --target $TARGET --locked cross run --bin xargo --target $TARGET -- -V