-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustc subcommand #1568
rustc subcommand #1568
Changes from 9 commits
754938f
77bb01e
b177d2a
512b217
53453c8
582e9d9
d8cd6f0
bd4d15f
c867813
dc33bfa
98c0e2d
2cd3c86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use std::env; | ||
|
||
use cargo::ops::CompileOptions; | ||
use cargo::ops; | ||
use cargo::util::important_paths::{find_root_manifest_for_cwd}; | ||
use cargo::util::{CliResult, CliError, Config}; | ||
|
||
#[derive(RustcDecodable)] | ||
struct Options { | ||
arg_opts: Option<Vec<String>>, | ||
flag_package: Option<String>, | ||
flag_jobs: Option<u32>, | ||
flag_features: Vec<String>, | ||
flag_no_default_features: bool, | ||
flag_target: Option<String>, | ||
flag_manifest_path: Option<String>, | ||
flag_verbose: bool, | ||
flag_release: bool, | ||
flag_lib: bool, | ||
flag_bin: Vec<String>, | ||
flag_example: Vec<String>, | ||
flag_test: Vec<String>, | ||
flag_bench: Vec<String>, | ||
} | ||
|
||
pub const USAGE: &'static str = " | ||
Compile a package and all of its dependencies | ||
|
||
Usage: | ||
cargo rustc [options] [--] [<opts>...] | ||
|
||
Options: | ||
-h, --help Print this message | ||
-p SPEC, --package SPEC The profile to compile for | ||
-j N, --jobs N The number of jobs to run in parallel | ||
--lib Build only this package's library | ||
--bin NAME Build only the specified binary | ||
--example NAME Build only the specified example | ||
--test NAME Build only the specified test | ||
--bench NAME Build only the specified benchmark | ||
--release Build artifacts in release mode, with optimizations | ||
--features FEATURES Features to compile for the package | ||
--no-default-features Do not compile default features for the package | ||
--target TRIPLE Target triple which compiles will be for | ||
--manifest-path PATH Path to the manifest to fetch depednencies for | ||
-v, --verbose Use verbose output | ||
|
||
The <pkgid> specified (defaults to the current package) will have all of its | ||
dependencies compiled, and then the package itself will be compiled. This | ||
command requires that a lockfile is available and dependencies have been | ||
fetched. | ||
|
||
All of the trailing arguments are passed through to the *final* rustc | ||
invocation, not any of the dependencies. | ||
|
||
Dependencies will not be recompiled if they do not need to be, but the package | ||
specified will always be compiled. The compiler will receive a number of | ||
arguments unconditionally such as --extern, -L, etc. Note that dependencies are | ||
recompiled when the flags they're compiled with change, so it is not allowed to | ||
manually compile a package's dependencies and then compile the package against | ||
the artifacts just generated. | ||
"; | ||
|
||
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> { | ||
debug!("executing; cmd=cargo-rustc; args={:?}", | ||
env::args().collect::<Vec<_>>()); | ||
config.shell().set_verbose(options.flag_verbose); | ||
|
||
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); | ||
|
||
let opts = CompileOptions { | ||
config: config, | ||
jobs: options.flag_jobs, | ||
target: options.flag_target.as_ref().map(|t| &t[..]), | ||
features: &options.flag_features, | ||
no_default_features: options.flag_no_default_features, | ||
spec: options.flag_package.as_ref().map(|s| &s[..]), | ||
exec_engine: None, | ||
mode: ops::CompileMode::Build, | ||
release: options.flag_release, | ||
filter: ops::CompileFilter::new(options.flag_lib, | ||
&options.flag_bin, | ||
&options.flag_test, | ||
&options.flag_example, | ||
&options.flag_bench), | ||
target_rustc_args: options.arg_opts.as_ref().map(|a| &a[..]), | ||
}; | ||
|
||
ops::compile(&root, &opts).map(|_| None).map_err(|err| { | ||
CliError::from_boxed(err, 101) | ||
}) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,9 @@ pub struct CompileOptions<'a, 'b: 'a> { | |
pub release: bool, | ||
/// Mode for this compile. | ||
pub mode: CompileMode, | ||
/// The specified target will be compiled with all the available arguments, | ||
/// note that this only accounts for the *final* invocation of rustc | ||
pub target_rustc_args: Option<&'a [String]>, | ||
} | ||
|
||
#[derive(Clone, Copy, PartialEq)] | ||
|
@@ -102,7 +105,8 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions) | |
-> CargoResult<ops::Compilation> { | ||
let CompileOptions { config, jobs, target, spec, features, | ||
no_default_features, release, mode, | ||
ref filter, ref exec_engine } = *options; | ||
ref filter, ref exec_engine, | ||
ref target_rustc_args } = *options; | ||
|
||
let target = target.map(|s| s.to_string()); | ||
let features = features.iter().flat_map(|s| { | ||
|
@@ -163,6 +167,23 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions) | |
let to_build = packages.iter().find(|p| p.package_id() == pkgid).unwrap(); | ||
let targets = try!(generate_targets(to_build, mode, filter, release)); | ||
|
||
let target_with_args = match target_rustc_args { | ||
&Some(args) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typically instead of matching match *target_rustc_args {
Some(args) if args.len() > 1 => return Err(...),
Some(args) => { ... }
// ...
} |
||
if targets.len() > 1 { | ||
return Err(human("extra arguments to `rustc` can only be \ | ||
invoked for one target")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I agree that it would be nice to improve this error message a bit. It would be nice for it to mention the filtering utilities (e.g. |
||
} | ||
let (target, profile) = targets[0]; | ||
let mut profile = profile.clone(); | ||
profile.rustc_args = Some(args.to_vec()); | ||
Some((target, profile)) | ||
}, | ||
&None => None, | ||
}; | ||
|
||
let targets = target_with_args.as_ref().map(|&(t, ref p)| vec!((t, p))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typically we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, could this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, I'm not exactly sure how this would be done since I'm already cloning the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh right it needs to be rooted somewhere, nevermind! |
||
.unwrap_or(targets); | ||
|
||
let ret = { | ||
let _p = profile::start("compiling"); | ||
let mut build_config = try!(scrape_build_config(config, jobs, target)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -620,8 +620,8 @@ fn build_base_args(cx: &Context, | |
profile: &Profile, | ||
crate_types: &[&str]) { | ||
let Profile { | ||
opt_level, lto, codegen_units, debuginfo, debug_assertions, rpath, test, | ||
doc: _doc, | ||
opt_level, lto, codegen_units, ref rustc_args, debuginfo, debug_assertions, | ||
rpath, test, doc: _doc, | ||
} = *profile; | ||
|
||
// Move to cwd so the root_path() passed below is actually correct | ||
|
@@ -664,6 +664,10 @@ fn build_base_args(cx: &Context, | |
cmd.arg("-g"); | ||
} | ||
|
||
if let &Some(ref args) = rustc_args { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
cmd.args(args); | ||
} | ||
|
||
if debug_assertions && opt_level > 0 { | ||
cmd.args(&["-C", "debug-assertions=on"]); | ||
} else if !debug_assertions && opt_level == 0 { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this documentation may want to be touched up a bit, perhaps something along the lines of: