Skip to content

Commit

Permalink
Add --build-plan for 'cargo build'
Browse files Browse the repository at this point in the history
With 'cargo build --build-plan', cargo does not actually run any
commands, but instead prints out what it would have done in the form of
Python data structures. The 'dependencies' structure lists the
dependencies between steps, and the 'commands' structure lists the
information required to run the commands from an external build system.

Fixes rust-lang#3815
  • Loading branch information
mshal committed Aug 3, 2017
1 parent b1df578 commit 49b9665
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/bin/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_lib: bool,
flag_bin: Vec<String>,
flag_bins: bool,
Expand Down Expand Up @@ -67,6 +68,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--no-fail-fast Run all benchmarks regardless of failure
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down Expand Up @@ -127,6 +129,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,),
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
target_rustdoc_args: None,
target_rustc_args: None,
},
Expand Down
3 changes: 3 additions & 0 deletions src/bin/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_release: bool,
flag_lib: bool,
flag_bin: Vec<String>,
Expand Down Expand Up @@ -65,6 +66,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down Expand Up @@ -115,6 +117,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,),
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
target_rustdoc_args: None,
target_rustc_args: None,
};
Expand Down
3 changes: 3 additions & 0 deletions src/bin/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand All @@ -62,6 +63,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_release: bool,
flag_lib: bool,
flag_bin: Vec<String>,
Expand Down Expand Up @@ -112,6 +114,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,),
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
target_rustdoc_args: None,
target_rustc_args: None,
};
Expand Down
3 changes: 3 additions & 0 deletions src/bin/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_package: Vec<String>,
flag_lib: bool,
flag_bin: Vec<String>,
Expand Down Expand Up @@ -55,6 +56,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down Expand Up @@ -106,6 +108,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&empty, false,
&empty, false),
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
release: options.flag_release,
mode: ops::CompileMode::Doc {
deps: !options.flag_no_deps,
Expand Down
1 change: 1 addition & 0 deletions src/bin/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&options.flag_example, options.flag_examples,
&[], false),
message_format: ops::MessageFormat::Human,
build_plan: false,
target_rustc_args: None,
target_rustdoc_args: None,
};
Expand Down
3 changes: 3 additions & 0 deletions src/bin/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_release: bool,
flag_frozen: bool,
flag_locked: bool,
Expand Down Expand Up @@ -48,6 +49,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down Expand Up @@ -101,6 +103,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&[], false)
},
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
target_rustdoc_args: None,
target_rustc_args: None,
};
Expand Down
3 changes: 3 additions & 0 deletions src/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_release: bool,
flag_lib: bool,
flag_bin: Vec<String>,
Expand Down Expand Up @@ -64,6 +65,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down Expand Up @@ -122,6 +124,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,),
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
target_rustdoc_args: None,
target_rustc_args: options.arg_opts.as_ref().map(|a| &a[..]),
};
Expand Down
3 changes: 3 additions & 0 deletions src/bin/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_package: Option<String>,
flag_lib: bool,
flag_bin: Vec<String>,
Expand Down Expand Up @@ -62,6 +63,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down Expand Up @@ -107,6 +109,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,),
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
mode: ops::CompileMode::Doc { deps: false },
target_rustdoc_args: Some(&options.arg_opts),
target_rustc_args: None,
Expand Down
3 changes: 3 additions & 0 deletions src/bin/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct Options {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_build_plan: bool,
flag_release: bool,
flag_no_fail_fast: bool,
flag_frozen: bool,
Expand Down Expand Up @@ -71,6 +72,7 @@ Options:
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--build-plan Generate a build plan
--no-fail-fast Run all tests regardless of failure
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
Expand Down Expand Up @@ -159,6 +161,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
mode: mode,
filter: filter,
message_format: options.flag_message_format,
build_plan: options.flag_build_plan,
target_rustdoc_args: None,
target_rustc_args: None,
},
Expand Down
5 changes: 5 additions & 0 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ pub struct CompileOptions<'a> {
pub mode: CompileMode,
/// `--error_format` flag for the compiler.
pub message_format: MessageFormat,
/// Output a build plan to stdout instead of actually compiling.
pub build_plan: bool,
/// Extra arguments to be passed to rustdoc (for main crate and dependencies)
pub target_rustdoc_args: Option<&'a [String]>,
/// The specified target will be compiled with all the available arguments,
Expand All @@ -81,6 +83,7 @@ impl<'a> CompileOptions<'a> {
release: false,
filter: CompileFilter::Everything { required_features_filterable: false },
message_format: MessageFormat::Human,
build_plan: false,
target_rustdoc_args: None,
target_rustc_args: None,
}
Expand Down Expand Up @@ -196,6 +199,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
let CompileOptions { config, jobs, target, spec, features,
all_features, no_default_features,
release, mode, message_format,
build_plan,
ref filter,
ref target_rustdoc_args,
ref target_rustc_args } = *options;
Expand Down Expand Up @@ -297,6 +301,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
build_config.release = release;
build_config.test = mode == CompileMode::Test || mode == CompileMode::Bench;
build_config.json_messages = message_format == MessageFormat::Json;
build_config.build_plan = build_plan;
if let CompileMode::Doc { deps } = mode {
build_config.doc_all = deps;
}
Expand Down
1 change: 1 addition & 0 deletions src/cargo/ops/cargo_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ fn run_verify(ws: &Workspace, tar: &File, opts: &PackageOpts) -> CargoResult<()>
filter: ops::CompileFilter::Everything { required_features_filterable: true },
release: false,
message_format: ops::MessageFormat::Human,
build_plan: false,
mode: ops::CompileMode::Build,
target_rustdoc_args: None,
target_rustc_args: None,
Expand Down
46 changes: 41 additions & 5 deletions src/cargo/ops/cargo_rustc/job_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::collections::hash_map::HashMap;
use std::fmt;
use std::io;
use std::mem;
use std::sync::Arc;
use std::path::PathBuf;
use std::sync::mpsc::{channel, Sender, Receiver};

use crossbeam::{self, Scope};
Expand Down Expand Up @@ -56,6 +58,7 @@ pub struct JobState<'a> {

enum Message<'a> {
Run(String),
BuildPlan(PackageId, ProcessBuilder, Arc<Vec<(PathBuf, Option<PathBuf>, bool)>>),
Stdout(String),
Stderr(String),
Token(io::Result<Acquired>),
Expand All @@ -67,6 +70,10 @@ impl<'a> JobState<'a> {
let _ = self.tx.send(Message::Run(cmd.to_string()));
}

pub fn build_plan(&self, pkg: PackageId, cmd: ProcessBuilder, filenames: Arc<Vec<(PathBuf, Option<PathBuf>, bool)>>) {
let _ = self.tx.send(Message::BuildPlan(pkg, cmd, filenames));
}

pub fn stdout(&self, out: &str) {
let _ = self.tx.send(Message::Stdout(out.to_string()));
}
Expand Down Expand Up @@ -149,6 +156,7 @@ impl<'a> JobQueue<'a> {

let mut tokens = Vec::new();
let mut queue = Vec::new();
let build_plan = cx.build_config.build_plan;
trace!("queue: {:#?}", self.queue);

// Iteratively execute the entire dependency graph. Each turn of the
Expand Down Expand Up @@ -189,7 +197,7 @@ impl<'a> JobQueue<'a> {
// we're able to perform some parallel work.
while error.is_none() && self.active < tokens.len() + 1 && !queue.is_empty() {
let (key, job, fresh) = queue.remove(0);
self.run(key, fresh, job, cx.config, scope)?;
self.run(key, fresh, job, cx.config, scope, build_plan)?;
}

// If after all that we're not actually running anything then we're
Expand All @@ -209,6 +217,16 @@ impl<'a> JobQueue<'a> {
Message::Run(cmd) => {
cx.config.shell().verbose(|c| c.status("Running", &cmd))?;
}
Message::BuildPlan(pkg, cmd, filenames) => {
println!(" {:?}: {{", pkg.name());
println!(" 'outputs': [");
for &(ref dst, _, _) in filenames.iter() {
println!(" {:?},", dst);
}
println!(" ],");
cmd.output_build_plan();
println!(" }},");
}
Message::Stdout(out) => {
if cx.config.extra_verbose() {
println!("{}", out);
Expand Down Expand Up @@ -269,7 +287,9 @@ impl<'a> JobQueue<'a> {
build_type,
opt_type,
time_elapsed);
cx.config.shell().status("Finished", message)?;
if !build_plan {
cx.config.shell().status("Finished", message)?;
}
Ok(())
} else if let Some(e) = error {
Err(e)
Expand All @@ -286,7 +306,8 @@ impl<'a> JobQueue<'a> {
fresh: Freshness,
job: Job,
config: &Config,
scope: &Scope<'a>) -> CargoResult<()> {
scope: &Scope<'a>,
build_plan: bool) -> CargoResult<()> {
info!("start: {:?}", key);

self.active += 1;
Expand All @@ -304,8 +325,10 @@ impl<'a> JobQueue<'a> {
Freshness::Dirty => { scope.spawn(doit); }
}

// Print out some nice progress information
self.note_working_on(config, &key, fresh)?;
if !build_plan {
// Print out some nice progress information
self.note_working_on(config, &key, fresh)?;
}

Ok(())
}
Expand Down Expand Up @@ -385,6 +408,19 @@ impl<'a> JobQueue<'a> {
}
Ok(())
}

pub fn output_build_plan(&self) {
let dep_map = self.queue.get_dep_map();
println!("dependencies = {{");
for (key, deps) in dep_map.iter() {
println!(" {:?}: [", key.pkg.name());
for dep in deps.0.iter() {
println!(" {:?},", dep.pkg.name());
}
println!(" ],");
}
println!("}}");
}
}

impl<'a> Key<'a> {
Expand Down
Loading

0 comments on commit 49b9665

Please sign in to comment.