Skip to content

Commit

Permalink
auto merge of #792 : alexcrichton/cargo/build-cmd, r=brson
Browse files Browse the repository at this point in the history
This series of commits (based on #763) is an implementation of the recent [Cargo RFC](https://github.com/rust-lang/rfcs/blob/master/text/0403-cargo-build-command.md). This should implement all portions of the RFC, but there's a lot so an extra set of eyes would be nice!

I haven't added documentation for it all yet, but I would like to do so before landing (starting with #749). Otherwise I've been migrating all of the existing cargo dependencies away from the build command to a build script, and the progress can be seen with these repositories:

* https://github.com/alexcrichton/gcc-rs
* https://github.com/alexcrichton/pkg-config-rs
* https://github.com/alexcrichton/git2-rs/tree/build-cmd
* https://github.com/alexcrichton/openssl-sys
* https://github.com/alexcrichton/flate2-rs/tree/build-cmd
* https://github.com/alexcrichton/libz-sys
* https://github.com/alexcrichton/ssh2-rs/tree/build-cmd

I haven't quite gotten around to curl just yet, but it's next on my list!
  • Loading branch information
bors committed Nov 5, 2014
2 parents 1852281 + 5e29a8b commit 6e94e58
Show file tree
Hide file tree
Showing 32 changed files with 2,665 additions and 816 deletions.
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ clean:

# === Documentation

DOCS := index faq config guide manifest native-build pkgid-spec
DOCS := index faq config guide manifest build-script pkgid-spec
DOC_DIR := target/doc
DOC_OPTS := --markdown-no-toc \
--markdown-css stylesheets/normalize.css \
Expand Down
25 changes: 20 additions & 5 deletions src/cargo/core/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct Dependency {
source_id: SourceId,
req: VersionReq,
specified_req: Option<String>,
transitive: bool,
kind: Kind,
only_match_name: bool,

optional: bool,
Expand All @@ -22,6 +22,13 @@ pub struct Dependency {
only_for_platform: Option<String>,
}

#[deriving(PartialEq, Clone, Show)]
pub enum Kind {
Normal,
Development,
Build,
}

impl Dependency {
/// Attempt to create a `Dependency` from an entry in the manifest.
///
Expand Down Expand Up @@ -55,7 +62,7 @@ impl Dependency {
name: name.to_string(),
source_id: source_id.clone(),
req: VersionReq::any(),
transitive: true,
kind: Normal,
only_match_name: true,
optional: false,
features: Vec::new(),
Expand Down Expand Up @@ -83,8 +90,8 @@ impl Dependency {
&self.source_id
}

pub fn transitive(mut self, transitive: bool) -> Dependency {
self.transitive = transitive;
pub fn kind(mut self, kind: Kind) -> Dependency {
self.kind = kind;
self
}

Expand Down Expand Up @@ -132,7 +139,15 @@ impl Dependency {
}

/// Returns false if the dependency is only used to build the local package.
pub fn is_transitive(&self) -> bool { self.transitive }
pub fn is_transitive(&self) -> bool {
match self.kind {
Normal | Build => true,
Development => false,
}
}
pub fn is_build(&self) -> bool {
match self.kind { Build => true, _ => false }
}
pub fn is_optional(&self) -> bool { self.optional }
/// Returns true if the default features of the dependency are requested.
pub fn uses_default_features(&self) -> bool { self.default_features }
Expand Down
59 changes: 47 additions & 12 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ pub struct Manifest {
targets: Vec<Target>,
target_dir: Path,
doc_dir: Path,
build: Vec<String>,
build: Vec<String>, // TODO: deprecated, remove
links: Option<String>,
warnings: Vec<String>,
exclude: Vec<String>,
metadata: ManifestMetadata,
Expand Down Expand Up @@ -59,7 +60,7 @@ pub struct SerializedManifest {
targets: Vec<Target>,
target_dir: String,
doc_dir: String,
build: Option<Vec<String>>,
build: Option<Vec<String>>, // TODO: deprecated, remove
}

impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
Expand All @@ -73,6 +74,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
targets: self.targets.clone(),
target_dir: self.target_dir.display().to_string(),
doc_dir: self.doc_dir.display().to_string(),
// TODO: deprecated, remove
build: if self.build.len() == 0 { None } else { Some(self.build.clone()) },
}.encode(s)
}
Expand Down Expand Up @@ -131,8 +133,9 @@ pub struct Profile {
doctest: bool,
doc: bool,
dest: Option<String>,
plugin: bool,
for_host: bool,
harness: bool, // whether to use the test harness (--test)
custom_build: bool,
}

impl Profile {
Expand All @@ -146,8 +149,9 @@ impl Profile {
test: false,
doc: false,
dest: None,
plugin: false,
for_host: false,
doctest: false,
custom_build: false,
harness: true,
}
}
Expand Down Expand Up @@ -219,8 +223,13 @@ impl Profile {
self.doctest
}

pub fn is_plugin(&self) -> bool {
self.plugin
pub fn is_custom_build(&self) -> bool {
self.custom_build
}

/// Returns true if the target must be built for the host instead of the target.
pub fn is_for_host(&self) -> bool {
self.for_host
}

pub fn get_opt_level(&self) -> uint {
Expand Down Expand Up @@ -282,15 +291,22 @@ impl Profile {
self
}

pub fn plugin(mut self, plugin: bool) -> Profile {
self.plugin = plugin;
/// Sets whether the `Target` must be compiled for the host instead of the target platform.
pub fn for_host(mut self, for_host: bool) -> Profile {
self.for_host = for_host;
self
}

pub fn harness(mut self, harness: bool) -> Profile {
self.harness = harness;
self
}

/// Sets whether the `Target` is a custom build script.
pub fn custom_build(mut self, custom_build: bool) -> Profile {
self.custom_build = custom_build;
self
}
}

impl<H: hash::Writer> hash::Hash<H> for Profile {
Expand All @@ -302,7 +318,7 @@ impl<H: hash::Writer> hash::Hash<H> for Profile {
codegen_units,
debug,
rpath,
plugin,
for_host,
ref dest,
harness,

Expand All @@ -313,8 +329,10 @@ impl<H: hash::Writer> hash::Hash<H> for Profile {
env: _,
test: _,
doctest: _,

custom_build: _,
} = *self;
(opt_level, codegen_units, debug, rpath, plugin, dest, harness).hash(into)
(opt_level, codegen_units, debug, rpath, for_host, dest, harness).hash(into)
}
}

Expand Down Expand Up @@ -366,16 +384,17 @@ impl Show for Target {
impl Manifest {
pub fn new(summary: Summary, targets: Vec<Target>,
target_dir: Path, doc_dir: Path,
build: Vec<String>, exclude: Vec<String>,
build: Vec<String>, exclude: Vec<String>, links: Option<String>,
metadata: ManifestMetadata) -> Manifest {
Manifest {
summary: summary,
targets: targets,
target_dir: target_dir,
doc_dir: doc_dir,
build: build,
build: build, // TODO: deprecated, remove
warnings: Vec::new(),
exclude: exclude,
links: links,
metadata: metadata,
}
}
Expand Down Expand Up @@ -416,6 +435,10 @@ impl Manifest {
self.build.as_slice()
}

pub fn get_links(&self) -> Option<&str> {
self.links.as_ref().map(|s| s.as_slice())
}

pub fn add_warning(&mut self, s: String) {
self.warnings.push(s)
}
Expand Down Expand Up @@ -466,6 +489,18 @@ impl Target {
}
}

/// Builds a `Target` corresponding to the `build = "build.rs"` entry.
pub fn custom_build_target(name: &str, src_path: &Path, profile: &Profile,
metadata: Option<Metadata>) -> Target {
Target {
kind: BinTarget,
name: name.to_string(),
src_path: src_path.clone(),
profile: profile.clone(),
metadata: metadata,
}
}

pub fn example_target(name: &str, src_path: &Path, profile: &Profile) -> Target {
Target {
kind: ExampleTarget,
Expand Down
3 changes: 2 additions & 1 deletion src/cargo/ops/cargo_clean.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::io::fs::{mod, PathExtensions};

use core::{MultiShell, PackageSet};
Expand Down Expand Up @@ -49,7 +50,7 @@ pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> {
let pkgs = PackageSet::new([]);
let cx = try!(Context::new("compile", &resolve, &srcs, &pkgs, &mut cfg,
Layout::at(root.get_absolute_target_dir()),
None, &pkg));
None, &pkg, HashMap::new()));

// And finally, clean everything out!
for target in pkg.get_targets().iter() {
Expand Down
89 changes: 58 additions & 31 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use std::collections::HashMap;
use core::registry::PackageRegistry;
use core::{MultiShell, Source, SourceId, PackageSet, Package, Target, PackageId};
use core::resolver;
use ops;
use ops::{mod, BuildOutput};
use sources::{PathSource};
use util::config::{Config, ConfigValue};
use util::{CargoResult, Wrap, config, internal, human, ChainError, profile};
Expand Down Expand Up @@ -129,7 +129,7 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions)
};

let targets = to_build.get_targets().iter().filter(|target| {
match env {
target.get_profile().is_custom_build() || match env {
// doc-all == document everything, so look for doc targets
"doc" | "doc-all" => target.get_profile().get_env() == "doc",
env => target.get_profile().get_env() == env,
Expand All @@ -138,12 +138,12 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions)

let ret = {
let _p = profile::start("compiling");
try!(scrape_target_config(&config, &user_configs));
let lib_overrides = try!(scrape_target_config(&config, &user_configs));

try!(ops::compile_targets(env.as_slice(), targets.as_slice(), to_build,
&PackageSet::new(packages.as_slice()),
&resolve_with_overrides, &sources,
&config))
&config, lib_overrides))
};

return Ok(ret);
Expand Down Expand Up @@ -175,41 +175,68 @@ fn source_ids_from_config(configs: &HashMap<String, config::ConfigValue>,

fn scrape_target_config(config: &Config,
configs: &HashMap<String, config::ConfigValue>)
-> CargoResult<()> {
-> CargoResult<HashMap<String, BuildOutput>> {
let target = match configs.find_equiv("target") {
None => return Ok(()),
None => return Ok(HashMap::new()),
Some(target) => try!(target.table().chain_error(|| {
internal("invalid configuration for the key `target`")
})),
};
let target = match config.target() {
None => target,
Some(triple) => match target.find_equiv(triple) {
None => return Ok(()),
Some(target) => try!(target.table().chain_error(|| {
internal(format!("invalid configuration for the key \
`target.{}`", triple))
})),
},
let triple = config.target().unwrap_or(config.rustc_host()).to_string();
let target = match target.find(&triple) {
None => return Ok(HashMap::new()),
Some(target) => try!(target.table().chain_error(|| {
internal(format!("invalid configuration for the key \
`target.{}`", triple))
})),
};

match target.find_equiv("ar") {
None => {}
Some(ar) => {
config.set_ar(try!(ar.string().chain_error(|| {
internal("invalid configuration for key `ar`")
})).ref0().to_string());
}
}

match target.find_equiv("linker") {
None => {}
Some(linker) => {
config.set_linker(try!(linker.string().chain_error(|| {
internal("invalid configuration for key `ar`")
})).ref0().to_string());
let mut ret = HashMap::new();
for (k, v) in target.iter() {
match k.as_slice() {
"ar" | "linker" => {
let v = try!(v.string().chain_error(|| {
internal(format!("invalid configuration for key `{}`", k))
})).ref0().to_string();
if k.as_slice() == "linker" {
config.set_linker(v);
} else {
config.set_ar(v);
}
}
lib_name => {
let table = try!(v.table().chain_error(|| {
internal(format!("invalid configuration for the key \
`target.{}.{}`", triple, lib_name))
}));
let mut output = BuildOutput {
library_paths: Vec::new(),
library_links: Vec::new(),
metadata: Vec::new(),
};
for (k, v) in table.iter() {
let v = try!(v.string().chain_error(|| {
internal(format!("invalid configuration for the key \
`target.{}.{}.{}`", triple, lib_name,
k))
})).val0();
if k.as_slice() == "rustc-flags" {
let whence = format!("in `target.{}.{}.rustc-flags`",
triple, lib_name);
let whence = whence.as_slice();
let (paths, links) = try!(
BuildOutput::parse_rustc_flags(v.as_slice(), whence)
);
output.library_paths.extend(paths.into_iter());
output.library_links.extend(links.into_iter());
} else {
output.metadata.push((k.to_string(), v.to_string()));
}
}
ret.insert(lib_name.to_string(), output);
}
}
}

Ok(())
Ok(ret)
}
3 changes: 2 additions & 1 deletion src/cargo/ops/cargo_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ pub fn run(manifest_path: &Path,
LibTarget(_) => false,
};
let matches_name = name.as_ref().map_or(true, |n| n.as_slice() == a.get_name());
matches_kind && matches_name && a.get_profile().get_env() == env
matches_kind && matches_name && a.get_profile().get_env() == env &&
!a.get_profile().is_custom_build()
});
let bin = try!(bins.next().require(|| {
human("a bin target must be available for `cargo run`")
Expand Down
3 changes: 2 additions & 1 deletion src/cargo/ops/cargo_rustc/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub struct Compilation {
///
/// This is currently used to drive some entries which are added to the
/// LD_LIBRARY_PATH as appropriate.
// TODO: deprecated, remove
pub native_dirs: HashMap<PackageId, Path>,

/// Root output directory (for the local package's artifacts)
Expand All @@ -43,7 +44,7 @@ impl Compilation {
pub fn new(pkg: &Package) -> Compilation {
Compilation {
libraries: HashMap::new(),
native_dirs: HashMap::new(),
native_dirs: HashMap::new(), // TODO: deprecated, remove
root_output: Path::new("/"),
deps_output: Path::new("/"),
tests: Vec::new(),
Expand Down
Loading

0 comments on commit 6e94e58

Please sign in to comment.