Skip to content

Commit 2f2b827

Browse files
committed
Allow toml targets to be conditionally compiled with cfg(..)
Fix rust-lang#4900 Sort of addresses rust-lang#4881 as well.
1 parent caa7ac1 commit 2f2b827

File tree

14 files changed

+638
-90
lines changed

14 files changed

+638
-90
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
44
use std::str::{self, FromStr};
55

66
use core::profiles::Profiles;
7-
use core::{Dependency, Workspace};
7+
use core::{Dependency, Target, Workspace};
88
use core::{Package, PackageId, PackageSet, Resolve};
99
use util::errors::CargoResult;
1010
use util::{profile, Cfg, CfgExpr, Config, Rustc};
@@ -133,6 +133,18 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
133133
platform.matches(name, info.cfg())
134134
}
135135

136+
pub fn target_platform_activated(&self, target: &Target, kind: Kind) -> bool {
137+
let platform = match target.platform() {
138+
Some(p) => p,
139+
None => return true,
140+
};
141+
let (name, info) = match kind {
142+
Kind::Host => (self.host_triple(), &self.host_info),
143+
Kind::Target => (self.target_triple(), &self.target_info),
144+
};
145+
platform.matches(name, info.cfg())
146+
}
147+
136148
/// Gets a package for the given package id.
137149
pub fn get_package(&self, id: &PackageId) -> CargoResult<&'a Package> {
138150
self.packages.get(id)

src/cargo/core/compiler/context/mod.rs

100644100755
File mode changed.

src/cargo/core/manifest.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use url::Url;
1111

1212
use core::interning::InternedString;
1313
use core::profiles::Profiles;
14-
use core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
14+
use core::{Dependency, PackageId, PackageIdSpec, Platform, SourceId, Summary};
1515
use core::{Edition, Feature, Features, WorkspaceConfig};
1616
use util::errors::*;
1717
use util::toml::TomlManifest;
@@ -171,6 +171,10 @@ pub struct Target {
171171
doctest: bool,
172172
harness: bool, // whether to use the test harness (--test)
173173
for_host: bool,
174+
175+
// This target should only be built for this platform. `None` means *all
176+
// platforms*.
177+
platform: Option<Platform>,
174178
}
175179

176180
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -194,6 +198,7 @@ struct SerializedTarget<'a> {
194198
crate_types: Vec<&'a str>,
195199
name: &'a str,
196200
src_path: &'a PathBuf,
201+
platform: Option<&'a Platform>,
197202
}
198203

199204
impl ser::Serialize for Target {
@@ -203,6 +208,7 @@ impl ser::Serialize for Target {
203208
crate_types: self.rustc_crate_types(),
204209
name: &self.name,
205210
src_path: &self.src_path.path,
211+
platform: self.platform(),
206212
}.serialize(s)
207213
}
208214
}
@@ -417,6 +423,7 @@ impl Target {
417423
for_host: false,
418424
tested: true,
419425
benched: true,
426+
platform: None,
420427
}
421428
}
422429

@@ -537,6 +544,12 @@ impl Target {
537544
self.benched
538545
}
539546

547+
/// If none, this target must be built for all platforms.
548+
/// If some, it must only be built for the specified platform.
549+
pub fn platform(&self) -> Option<&Platform> {
550+
self.platform.as_ref()
551+
}
552+
540553
pub fn doctested(&self) -> bool {
541554
self.doctest && match self.kind {
542555
TargetKind::Lib(ref kinds) => kinds
@@ -552,7 +565,7 @@ impl Target {
552565

553566
pub fn is_lib(&self) -> bool {
554567
match self.kind {
555-
TargetKind::Lib(_) => true,
568+
TargetKind::Lib(..) => true,
556569
_ => false,
557570
}
558571
}
@@ -659,6 +672,10 @@ impl Target {
659672
self.doc = doc;
660673
self
661674
}
675+
pub fn set_platform(&mut self, platform: Option<Platform>) -> &mut Target {
676+
self.platform = platform;
677+
self
678+
}
662679
}
663680

664681
impl fmt::Display for Target {

src/cargo/core/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub use self::dependency::Dependency;
1+
pub use self::dependency::{Dependency, Platform};
22
pub use self::features::{CliUnstable, Edition, Feature, Features};
33
pub use self::manifest::{EitherManifest, VirtualManifest};
44
pub use self::manifest::{LibKind, Manifest, Target, TargetKind};

src/cargo/ops/cargo_compile.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
//! previously compiled dependency
2323
//!
2424
25-
use std::collections::HashSet;
25+
use std::collections::{HashMap, HashSet};
2626
use std::path::PathBuf;
2727
use std::sync::Arc;
2828

@@ -256,8 +256,6 @@ pub fn compile_ws<'a>(
256256
let profiles = ws.profiles();
257257
profiles.validate_packages(&mut config.shell(), &packages)?;
258258

259-
let mut extra_compiler_args = None;
260-
261259
let units = generate_targets(
262260
ws,
263261
profiles,
@@ -268,6 +266,8 @@ pub fn compile_ws<'a>(
268266
build_config,
269267
)?;
270268

269+
let mut extra_compiler_args = None;
270+
271271
if let Some(args) = extra_args {
272272
if units.len() != 1 {
273273
bail!(
@@ -281,7 +281,6 @@ pub fn compile_ws<'a>(
281281
}
282282

283283
let mut ret = {
284-
let _p = profile::start("compiling");
285284
let bcx = BuildContext::new(
286285
ws,
287286
&resolve_with_overrides,
@@ -292,6 +291,57 @@ pub fn compile_ws<'a>(
292291
extra_compiler_args,
293292
)?;
294293
let mut cx = Context::new(config, &bcx)?;
294+
295+
// Filter to just the units whose target is activated.
296+
let units = units
297+
.into_iter()
298+
.filter(|u| {
299+
let kind = if u.target.for_host() {
300+
Kind::Host
301+
} else {
302+
Kind::Target
303+
};
304+
305+
cx.bcx.target_platform_activated(&u.target, kind)
306+
})
307+
.collect::<Vec<_>>();
308+
309+
// Ensure that there is only one [lib] activated per crate.
310+
{
311+
let mut pkg_libs: HashMap<(&PackageId, &str), Vec<&Unit>> = Default::default();
312+
313+
for unit in &units {
314+
if let TargetKind::Lib(_) = *unit.target.kind() {
315+
let pkgid = unit.pkg.package_id();
316+
pkg_libs
317+
.entry((pkgid, &unit.profile.name))
318+
.or_insert(vec![])
319+
.push(unit);
320+
}
321+
}
322+
323+
for ((pkg, profile), libs) in pkg_libs {
324+
if libs.len() > 1 {
325+
let mut msg = format!(
326+
"Can only have one [lib] per crate and profile pair! \
327+
For crate {} and profile {}, found ",
328+
pkg,
329+
profile
330+
);
331+
332+
for (i, u) in libs.into_iter().enumerate() {
333+
if i > 0 {
334+
msg.push_str(", ");
335+
}
336+
msg.push_str(&format!("{}", u.target));
337+
}
338+
339+
bail!(msg);
340+
}
341+
}
342+
}
343+
344+
let _p = profile::start("compiling");
295345
cx.compile(&units, export_dir.clone(), &exec)?
296346
};
297347

src/cargo/util/errors.rs

100644100755
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl CargoTestError {
141141
TargetKind::Bin => {
142142
format!("test failed, to rerun pass '{}--bin {}'", pkg_info, name)
143143
}
144-
TargetKind::Lib(_) => format!("test failed, to rerun pass '{}--lib'", pkg_info),
144+
TargetKind::Lib(..) => format!("test failed, to rerun pass '{}--lib'", pkg_info),
145145
TargetKind::Test => {
146146
format!("test failed, to rerun pass '{}--test {}'", pkg_info, name)
147147
}

src/cargo/util/toml/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,11 @@ impl TomlManifest {
679679
.or_else(|| v.build_dependencies2.as_ref()),
680680
)?,
681681
build_dependencies2: None,
682+
lib: v.lib.clone(),
683+
bin: v.bin.clone(),
684+
bench: v.bench.clone(),
685+
test: v.test.clone(),
686+
example: v.example.clone(),
682687
},
683688
))
684689
})
@@ -1373,6 +1378,12 @@ struct TomlPlatform {
13731378
dev_dependencies: Option<BTreeMap<String, TomlDependency>>,
13741379
#[serde(rename = "dev_dependencies")]
13751380
dev_dependencies2: Option<BTreeMap<String, TomlDependency>>,
1381+
1382+
lib: Option<TomlLibTarget>,
1383+
bin: Option<Vec<TomlBinTarget>>,
1384+
example: Option<Vec<TomlExampleTarget>>,
1385+
test: Option<Vec<TomlTestTarget>>,
1386+
bench: Option<Vec<TomlBenchTarget>>,
13761387
}
13771388

13781389
impl TomlTarget {

0 commit comments

Comments
 (0)