1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Command-line interface of the rustbuild build system.
13 //! This module implements the command-line parsing of the build system which
14 //! has various flags to configure how it's run.
18 use std
::path
::PathBuf
;
21 use getopts
::{Matches, Options}
;
28 /// Deserialized version of all flags for this compile.
31 pub stage
: Option
<u32>,
32 pub keep_stage
: Option
<u32>,
34 pub host
: Vec
<String
>,
35 pub target
: Vec
<String
>,
36 pub config
: Option
<PathBuf
>,
37 pub src
: Option
<PathBuf
>,
38 pub jobs
: Option
<u32>,
51 test_args
: Vec
<String
>,
55 test_args
: Vec
<String
>,
64 pub fn parse(args
: &[String
]) -> Flags
{
65 let mut opts
= Options
::new();
66 opts
.optflag("v", "verbose", "use verbose output");
67 opts
.optopt("", "config", "TOML configuration file for build", "FILE");
68 opts
.optopt("", "build", "build target of the stage0 compiler", "BUILD");
69 opts
.optmulti("", "host", "host targets to build", "HOST");
70 opts
.optmulti("", "target", "target targets to build", "TARGET");
71 opts
.optopt("", "stage", "stage to build", "N");
72 opts
.optopt("", "keep-stage", "stage to keep without recompiling", "N");
73 opts
.optopt("", "src", "path to the root of the rust checkout", "DIR");
74 opts
.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
75 opts
.optflag("h", "help", "print this help message");
77 let usage
= |n
, opts
: &Options
| -> ! {
78 let command
= args
.get(0).map(|s
| &**s
);
79 let brief
= format
!("Usage: x.py {} [options] [<args>...]",
80 command
.unwrap_or("<command>"));
82 println
!("{}", opts
.usage(&brief
));
87 This subcommand accepts a number of positional arguments of directories to
88 the crates and/or artifacts to compile. For example:
90 ./x.py build src/libcore
91 ./x.py build src/libproc_macro
92 ./x.py build src/libstd --stage 1
94 If no arguments are passed then the complete artifacts for that stage are
98 ./x.py build --stage 1
100 For a quick build with a usable compile, you can pass:
102 ./x.py build --stage 1 src/libtest
109 This subcommand accepts a number of positional arguments of directories to
110 tests that should be compiled and run. For example:
112 ./x.py test src/test/run-pass
113 ./x.py test src/libstd --test-args hash_map
114 ./x.py test src/libstd --stage 0
116 If no arguments are passed then the complete artifacts for that stage are
120 ./x.py test --stage 1
127 This subcommand accepts a number of positional arguments of directories of
128 documentation to build. For example:
130 ./x.py doc src/doc/book
131 ./x.py doc src/doc/nomicon
132 ./x.py doc src/libstd
134 If no arguments are passed then everything is documented:
144 if let Some(command
) = command
{
145 if command
== "build" ||
149 command
== "bench" ||
151 println
!("Available invocations:");
152 if args
.iter().any(|a
| a
== "-v") {
153 let flags
= Flags
::parse(&["build".to_string()]);
154 let mut config
= Config
::default();
155 config
.build
= flags
.build
.clone();
156 let mut build
= Build
::new(flags
, config
);
157 metadata
::build(&mut build
);
158 step
::build_rules(&build
).print_help(command
);
160 println
!(" ... elided, run `./x.py {} -h -v` to see",
170 build Compile either the compiler or libraries
171 test Build and run some test suites
172 bench Build and run some benchmarks
173 doc Build documentation
174 clean Clean out build directories
175 dist Build and/or install distribution artifacts
177 To learn more about a subcommand, run `./x.py <command> -h`
183 println
!("a command must be passed");
186 let parse
= |opts
: &Options
| {
187 let m
= opts
.parse(&args
[1..]).unwrap_or_else(|e
| {
188 println
!("failed to parse options: {}", e
);
191 if m
.opt_present("h") {
197 let cwd
= t
!(env
::current_dir());
198 let remaining_as_path
= |m
: &Matches
| {
199 m
.free
.iter().map(|p
| cwd
.join(p
)).collect
::<Vec
<_
>>()
203 let cmd
= match &args
[0][..] {
206 Subcommand
::Build { paths: remaining_as_path(&m) }
210 Subcommand
::Doc { paths: remaining_as_path(&m) }
213 opts
.optmulti("", "test-args", "extra arguments", "ARGS");
216 paths
: remaining_as_path(&m
),
217 test_args
: m
.opt_strs("test-args"),
221 opts
.optmulti("", "test-args", "extra arguments", "ARGS");
224 paths
: remaining_as_path(&m
),
225 test_args
: m
.opt_strs("test-args"),
230 if m
.free
.len() > 0 {
231 println
!("clean takes no arguments");
237 opts
.optflag("", "install", "run installer as well");
240 install
: m
.opt_present("install"),
243 "--help" => usage(0, &opts
),
245 println
!("unknown command: {}", cmd
);
251 let cfg_file
= m
.opt_str("config").map(PathBuf
::from
).or_else(|| {
252 if fs
::metadata("config.toml").is_ok() {
253 Some(PathBuf
::from("config.toml"))
260 verbose
: m
.opt_present("v"),
261 stage
: m
.opt_str("stage").map(|j
| j
.parse().unwrap()),
262 keep_stage
: m
.opt_str("keep-stage").map(|j
| j
.parse().unwrap()),
263 build
: m
.opt_str("build").unwrap_or_else(|| {
264 env
::var("BUILD").unwrap()
266 host
: m
.opt_strs("host"),
267 target
: m
.opt_strs("target"),
269 src
: m
.opt_str("src").map(PathBuf
::from
),
270 jobs
: m
.opt_str("jobs").map(|j
| j
.parse().unwrap()),
277 pub fn test_args(&self) -> Vec
<&str> {
279 Subcommand
::Test { ref test_args, .. }
|
280 Subcommand
::Bench { ref test_args, .. }
=> {
281 test_args
.iter().flat_map(|s
| s
.split_whitespace()).collect()