Skip to content

Commit 41dccce

Browse files
bors[bot]Aaron1011
andauthored
Merge #267
267: Add `xargo-check` command r=RalfJung a=Aaron1011 This allows configuring Xargo to run `cargo check` instead of `cargo build` Needed to support rust-lang/miri#1048 Co-authored-by: Aaron Hill <[email protected]>
2 parents d1d7606 + e399fc9 commit 41dccce

File tree

9 files changed

+149
-32
lines changed

9 files changed

+149
-32
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license = "MIT OR Apache-2.0"
99
name = "xargo"
1010
repository = "https://github.com/japaric/xargo"
1111
version = "0.3.18"
12+
default-run = "xargo"
1213

1314
[dependencies]
1415
error-chain = "0.7.2"

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,18 @@ git = "https://github.com/japaric/steed"
309309
stage = 2
310310
```
311311

312+
## Check-only sysroot build
313+
314+
Xargo supports performing a 'check build' of the syroot
315+
via the `xargo-check` command. This command is invoked exactly
316+
like `xargo`, but will invoke `cargo check` instead of `cargo build`
317+
when building the sysroot.
318+
319+
This is only useful for very specialized applicationsm like Miri.
320+
The resulting libstd will *not* be useable in a normal build, since codegen
321+
will not be performed. You should almost always run `xargo check` (note the space),
322+
which will perform a normal sysroot build, followed by a 'check' build of *your application*
323+
312324
## Caveats / gotchas
313325

314326
- Xargo won't build a sysroot when used with stable or beta Rust. This is

ci/script.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ set -euxo pipefail
33
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
44

55
main() {
6+
# We test against Cargo versions that don't support 'default-run'
7+
# As a workaround, we remove 'default-run' from the Cargo.toml
8+
# on CI
9+
sed -i 's/default-run = "xargo"//g' Cargo.toml
610
cross build --target $TARGET --locked
7-
cross run --target $TARGET -- -V
11+
cross run --bin xargo --target $TARGET -- -V
812

913
if beginswith nightly $TRAVIS_RUST_VERSION; then
1014
cargo test --features dev --target $TARGET

src/bin/xargo-check.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
xargo::main_inner(xargo::XargoMode::Check);
3+
}

src/bin/xargo.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
xargo::main_inner(xargo::XargoMode::Build);
3+
}

src/cargo.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use cli::Args;
1010
use errors::*;
1111
use extensions::CommandExt;
1212
use util;
13+
use sysroot::XargoMode;
1314
use xargo::Home;
1415

1516
pub struct Rustflags {
@@ -247,10 +248,15 @@ impl Root {
247248
}
248249
}
249250

250-
pub fn root() -> Result<Option<Root>> {
251+
pub fn root(mode: XargoMode) -> Result<Option<Root>> {
252+
// Don't require a 'Cargo.toml' to exist when 'xargo-check' is used
253+
let name = match mode {
254+
XargoMode::Build => "Cargo.toml",
255+
XargoMode::Check => "Xargo.toml"
256+
};
251257
let cd = env::current_dir().chain_err(|| "couldn't get the current directory")?;
252258

253-
Ok(util::search(&cd, "Cargo.toml").map(|p| Root { path: p.to_owned() }))
259+
Ok(util::search(&cd, name).map(|p| Root { path: p.to_owned() }))
254260
}
255261

256262
#[derive(Clone, Copy, PartialEq)]

src/main.rs renamed to src/lib.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ mod sysroot;
3333
mod util;
3434
mod xargo;
3535

36+
pub use sysroot::XargoMode;
37+
3638
// We use a different sysroot for Native compilation to avoid file locking
3739
//
3840
// Cross compilation requires `lib/rustlib/$HOST` to match `rustc`'s sysroot,
@@ -72,12 +74,12 @@ impl CompilationMode {
7274
}
7375
}
7476

75-
pub fn main() {
77+
pub fn main_inner(xargo_mode: XargoMode) {
7678
fn show_backtrace() -> bool {
7779
env::var("RUST_BACKTRACE").as_ref().map(|s| &s[..]) == Ok("1")
7880
}
7981

80-
match run() {
82+
match run(xargo_mode) {
8183
Err(e) => {
8284
let stderr = io::stderr();
8385
let mut stderr = stderr.lock();
@@ -98,21 +100,22 @@ pub fn main() {
98100

99101
process::exit(1)
100102
}
101-
Ok(status) => if !status.success() {
103+
Ok(Some(status)) => if !status.success() {
102104
process::exit(status.code().unwrap_or(1))
103105
},
106+
Ok(None) => {}
104107
}
105108
}
106109

107-
fn run() -> Result<ExitStatus> {
110+
fn run(cargo_mode: XargoMode) -> Result<Option<ExitStatus>> {
108111
let args = cli::args();
109112
let verbose = args.verbose();
110113

111114
let meta = rustc::version();
112115

113116
if let Some(sc) = args.subcommand() {
114117
if !sc.needs_sysroot() {
115-
return cargo::run(&args, verbose);
118+
return cargo::run(&args, verbose).map(Some);
116119
}
117120
} else if args.version() {
118121
writeln!(
@@ -121,13 +124,13 @@ fn run() -> Result<ExitStatus> {
121124
include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt"))
122125
).ok();
123126

124-
return cargo::run(&args, verbose);
127+
return cargo::run(&args, verbose).map(Some);
125128
}
126129

127130
let cd = CurrentDirectory::get()?;
128131

129132
let config = cargo::config()?;
130-
if let Some(root) = cargo::root()? {
133+
if let Some(root) = cargo::root(cargo_mode)? {
131134
// We can't build sysroot with stable or beta due to unstable features
132135
let sysroot = rustc::sysroot(verbose)?;
133136
let src = match meta.channel {
@@ -147,7 +150,7 @@ fn run() -> Result<ExitStatus> {
147150
Switch to nightly.",
148151
meta.channel
149152
).ok();
150-
return cargo::run(&args, verbose);
153+
return cargo::run(&args, verbose).map(Some);
151154
}
152155
};
153156

@@ -187,21 +190,27 @@ fn run() -> Result<ExitStatus> {
187190
&src,
188191
&sysroot,
189192
verbose,
190-
args.message_format()
193+
args.message_format(),
194+
cargo_mode,
191195
)?;
192-
return xargo::run(
193-
&args,
194-
&cmode,
195-
rustflags,
196-
&home,
197-
&meta,
198-
config.as_ref(),
199-
verbose,
200-
);
196+
197+
if args.subcommand().is_some() || cargo_mode == XargoMode::Build {
198+
return xargo::run(
199+
&args,
200+
&cmode,
201+
rustflags,
202+
&home,
203+
&meta,
204+
config.as_ref(),
205+
verbose,
206+
).map(Some);
207+
} else {
208+
return Ok(None)
209+
}
201210
}
202211
}
203212

204-
cargo::run(&args, verbose)
213+
cargo::run(&args, verbose).map(Some)
205214
}
206215

207216
pub struct CurrentDirectory {

src/sysroot.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ fn profile() -> &'static str {
3131
fn build(
3232
cmode: &CompilationMode,
3333
blueprint: Blueprint,
34-
ctoml: &cargo::Toml,
34+
ctoml: &Option<cargo::Toml>,
3535
home: &Home,
3636
rustflags: &Rustflags,
3737
src: &Src,
3838
sysroot: &Sysroot,
3939
hash: u64,
4040
verbose: bool,
41-
message_format: Option<&str>
41+
message_format: Option<&str>,
42+
cargo_mode: XargoMode,
4243
) -> Result<()> {
4344
const TOML: &'static str = r#"
4445
[package]
@@ -96,8 +97,10 @@ version = "0.0.0"
9697
stoml.push_str(&Value::Table(map).to_string());
9798
}
9899

99-
if let Some(profile) = ctoml.profile() {
100-
stoml.push_str(&profile.to_string())
100+
if let Some(ctoml) = ctoml {
101+
if let Some(profile) = ctoml.profile() {
102+
stoml.push_str(&profile.to_string())
103+
}
101104
}
102105

103106
// rust-src comes with a lockfile for libstd. Use it.
@@ -165,7 +168,10 @@ version = "0.0.0"
165168
}
166169
}
167170

168-
cmd.arg("build");
171+
match cargo_mode {
172+
XargoMode::Build => cmd.arg("build"),
173+
XargoMode::Check => cmd.arg("check")
174+
};
169175

170176
match () {
171177
#[cfg(feature = "dev")]
@@ -234,7 +240,7 @@ fn hash(
234240
cmode: &CompilationMode,
235241
blueprint: &Blueprint,
236242
rustflags: &Rustflags,
237-
ctoml: &cargo::Toml,
243+
ctoml: &Option<cargo::Toml>,
238244
meta: &VersionMeta,
239245
) -> Result<u64> {
240246
let mut hasher = DefaultHasher::new();
@@ -245,8 +251,10 @@ fn hash(
245251

246252
cmode.hash(&mut hasher)?;
247253

248-
if let Some(profile) = ctoml.profile() {
249-
profile.hash(&mut hasher);
254+
if let Some(ctoml) = ctoml {
255+
if let Some(profile) = ctoml.profile() {
256+
profile.hash(&mut hasher);
257+
}
250258
}
251259

252260
if let Some(ref hash) = meta.commit_hash {
@@ -265,9 +273,20 @@ pub fn update(
265273
src: &Src,
266274
sysroot: &Sysroot,
267275
verbose: bool,
268-
message_format: Option<&str>
276+
message_format: Option<&str>,
277+
cargo_mode: XargoMode,
269278
) -> Result<()> {
270-
let ctoml = cargo::toml(root)?;
279+
let ctoml = match cargo_mode {
280+
XargoMode::Build => Some(cargo::toml(root)?),
281+
XargoMode::Check => {
282+
if root.path().join("Cargo.toml").exists() {
283+
Some(cargo::toml(root)?)
284+
} else {
285+
None
286+
}
287+
}
288+
};
289+
271290
let (xtoml_parent, xtoml) = xargo::toml(root)?;
272291

273292
// As paths in the 'Xargo.toml' can be relative to the directory containing
@@ -292,6 +311,7 @@ pub fn update(
292311
hash,
293312
verbose,
294313
message_format,
314+
cargo_mode,
295315
)?;
296316
}
297317

@@ -344,6 +364,14 @@ pub struct Stage {
344364
patch: Table,
345365
}
346366

367+
/// Which mode to invoke `cargo` in when building the sysroot
368+
/// Can be either `cargo build` or `cargo check`
369+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
370+
pub enum XargoMode {
371+
Build,
372+
Check,
373+
}
374+
347375
/// A sysroot that will be built in "stages"
348376
#[derive(Debug)]
349377
pub struct Blueprint {

tests/smoke.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ fn xargo() -> Result<Command> {
121121
Ok(Command::new(p))
122122
}
123123

124+
fn xargo_check() -> Result<Command> {
125+
let mut p = env::current_exe().chain_err(|| "couldn't get path to current executable")?;
126+
p.pop();
127+
p.pop();
128+
p.push("xargo-check");
129+
Ok(Command::new(p))
130+
}
131+
124132
trait CommandExt {
125133
fn run(&mut self) -> Result<()>;
126134
fn run_and_get_stderr(&mut self) -> Result<String>;
@@ -254,6 +262,7 @@ impl Project {
254262
Ok(())
255263
}
256264

265+
257266
/// Adds a `Xargo.toml` to the project
258267
fn xargo_toml(&self, toml: &str) -> Result<()> {
259268
write(&self.td.path().join("Xargo.toml"), false, toml)
@@ -336,6 +345,18 @@ impl HProject {
336345
fn xargo_toml(&self, toml: &str) -> Result<()> {
337346
write(&self.td.path().join("Xargo.toml"), false, toml)
338347
}
348+
349+
/// Runs `xargo-check` with the specified subcommand
350+
fn xargo_check_subcommand(&self, subcommand: Option<&str>) -> Result<String> {
351+
let mut cmd = xargo_check()?;
352+
if let Some(subcommand) = subcommand {
353+
cmd.args(&[subcommand]);
354+
}
355+
cmd
356+
.current_dir(self.td.path())
357+
.run_and_get_stderr()
358+
}
359+
339360
}
340361

341362
impl Drop for HProject {
@@ -887,3 +908,33 @@ tag = "1.0.25"
887908
run!()
888909
}
889910
}
911+
912+
#[cfg(feature = "dev")]
913+
#[test]
914+
fn cargo_check_check() {
915+
fn run() -> Result<()> {
916+
let project = HProject::new(false)?;
917+
project.xargo_check_subcommand(Some("check"))?;
918+
919+
Ok(())
920+
}
921+
run!()
922+
}
923+
924+
#[cfg(feature = "dev")]
925+
#[test]
926+
fn cargo_check_check_no_ctoml() {
927+
fn run() -> Result<()> {
928+
let project = HProject::new(false)?;
929+
// Make sure that 'Xargo.toml` exists
930+
project.xargo_toml("")?;
931+
std::fs::remove_file(project.td.path().join("Cargo.toml"))
932+
.chain_err(|| format!("Could not remove Cargo.toml"))?;
933+
934+
let stderr = project.xargo_check_subcommand(None)?;
935+
assert!(stderr.contains("Checking core"));
936+
937+
Ok(())
938+
}
939+
run!()
940+
}

0 commit comments

Comments
 (0)