Skip to content

Commit bf1a26d

Browse files
committed
Auto merge of #8167 - alexcrichton:multitarget, r=ehuss
Support multiple `--target` flags on the CLI This commit refactors the internals of Cargo to no longer have a singular `--target` flag (and singular `requested_target` kind throught) but to instead have a list. The semantics of multiple `--target` flags is to build the selected targets for each of the input `--target` flag inputs. For now this is gated behind `-Zmultitarget` as an unstable features, since I'm not entirely sure this is the interface we want. In general it'd be great if we had a way to simply specify `Unit` structures of what to build on the CLI, but we're in general very far away from that, so I figured that this is probably sufficient at least for testing for now. cc #8156
2 parents ceef92d + 3fd2814 commit bf1a26d

39 files changed

+659
-413
lines changed

src/bin/cargo/commands/clean.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
2828
let opts = CleanOptions {
2929
config,
3030
spec: values(args, "package"),
31-
target: args.target(),
31+
targets: args.targets(),
3232
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Checked)?,
3333
profile_specified: args.is_present("profile") || args.is_present("release"),
3434
doc: args.is_present("doc"),

src/bin/cargo/commands/fetch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
2828

2929
let opts = FetchOptions {
3030
config,
31-
target: args.target(),
31+
targets: args.targets(),
3232
};
3333
let _ = ops::fetch(&ws, &opts)?;
3434
Ok(())

src/bin/cargo/commands/metadata.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ pub fn cli() -> App {
1212
)
1313
.arg(opt("quiet", "No output printed to stdout").short("q"))
1414
.arg_features()
15-
.arg(
16-
opt(
17-
"filter-platform",
18-
"Only include resolve dependencies matching the given target-triple",
19-
)
20-
.value_name("TRIPLE"),
21-
)
15+
.arg(multi_opt(
16+
"filter-platform",
17+
"TRIPLE",
18+
"Only include resolve dependencies matching the given target-triple",
19+
))
2220
.arg(opt(
2321
"no-deps",
2422
"Output information only about the workspace members \
@@ -51,7 +49,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
5149
all_features: args.is_present("all-features"),
5250
no_default_features: args.is_present("no-default-features"),
5351
no_deps: args.is_present("no-deps"),
54-
filter_platform: args.value_of("filter-platform").map(|s| s.to_string()),
52+
filter_platforms: args._values_of("filter-platform"),
5553
version,
5654
};
5755

src/bin/cargo/commands/package.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
4242
list: args.is_present("list"),
4343
check_metadata: !args.is_present("no-metadata"),
4444
allow_dirty: args.is_present("allow-dirty"),
45-
target: args.target(),
45+
targets: args.targets(),
4646
jobs: args.jobs()?,
4747
features: args._values_of("features"),
4848
all_features: args.is_present("all-features"),

src/bin/cargo/commands/publish.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
4040
index,
4141
verify: !args.is_present("no-verify"),
4242
allow_dirty: args.is_present("allow-dirty"),
43-
target: args.target(),
43+
targets: args.targets(),
4444
jobs: args.jobs()?,
4545
dry_run: args.is_present("dry-run"),
4646
registry,

src/bin/cargo/commands/tree.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
129129
)?;
130130
}
131131

132-
let target = if args.is_present("all-targets") {
132+
let targets = if args.is_present("all-targets") {
133133
config
134134
.shell()
135135
.warn("the --all-targets flag has been changed to --target=all")?;
136-
Some("all")
136+
vec!["all".to_string()]
137137
} else {
138-
args.value_of("target")
138+
args._values_of("target")
139139
};
140-
let target = tree::Target::from_cli(target);
140+
let target = tree::Target::from_cli(targets);
141141

142142
let edge_kinds = parse_edge_kinds(config, args)?;
143143
let graph_features = edge_kinds.contains(&EdgeKind::Feature);

src/cargo/core/compiler/build_config.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::core::compiler::CompileKind;
22
use crate::core::interning::InternedString;
33
use crate::util::ProcessBuilder;
44
use crate::util::{CargoResult, Config, RustfixDiagnosticServer};
5+
use anyhow::bail;
56
use serde::ser;
67
use std::cell::RefCell;
78
use std::path::PathBuf;
@@ -10,7 +11,7 @@ use std::path::PathBuf;
1011
#[derive(Debug)]
1112
pub struct BuildConfig {
1213
/// The requested kind of compilation for this session
13-
pub requested_kind: CompileKind,
14+
pub requested_kinds: Vec<CompileKind>,
1415
/// Number of rustc jobs to run in parallel.
1516
pub jobs: u32,
1617
/// Build profile
@@ -50,12 +51,11 @@ impl BuildConfig {
5051
pub fn new(
5152
config: &Config,
5253
jobs: Option<u32>,
53-
requested_target: &Option<String>,
54+
requested_targets: &[String],
5455
mode: CompileMode,
5556
) -> CargoResult<BuildConfig> {
5657
let cfg = config.build_config()?;
57-
let requested_kind =
58-
CompileKind::from_requested_target(config, requested_target.as_deref())?;
58+
let requested_kinds = CompileKind::from_requested_targets(config, requested_targets)?;
5959
if jobs == Some(0) {
6060
anyhow::bail!("jobs must be at least 1")
6161
}
@@ -69,7 +69,7 @@ impl BuildConfig {
6969
let jobs = jobs.or(cfg.jobs).unwrap_or(::num_cpus::get() as u32);
7070

7171
Ok(BuildConfig {
72-
requested_kind,
72+
requested_kinds,
7373
jobs,
7474
requested_profile: InternedString::new("dev"),
7575
mode,
@@ -95,6 +95,13 @@ impl BuildConfig {
9595
pub fn test(&self) -> bool {
9696
self.mode == CompileMode::Test || self.mode == CompileMode::Bench
9797
}
98+
99+
pub fn single_requested_kind(&self) -> CargoResult<CompileKind> {
100+
match self.requested_kinds.len() {
101+
1 => Ok(self.requested_kinds[0]),
102+
_ => bail!("only one `--target` argument is supported"),
103+
}
104+
}
98105
}
99106

100107
#[derive(Clone, Copy, Debug, PartialEq, Eq)]

src/cargo/core/compiler/build_context/target_info.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,18 @@ impl FileType {
9090
impl TargetInfo {
9191
pub fn new(
9292
config: &Config,
93-
requested_kind: CompileKind,
93+
requested_kinds: &[CompileKind],
9494
rustc: &Rustc,
9595
kind: CompileKind,
9696
) -> CargoResult<TargetInfo> {
97-
let rustflags = env_args(config, requested_kind, &rustc.host, None, kind, "RUSTFLAGS")?;
97+
let rustflags = env_args(
98+
config,
99+
requested_kinds,
100+
&rustc.host,
101+
None,
102+
kind,
103+
"RUSTFLAGS",
104+
)?;
98105
let mut process = rustc.process();
99106
process
100107
.arg("-")
@@ -180,15 +187,15 @@ impl TargetInfo {
180187
// information
181188
rustflags: env_args(
182189
config,
183-
requested_kind,
190+
requested_kinds,
184191
&rustc.host,
185192
Some(&cfg),
186193
kind,
187194
"RUSTFLAGS",
188195
)?,
189196
rustdocflags: env_args(
190197
config,
191-
requested_kind,
198+
requested_kinds,
192199
&rustc.host,
193200
Some(&cfg),
194201
kind,
@@ -416,7 +423,7 @@ fn output_err_info(cmd: &ProcessBuilder, stdout: &str, stderr: &str) -> String {
416423
/// scripts, ...), even if it is the same as the target.
417424
fn env_args(
418425
config: &Config,
419-
requested_kind: CompileKind,
426+
requested_kinds: &[CompileKind],
420427
host_triple: &str,
421428
target_cfg: Option<&[Cfg]>,
422429
kind: CompileKind,
@@ -441,7 +448,7 @@ fn env_args(
441448
// This means that, e.g., even if the specified --target is the
442449
// same as the host, build scripts in plugins won't get
443450
// RUSTFLAGS.
444-
if !requested_kind.is_host() && kind.is_host() {
451+
if requested_kinds != &[CompileKind::Host] && kind.is_host() {
445452
// This is probably a build script or plugin and we're
446453
// compiling with --target. In this scenario there are
447454
// no rustflags we can apply.
@@ -526,20 +533,25 @@ pub struct RustcTargetData {
526533
}
527534

528535
impl RustcTargetData {
529-
pub fn new(ws: &Workspace<'_>, requested_kind: CompileKind) -> CargoResult<RustcTargetData> {
536+
pub fn new(
537+
ws: &Workspace<'_>,
538+
requested_kinds: &[CompileKind],
539+
) -> CargoResult<RustcTargetData> {
530540
let config = ws.config();
531541
let rustc = config.load_global_rustc(Some(ws))?;
532542
let host_config = config.target_cfg_triple(&rustc.host)?;
533-
let host_info = TargetInfo::new(config, requested_kind, &rustc, CompileKind::Host)?;
543+
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
534544
let mut target_config = HashMap::new();
535545
let mut target_info = HashMap::new();
536-
if let CompileKind::Target(target) = requested_kind {
537-
let tcfg = config.target_cfg_triple(target.short_name())?;
538-
target_config.insert(target, tcfg);
539-
target_info.insert(
540-
target,
541-
TargetInfo::new(config, requested_kind, &rustc, CompileKind::Target(target))?,
542-
);
546+
for kind in requested_kinds {
547+
if let CompileKind::Target(target) = *kind {
548+
let tcfg = config.target_cfg_triple(target.short_name())?;
549+
target_config.insert(target, tcfg);
550+
target_info.insert(
551+
target,
552+
TargetInfo::new(config, requested_kinds, &rustc, *kind)?,
553+
);
554+
}
543555
}
544556

545557
Ok(RustcTargetData {

0 commit comments

Comments
 (0)