Skip to content

Commit

Permalink
Allow toml targets to be conditionally compiled with cfg(..)
Browse files Browse the repository at this point in the history
Fix rust-lang#4900

Sort of addresses rust-lang#4881 as well.
  • Loading branch information
fitzgen committed May 8, 2018
1 parent caa7ac1 commit 2f2b827
Show file tree
Hide file tree
Showing 14 changed files with 638 additions and 90 deletions.
14 changes: 13 additions & 1 deletion src/cargo/core/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use std::str::{self, FromStr};

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

pub fn target_platform_activated(&self, target: &Target, kind: Kind) -> bool {
let platform = match target.platform() {
Some(p) => p,
None => return true,
};
let (name, info) = match kind {
Kind::Host => (self.host_triple(), &self.host_info),
Kind::Target => (self.target_triple(), &self.target_info),
};
platform.matches(name, info.cfg())
}

/// Gets a package for the given package id.
pub fn get_package(&self, id: &PackageId) -> CargoResult<&'a Package> {
self.packages.get(id)
Expand Down
Empty file modified src/cargo/core/compiler/context/mod.rs
100644 → 100755
Empty file.
21 changes: 19 additions & 2 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use url::Url;

use core::interning::InternedString;
use core::profiles::Profiles;
use core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
use core::{Dependency, PackageId, PackageIdSpec, Platform, SourceId, Summary};
use core::{Edition, Feature, Features, WorkspaceConfig};
use util::errors::*;
use util::toml::TomlManifest;
Expand Down Expand Up @@ -171,6 +171,10 @@ pub struct Target {
doctest: bool,
harness: bool, // whether to use the test harness (--test)
for_host: bool,

// This target should only be built for this platform. `None` means *all
// platforms*.
platform: Option<Platform>,
}

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

impl ser::Serialize for Target {
Expand All @@ -203,6 +208,7 @@ impl ser::Serialize for Target {
crate_types: self.rustc_crate_types(),
name: &self.name,
src_path: &self.src_path.path,
platform: self.platform(),
}.serialize(s)
}
}
Expand Down Expand Up @@ -417,6 +423,7 @@ impl Target {
for_host: false,
tested: true,
benched: true,
platform: None,
}
}

Expand Down Expand Up @@ -537,6 +544,12 @@ impl Target {
self.benched
}

/// If none, this target must be built for all platforms.
/// If some, it must only be built for the specified platform.
pub fn platform(&self) -> Option<&Platform> {
self.platform.as_ref()
}

pub fn doctested(&self) -> bool {
self.doctest && match self.kind {
TargetKind::Lib(ref kinds) => kinds
Expand All @@ -552,7 +565,7 @@ impl Target {

pub fn is_lib(&self) -> bool {
match self.kind {
TargetKind::Lib(_) => true,
TargetKind::Lib(..) => true,
_ => false,
}
}
Expand Down Expand Up @@ -659,6 +672,10 @@ impl Target {
self.doc = doc;
self
}
pub fn set_platform(&mut self, platform: Option<Platform>) -> &mut Target {
self.platform = platform;
self
}
}

impl fmt::Display for Target {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub use self::dependency::Dependency;
pub use self::dependency::{Dependency, Platform};
pub use self::features::{CliUnstable, Edition, Feature, Features};
pub use self::manifest::{EitherManifest, VirtualManifest};
pub use self::manifest::{LibKind, Manifest, Target, TargetKind};
Expand Down
58 changes: 54 additions & 4 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
//! previously compiled dependency
//!

use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use std::path::PathBuf;
use std::sync::Arc;

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

let mut extra_compiler_args = None;

let units = generate_targets(
ws,
profiles,
Expand All @@ -268,6 +266,8 @@ pub fn compile_ws<'a>(
build_config,
)?;

let mut extra_compiler_args = None;

if let Some(args) = extra_args {
if units.len() != 1 {
bail!(
Expand All @@ -281,7 +281,6 @@ pub fn compile_ws<'a>(
}

let mut ret = {
let _p = profile::start("compiling");
let bcx = BuildContext::new(
ws,
&resolve_with_overrides,
Expand All @@ -292,6 +291,57 @@ pub fn compile_ws<'a>(
extra_compiler_args,
)?;
let mut cx = Context::new(config, &bcx)?;

// Filter to just the units whose target is activated.
let units = units
.into_iter()
.filter(|u| {
let kind = if u.target.for_host() {
Kind::Host
} else {
Kind::Target
};

cx.bcx.target_platform_activated(&u.target, kind)
})
.collect::<Vec<_>>();

// Ensure that there is only one [lib] activated per crate.
{
let mut pkg_libs: HashMap<(&PackageId, &str), Vec<&Unit>> = Default::default();

for unit in &units {
if let TargetKind::Lib(_) = *unit.target.kind() {
let pkgid = unit.pkg.package_id();
pkg_libs
.entry((pkgid, &unit.profile.name))
.or_insert(vec![])
.push(unit);
}
}

for ((pkg, profile), libs) in pkg_libs {
if libs.len() > 1 {
let mut msg = format!(
"Can only have one [lib] per crate and profile pair! \
For crate {} and profile {}, found ",
pkg,
profile
);

for (i, u) in libs.into_iter().enumerate() {
if i > 0 {
msg.push_str(", ");
}
msg.push_str(&format!("{}", u.target));
}

bail!(msg);
}
}
}

let _p = profile::start("compiling");
cx.compile(&units, export_dir.clone(), &exec)?
};

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/util/errors.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl CargoTestError {
TargetKind::Bin => {
format!("test failed, to rerun pass '{}--bin {}'", pkg_info, name)
}
TargetKind::Lib(_) => format!("test failed, to rerun pass '{}--lib'", pkg_info),
TargetKind::Lib(..) => format!("test failed, to rerun pass '{}--lib'", pkg_info),
TargetKind::Test => {
format!("test failed, to rerun pass '{}--test {}'", pkg_info, name)
}
Expand Down
11 changes: 11 additions & 0 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,11 @@ impl TomlManifest {
.or_else(|| v.build_dependencies2.as_ref()),
)?,
build_dependencies2: None,
lib: v.lib.clone(),
bin: v.bin.clone(),
bench: v.bench.clone(),
test: v.test.clone(),
example: v.example.clone(),
},
))
})
Expand Down Expand Up @@ -1373,6 +1378,12 @@ struct TomlPlatform {
dev_dependencies: Option<BTreeMap<String, TomlDependency>>,
#[serde(rename = "dev_dependencies")]
dev_dependencies2: Option<BTreeMap<String, TomlDependency>>,

lib: Option<TomlLibTarget>,
bin: Option<Vec<TomlBinTarget>>,
example: Option<Vec<TomlExampleTarget>>,
test: Option<Vec<TomlTestTarget>>,
bench: Option<Vec<TomlBenchTarget>>,
}

impl TomlTarget {
Expand Down
Loading

0 comments on commit 2f2b827

Please sign in to comment.