mirror of https://github.com/rust-lang/cargo
Allow multiple and non-default crate_types
Note that at present there is no good error handling for fat-fingering the crate type. This is a TODO.
This commit is contained in:
parent
35e21c7600
commit
f9601cd2f6
|
@ -1,3 +1,4 @@
|
|||
use std::result;
|
||||
use std::fmt;
|
||||
use std::fmt::{Show,Formatter};
|
||||
use semver::Version;
|
||||
|
@ -9,6 +10,7 @@ use core::{
|
|||
Summary
|
||||
};
|
||||
use core::dependency::SerializedDependency;
|
||||
use util::{CargoResult,simple_human};
|
||||
|
||||
#[deriving(PartialEq,Clone)]
|
||||
pub struct Manifest {
|
||||
|
@ -48,9 +50,42 @@ impl<E, S: Encoder<E>> Encodable<S, E> for 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
|
||||
}
|
||||
|
||||
|
@ -63,7 +98,7 @@ pub struct Target {
|
|||
|
||||
#[deriving(Encodable)]
|
||||
pub struct SerializedTarget {
|
||||
kind: &'static str,
|
||||
kind: Vec<&'static str>,
|
||||
name: String,
|
||||
path: String
|
||||
}
|
||||
|
@ -71,8 +106,8 @@ pub struct SerializedTarget {
|
|||
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 {
|
||||
|
@ -138,9 +173,9 @@ impl Manifest {
|
|||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
@ -160,7 +195,7 @@ impl Target {
|
|||
|
||||
pub fn is_lib(&self) -> bool {
|
||||
match self.kind {
|
||||
LibTarget => true,
|
||||
LibTarget(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -172,10 +207,12 @@ impl Target {
|
|||
}
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,23 +52,29 @@ fn mk_target(target: &Path) -> CargoResult<()> {
|
|||
}
|
||||
|
||||
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")
|
||||
|
@ -77,11 +83,11 @@ fn prepare_rustc(root: &Path, target: &Target, dest: &Path, deps: &Path) -> Proc
|
|||
.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());
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ impl Show for GitSource {
|
|||
|
||||
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));
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::collections::HashMap;
|
|||
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};
|
||||
|
||||
|
@ -159,6 +160,7 @@ impl TomlManifest {
|
|||
#[deriving(Decodable,Encodable,PartialEq,Clone,Show)]
|
||||
struct TomlTarget {
|
||||
name: String,
|
||||
crate_type: Option<Vec<String>>,
|
||||
path: Option<String>
|
||||
}
|
||||
|
||||
|
@ -168,7 +170,8 @@ fn normalize(lib: Option<&[TomlLibTarget]>, bin: Option<&[TomlBinTarget]>) -> Ve
|
|||
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) {
|
||||
|
|
Loading…
Reference in New Issue