Skip to content

Commit 0d75eb6

Browse files
committed
Auto merge of #1568 - sondrele:rustc-subcommand, r=alexcrichton
## Work in progress I have followed issue #595 for a while now. I hope that this PR can solve it, after it's done of course. @alexcrichton: on IRC the other day, you suggested adding a `Vec<String>` to the `CompileOptions`. I have done this, but wasn't sure what the best way to identify the correct `Target` would be, so currently everything gets compiled with the additional arguments. I considered adding a `Target` structure to the `CompileOptions` as well, and then in `cargo_rustc::build_base_args` only append the arguments if the `Target` matches. What do you think about this? Is there an easier way of figuring out the correct `Target`? r? @alexcrichton
2 parents 1ec2257 + 2cd3c86 commit 0d75eb6

14 files changed

+427
-3
lines changed

src/bin/bench.rs

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
7575
&options.flag_test,
7676
&options.flag_example,
7777
&options.flag_bench),
78+
target_rustc_args: None,
7879
},
7980
};
8081

src/bin/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
7676
&options.flag_test,
7777
&options.flag_example,
7878
&options.flag_bench),
79+
target_rustc_args: None,
7980
};
8081

8182
ops::compile(&root, &opts).map(|_| None).map_err(|err| {

src/bin/cargo.rs

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ macro_rules! each_subcommand{ ($mac:ident) => ({
7676
$mac!(publish);
7777
$mac!(read_manifest);
7878
$mac!(run);
79+
$mac!(rustc);
7980
$mac!(search);
8081
$mac!(test);
8182
$mac!(update);

src/bin/doc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
6262
mode: ops::CompileMode::Doc {
6363
deps: !options.flag_no_deps,
6464
},
65+
target_rustc_args: None,
6566
},
6667
};
6768

src/bin/run.rs

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
7272
bins: &bins, examples: &examples,
7373
}
7474
},
75+
target_rustc_args: None,
7576
};
7677

7778
let err = try!(ops::run(&root,

src/bin/rustc.rs

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use std::env;
2+
3+
use cargo::ops::CompileOptions;
4+
use cargo::ops;
5+
use cargo::util::important_paths::{find_root_manifest_for_cwd};
6+
use cargo::util::{CliResult, CliError, Config};
7+
8+
#[derive(RustcDecodable)]
9+
struct Options {
10+
arg_opts: Option<Vec<String>>,
11+
flag_package: Option<String>,
12+
flag_jobs: Option<u32>,
13+
flag_features: Vec<String>,
14+
flag_no_default_features: bool,
15+
flag_target: Option<String>,
16+
flag_manifest_path: Option<String>,
17+
flag_verbose: bool,
18+
flag_release: bool,
19+
flag_lib: bool,
20+
flag_bin: Vec<String>,
21+
flag_example: Vec<String>,
22+
flag_test: Vec<String>,
23+
flag_bench: Vec<String>,
24+
}
25+
26+
pub const USAGE: &'static str = "
27+
Compile a package and all of its dependencies
28+
29+
Usage:
30+
cargo rustc [options] [--] [<opts>...]
31+
32+
Options:
33+
-h, --help Print this message
34+
-p SPEC, --package SPEC The profile to compile for
35+
-j N, --jobs N The number of jobs to run in parallel
36+
--lib Build only this package's library
37+
--bin NAME Build only the specified binary
38+
--example NAME Build only the specified example
39+
--test NAME Build only the specified test
40+
--bench NAME Build only the specified benchmark
41+
--release Build artifacts in release mode, with optimizations
42+
--features FEATURES Features to compile for the package
43+
--no-default-features Do not compile default features for the package
44+
--target TRIPLE Target triple which compiles will be for
45+
--manifest-path PATH Path to the manifest to fetch depednencies for
46+
-v, --verbose Use verbose output
47+
48+
The specified target for the current package (or package specified by SPEC if
49+
provided) will be compiled along with all of its dependencies. The specified
50+
<opts>... will all be passed to the final compiler invocation, not any of the
51+
dependencies. Note that the compiler will still unconditionally receive
52+
arguments such as -L, --extern, and --crate-type, and the specified <opts>...
53+
will simply be added to the compiler invocation.
54+
55+
This command requires that only one target is being compiled. If more than one
56+
target is available for the current package the filters of --lib, --bin, etc,
57+
must be used to select which target is compiled.
58+
";
59+
60+
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
61+
debug!("executing; cmd=cargo-rustc; args={:?}",
62+
env::args().collect::<Vec<_>>());
63+
config.shell().set_verbose(options.flag_verbose);
64+
65+
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
66+
67+
let opts = CompileOptions {
68+
config: config,
69+
jobs: options.flag_jobs,
70+
target: options.flag_target.as_ref().map(|t| &t[..]),
71+
features: &options.flag_features,
72+
no_default_features: options.flag_no_default_features,
73+
spec: options.flag_package.as_ref().map(|s| &s[..]),
74+
exec_engine: None,
75+
mode: ops::CompileMode::Build,
76+
release: options.flag_release,
77+
filter: ops::CompileFilter::new(options.flag_lib,
78+
&options.flag_bin,
79+
&options.flag_test,
80+
&options.flag_example,
81+
&options.flag_bench),
82+
target_rustc_args: options.arg_opts.as_ref().map(|a| &a[..]),
83+
};
84+
85+
ops::compile(&root, &opts).map(|_| None).map_err(|err| {
86+
CliError::from_boxed(err, 101)
87+
})
88+
}
89+
90+

src/bin/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
7979
&options.flag_test,
8080
&options.flag_example,
8181
&options.flag_bench),
82+
target_rustc_args: None,
8283
},
8384
};
8485

src/cargo/core/manifest.rs

+2
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ pub struct Profile {
116116
pub opt_level: u32,
117117
pub lto: bool,
118118
pub codegen_units: Option<u32>, // None = use rustc default
119+
pub rustc_args: Option<Vec<String>>,
119120
pub debuginfo: bool,
120121
pub debug_assertions: bool,
121122
pub rpath: bool,
@@ -464,6 +465,7 @@ impl Default for Profile {
464465
opt_level: 0,
465466
lto: false,
466467
codegen_units: None,
468+
rustc_args: None,
467469
debuginfo: false,
468470
debug_assertions: false,
469471
rpath: false,

src/cargo/ops/cargo_compile.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ pub struct CompileOptions<'a, 'b: 'a> {
5858
pub release: bool,
5959
/// Mode for this compile.
6060
pub mode: CompileMode,
61+
/// The specified target will be compiled with all the available arguments,
62+
/// note that this only accounts for the *final* invocation of rustc
63+
pub target_rustc_args: Option<&'a [String]>,
6164
}
6265

6366
#[derive(Clone, Copy, PartialEq)]
@@ -102,7 +105,8 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions)
102105
-> CargoResult<ops::Compilation> {
103106
let CompileOptions { config, jobs, target, spec, features,
104107
no_default_features, release, mode,
105-
ref filter, ref exec_engine } = *options;
108+
ref filter, ref exec_engine,
109+
ref target_rustc_args } = *options;
106110

107111
let target = target.map(|s| s.to_string());
108112
let features = features.iter().flat_map(|s| {
@@ -163,6 +167,23 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions)
163167
let to_build = packages.iter().find(|p| p.package_id() == pkgid).unwrap();
164168
let targets = try!(generate_targets(to_build, mode, filter, release));
165169

170+
let target_with_args = match *target_rustc_args {
171+
Some(args) if targets.len() == 1 => {
172+
let (target, profile) = targets[0];
173+
let mut profile = profile.clone();
174+
profile.rustc_args = Some(args.to_vec());
175+
Some((target, profile))
176+
}
177+
Some(_) =>
178+
return Err(human("extra arguments to `rustc` can only be passed to one target, \
179+
consider filtering\nthe package by passing e.g. `--lib` or \
180+
`--bin NAME` to specify a single target")),
181+
None => None,
182+
};
183+
184+
let targets = target_with_args.as_ref().map(|&(t, ref p)| vec![(t, p)])
185+
.unwrap_or(targets);
186+
166187
let ret = {
167188
let _p = profile::start("compiling");
168189
let mut build_config = try!(scrape_build_config(config, jobs, target));

src/cargo/ops/cargo_package.rs

+1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ fn run_verify(config: &Config, pkg: &Package, tar: &Path)
189189
exec_engine: None,
190190
release: false,
191191
mode: ops::CompileMode::Build,
192+
target_rustc_args: None,
192193
}));
193194

194195
Ok(())

src/cargo/ops/cargo_rustc/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,8 @@ fn build_base_args(cx: &Context,
622622
profile: &Profile,
623623
crate_types: &[&str]) {
624624
let Profile {
625-
opt_level, lto, codegen_units, debuginfo, debug_assertions, rpath, test,
626-
doc: _doc,
625+
opt_level, lto, codegen_units, ref rustc_args, debuginfo, debug_assertions,
626+
rpath, test, doc: _doc,
627627
} = *profile;
628628

629629
// Move to cwd so the root_path() passed below is actually correct
@@ -666,6 +666,10 @@ fn build_base_args(cx: &Context,
666666
cmd.arg("-g");
667667
}
668668

669+
if let Some(ref args) = *rustc_args {
670+
cmd.args(args);
671+
}
672+
669673
if debug_assertions && opt_level > 0 {
670674
cmd.args(&["-C", "debug-assertions=on"]);
671675
} else if !debug_assertions && opt_level == 0 {

src/cargo/util/toml.rs

+1
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
814814
opt_level: opt_level.unwrap_or(profile.opt_level),
815815
lto: lto.unwrap_or(profile.lto),
816816
codegen_units: codegen_units,
817+
rustc_args: None,
817818
debuginfo: debug.unwrap_or(profile.debuginfo),
818819
debug_assertions: debug_assertions.unwrap_or(profile.debug_assertions),
819820
rpath: rpath.unwrap_or(profile.rpath),

0 commit comments

Comments
 (0)