Skip to content

Commit

Permalink
Support multiple --target flags on the CLI
Browse files Browse the repository at this point in the history
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
  • Loading branch information
alexcrichton committed Apr 28, 2020
1 parent ceef92d commit 3fd2814
Show file tree
Hide file tree
Showing 39 changed files with 659 additions and 413 deletions.
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let opts = CleanOptions {
config,
spec: values(args, "package"),
target: args.target(),
targets: args.targets(),
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Checked)?,
profile_specified: args.is_present("profile") || args.is_present("release"),
doc: args.is_present("doc"),
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {

let opts = FetchOptions {
config,
target: args.target(),
targets: args.targets(),
};
let _ = ops::fetch(&ws, &opts)?;
Ok(())
Expand Down
14 changes: 6 additions & 8 deletions src/bin/cargo/commands/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ pub fn cli() -> App {
)
.arg(opt("quiet", "No output printed to stdout").short("q"))
.arg_features()
.arg(
opt(
"filter-platform",
"Only include resolve dependencies matching the given target-triple",
)
.value_name("TRIPLE"),
)
.arg(multi_opt(
"filter-platform",
"TRIPLE",
"Only include resolve dependencies matching the given target-triple",
))
.arg(opt(
"no-deps",
"Output information only about the workspace members \
Expand Down Expand Up @@ -51,7 +49,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
all_features: args.is_present("all-features"),
no_default_features: args.is_present("no-default-features"),
no_deps: args.is_present("no-deps"),
filter_platform: args.value_of("filter-platform").map(|s| s.to_string()),
filter_platforms: args._values_of("filter-platform"),
version,
};

Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
list: args.is_present("list"),
check_metadata: !args.is_present("no-metadata"),
allow_dirty: args.is_present("allow-dirty"),
target: args.target(),
targets: args.targets(),
jobs: args.jobs()?,
features: args._values_of("features"),
all_features: args.is_present("all-features"),
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo/commands/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
index,
verify: !args.is_present("no-verify"),
allow_dirty: args.is_present("allow-dirty"),
target: args.target(),
targets: args.targets(),
jobs: args.jobs()?,
dry_run: args.is_present("dry-run"),
registry,
Expand Down
8 changes: 4 additions & 4 deletions src/bin/cargo/commands/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
)?;
}

let target = if args.is_present("all-targets") {
let targets = if args.is_present("all-targets") {
config
.shell()
.warn("the --all-targets flag has been changed to --target=all")?;
Some("all")
vec!["all".to_string()]
} else {
args.value_of("target")
args._values_of("target")
};
let target = tree::Target::from_cli(target);
let target = tree::Target::from_cli(targets);

let edge_kinds = parse_edge_kinds(config, args)?;
let graph_features = edge_kinds.contains(&EdgeKind::Feature);
Expand Down
17 changes: 12 additions & 5 deletions src/cargo/core/compiler/build_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::core::compiler::CompileKind;
use crate::core::interning::InternedString;
use crate::util::ProcessBuilder;
use crate::util::{CargoResult, Config, RustfixDiagnosticServer};
use anyhow::bail;
use serde::ser;
use std::cell::RefCell;
use std::path::PathBuf;
Expand All @@ -10,7 +11,7 @@ use std::path::PathBuf;
#[derive(Debug)]
pub struct BuildConfig {
/// The requested kind of compilation for this session
pub requested_kind: CompileKind,
pub requested_kinds: Vec<CompileKind>,
/// Number of rustc jobs to run in parallel.
pub jobs: u32,
/// Build profile
Expand Down Expand Up @@ -50,12 +51,11 @@ impl BuildConfig {
pub fn new(
config: &Config,
jobs: Option<u32>,
requested_target: &Option<String>,
requested_targets: &[String],
mode: CompileMode,
) -> CargoResult<BuildConfig> {
let cfg = config.build_config()?;
let requested_kind =
CompileKind::from_requested_target(config, requested_target.as_deref())?;
let requested_kinds = CompileKind::from_requested_targets(config, requested_targets)?;
if jobs == Some(0) {
anyhow::bail!("jobs must be at least 1")
}
Expand All @@ -69,7 +69,7 @@ impl BuildConfig {
let jobs = jobs.or(cfg.jobs).unwrap_or(::num_cpus::get() as u32);

Ok(BuildConfig {
requested_kind,
requested_kinds,
jobs,
requested_profile: InternedString::new("dev"),
mode,
Expand All @@ -95,6 +95,13 @@ impl BuildConfig {
pub fn test(&self) -> bool {
self.mode == CompileMode::Test || self.mode == CompileMode::Bench
}

pub fn single_requested_kind(&self) -> CargoResult<CompileKind> {
match self.requested_kinds.len() {
1 => Ok(self.requested_kinds[0]),
_ => bail!("only one `--target` argument is supported"),
}
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down
42 changes: 27 additions & 15 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,18 @@ impl FileType {
impl TargetInfo {
pub fn new(
config: &Config,
requested_kind: CompileKind,
requested_kinds: &[CompileKind],
rustc: &Rustc,
kind: CompileKind,
) -> CargoResult<TargetInfo> {
let rustflags = env_args(config, requested_kind, &rustc.host, None, kind, "RUSTFLAGS")?;
let rustflags = env_args(
config,
requested_kinds,
&rustc.host,
None,
kind,
"RUSTFLAGS",
)?;
let mut process = rustc.process();
process
.arg("-")
Expand Down Expand Up @@ -180,15 +187,15 @@ impl TargetInfo {
// information
rustflags: env_args(
config,
requested_kind,
requested_kinds,
&rustc.host,
Some(&cfg),
kind,
"RUSTFLAGS",
)?,
rustdocflags: env_args(
config,
requested_kind,
requested_kinds,
&rustc.host,
Some(&cfg),
kind,
Expand Down Expand Up @@ -416,7 +423,7 @@ fn output_err_info(cmd: &ProcessBuilder, stdout: &str, stderr: &str) -> String {
/// scripts, ...), even if it is the same as the target.
fn env_args(
config: &Config,
requested_kind: CompileKind,
requested_kinds: &[CompileKind],
host_triple: &str,
target_cfg: Option<&[Cfg]>,
kind: CompileKind,
Expand All @@ -441,7 +448,7 @@ fn env_args(
// This means that, e.g., even if the specified --target is the
// same as the host, build scripts in plugins won't get
// RUSTFLAGS.
if !requested_kind.is_host() && kind.is_host() {
if requested_kinds != &[CompileKind::Host] && kind.is_host() {
// This is probably a build script or plugin and we're
// compiling with --target. In this scenario there are
// no rustflags we can apply.
Expand Down Expand Up @@ -526,20 +533,25 @@ pub struct RustcTargetData {
}

impl RustcTargetData {
pub fn new(ws: &Workspace<'_>, requested_kind: CompileKind) -> CargoResult<RustcTargetData> {
pub fn new(
ws: &Workspace<'_>,
requested_kinds: &[CompileKind],
) -> CargoResult<RustcTargetData> {
let config = ws.config();
let rustc = config.load_global_rustc(Some(ws))?;
let host_config = config.target_cfg_triple(&rustc.host)?;
let host_info = TargetInfo::new(config, requested_kind, &rustc, CompileKind::Host)?;
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
let mut target_config = HashMap::new();
let mut target_info = HashMap::new();
if let CompileKind::Target(target) = requested_kind {
let tcfg = config.target_cfg_triple(target.short_name())?;
target_config.insert(target, tcfg);
target_info.insert(
target,
TargetInfo::new(config, requested_kind, &rustc, CompileKind::Target(target))?,
);
for kind in requested_kinds {
if let CompileKind::Target(target) = *kind {
let tcfg = config.target_cfg_triple(target.short_name())?;
target_config.insert(target, tcfg);
target_info.insert(
target,
TargetInfo::new(config, requested_kinds, &rustc, *kind)?,
);
}
}

Ok(RustcTargetData {
Expand Down
Loading

0 comments on commit 3fd2814

Please sign in to comment.