+use std::result;
use std::fmt;
use std::fmt::{Show,Formatter};
use semver::Version;
Summary
};
use core::dependency::SerializedDependency;
+use util::{CargoResult,simple_human};
#[deriving(PartialEq,Clone)]
pub struct Manifest {
}
}
+#[deriving(Show,Clone,PartialEq,Encodable)]
+pub enum LibKind {
+ Lib,
+ Rlib,
+ Dylib,
+ StaticLib
+}
+
+impl LibKind {
+ pub fn from_str(string: &str) -> CargoResult<LibKind> {
+ match string {
+ "lib" => Ok(Lib),
+ "rlib" => Ok(Rlib),
+ "dylib" => Ok(Dylib),
+ "staticlib" => Ok(StaticLib),
+ _ => Err(simple_human(format!("{} was not one of lib|rlib|dylib|staticlib", string)))
+ }
+ }
+
+ pub fn from_strs<S: Str>(strings: Vec<S>) -> CargoResult<Vec<LibKind>> {
+ result::collect(strings.iter().map(|s| LibKind::from_str(s.as_slice())))
+ }
+
+ pub fn crate_type(&self) -> &'static str {
+ match *self {
+ Lib => "lib",
+ Rlib => "rlib",
+ Dylib => "dylib",
+ StaticLib => "staticlib"
+ }
+ }
+}
+
#[deriving(Show,Clone,PartialEq,Encodable)]
pub enum TargetKind {
- LibTarget,
+ LibTarget(Vec<LibKind>),
BinTarget
}
#[deriving(Encodable)]
pub struct SerializedTarget {
- kind: &'static str,
+ kind: Vec<&'static str>,
name: String,
path: String
}
impl<E, S: Encoder<E>> Encodable<S, E> for Target {
fn encode(&self, s: &mut S) -> Result<(), E> {
let kind = match self.kind {
- LibTarget => "lib",
- BinTarget => "bin"
+ LibTarget(ref kinds) => kinds.iter().map(|k| k.crate_type()).collect(),
+ BinTarget => vec!("bin")
};
SerializedTarget {
}
impl Target {
- pub fn lib_target(name: &str, path: &Path) -> Target {
+ pub fn lib_target(name: &str, crate_targets: Vec<LibKind>, path: &Path) -> Target {
Target {
- kind: LibTarget,
+ kind: LibTarget(crate_targets),
name: name.to_str(),
path: path.clone()
}
pub fn is_lib(&self) -> bool {
match self.kind {
- LibTarget => true,
+ LibTarget(_) => true,
_ => false
}
}
}
}
- pub fn rustc_crate_type(&self) -> &'static str {
+ pub fn rustc_crate_types(&self) -> Vec<&'static str> {
match self.kind {
- LibTarget => "lib",
- BinTarget => "bin"
+ LibTarget(ref kinds) => {
+ kinds.iter().map(|kind| kind.crate_type()).collect()
+ },
+ BinTarget => vec!("bin")
}
}
}
}
fn rustc(root: &Path, target: &Target, dest: &Path, deps: &Path, verbose: bool) -> CargoResult<()> {
- log!(5, "root={}; target={}; dest={}; deps={}; verbose={}", root.display(), target, dest.display(), deps.display(), verbose);
- let rustc = prepare_rustc(root, target, dest, deps);
+ let crate_types = target.rustc_crate_types();
- try!((if verbose {
- rustc.exec()
- } else {
- rustc.exec_with_output().and(Ok(()))
- }).map_err(|e| rustc_to_cargo_err(rustc.get_args().as_slice(), root, e)));
+ for crate_type in crate_types.iter() {
+ log!(5, "root={}; target={}; crate_type={}; dest={}; deps={}; verbose={}",
+ root.display(), target, crate_type, dest.display(), deps.display(), verbose);
+
+ let rustc = prepare_rustc(root, target, *crate_type, dest, deps);
+
+ try!((if verbose {
+ rustc.exec()
+ } else {
+ rustc.exec_with_output().and(Ok(()))
+ }).map_err(|e| rustc_to_cargo_err(rustc.get_args().as_slice(), root, e)));
+ }
Ok(())
}
-fn prepare_rustc(root: &Path, target: &Target, dest: &Path, deps: &Path) -> ProcessBuilder {
+fn prepare_rustc(root: &Path, target: &Target, crate_type: &'static str, dest: &Path, deps: &Path) -> ProcessBuilder {
let mut args = Vec::new();
- build_base_args(&mut args, target, dest);
+ build_base_args(&mut args, target, crate_type, dest);
build_deps_args(&mut args, deps);
util::process("rustc")
.env("RUST_LOG", None) // rustc is way too noisy
}
-fn build_base_args(into: &mut Args, target: &Target, dest: &Path) {
+fn build_base_args(into: &mut Args, target: &Target, crate_type: &'static str, dest: &Path) {
// TODO: Handle errors in converting paths into args
into.push(target.get_path().display().to_str());
into.push("--crate-type".to_str());
- into.push(target.rustc_crate_type().to_str());
+ into.push(crate_type.to_str());
into.push("--out-dir".to_str());
into.push(dest.display().to_str());
}
impl Source for GitSource {
fn update(&self) -> CargoResult<()> {
+ println!("Updating git repository `{}`", self.remote.get_url());
log!(5, "updating git source `{}`", self.remote);
let repo = try!(self.remote.checkout(&self.db_path));
try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path));
use serialize::Decodable;
use core::source::{SourceId,GitKind};
+use core::manifest::{LibKind,Lib};
use core::{Summary,Manifest,Target,Dependency,PackageId};
use util::{CargoResult,Require,simple_human,toml_error};
#[deriving(Decodable,Encodable,PartialEq,Clone,Show)]
struct TomlTarget {
name: String,
+ crate_type: Option<Vec<String>>,
path: Option<String>
}
fn lib_targets(dst: &mut Vec<Target>, libs: &[TomlLibTarget]) {
let l = &libs[0];
let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name));
- dst.push(Target::lib_target(l.name.as_slice(), &Path::new(path)));
+ let crate_types = l.crate_type.clone().and_then(|kinds| LibKind::from_strs(kinds).ok()).unwrap_or_else(|| vec!(Lib));
+ dst.push(Target::lib_target(l.name.as_slice(), crate_types, &Path::new(path)));
}
fn bin_targets(dst: &mut Vec<Target>, bins: &[TomlBinTarget], default: |&TomlBinTarget| -> String) {