Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "cargo"
version = "0.2.0"
version = "0.3.0"
authors = ["Yehuda Katz <[email protected]>",
"Carl Lerche <[email protected]>",
"Alex Crichton <[email protected]>"]
Expand Down
15 changes: 0 additions & 15 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use util::{CargoResult, human};
pub struct Manifest {
summary: Summary,
targets: Vec<Target>,
target_dir: PathBuf,
doc_dir: PathBuf,
links: Option<String>,
warnings: Vec<String>,
exclude: Vec<String>,
Expand Down Expand Up @@ -51,8 +49,6 @@ pub struct SerializedManifest {
version: String,
dependencies: Vec<SerializedDependency>,
targets: Vec<Target>,
target_dir: String,
doc_dir: String,
}

impl Encodable for Manifest {
Expand All @@ -64,8 +60,6 @@ impl Encodable for Manifest {
SerializedDependency::from_dependency(d)
}).collect(),
targets: self.targets.clone(),
target_dir: self.target_dir.display().to_string(),
doc_dir: self.doc_dir.display().to_string(),
}.encode(s)
}
}
Expand Down Expand Up @@ -181,7 +175,6 @@ impl Encodable for Target {

impl Manifest {
pub fn new(summary: Summary, targets: Vec<Target>,
target_dir: PathBuf, doc_dir: PathBuf,
exclude: Vec<String>,
include: Vec<String>,
links: Option<String>,
Expand All @@ -190,8 +183,6 @@ impl Manifest {
Manifest {
summary: summary,
targets: targets,
target_dir: target_dir,
doc_dir: doc_dir,
warnings: Vec::new(),
exclude: exclude,
include: include,
Expand All @@ -202,14 +193,12 @@ impl Manifest {
}

pub fn dependencies(&self) -> &[Dependency] { self.summary.dependencies() }
pub fn doc_dir(&self) -> &Path { &self.doc_dir }
pub fn exclude(&self) -> &[String] { &self.exclude }
pub fn include(&self) -> &[String] { &self.include }
pub fn metadata(&self) -> &ManifestMetadata { &self.metadata }
pub fn name(&self) -> &str { self.package_id().name() }
pub fn package_id(&self) -> &PackageId { self.summary.package_id() }
pub fn summary(&self) -> &Summary { &self.summary }
pub fn target_dir(&self) -> &Path { &self.target_dir }
pub fn targets(&self) -> &[Target] { &self.targets }
pub fn version(&self) -> &Version { self.package_id().version() }
pub fn warnings(&self) -> &[String] { &self.warnings }
Expand All @@ -225,10 +214,6 @@ impl Manifest {
pub fn set_summary(&mut self, summary: Summary) {
self.summary = summary;
}

pub fn set_target_dir(&mut self, target_dir: PathBuf) {
self.target_dir = target_dir;
}
}

impl Target {
Expand Down
5 changes: 0 additions & 5 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,9 @@ impl Package {
pub fn package_id(&self) -> &PackageId { self.manifest.package_id() }
pub fn root(&self) -> &Path { self.manifest_path.parent().unwrap() }
pub fn summary(&self) -> &Summary { self.manifest.summary() }
pub fn target_dir(&self) -> &Path { self.manifest.target_dir() }
pub fn targets(&self) -> &[Target] { self.manifest().targets() }
pub fn version(&self) -> &Version { self.package_id().version() }

pub fn absolute_target_dir(&self) -> PathBuf {
self.root().join(self.target_dir())
}

pub fn has_custom_build(&self) -> bool {
self.targets().iter().any(|t| t.is_custom_build())
}
Expand Down
8 changes: 4 additions & 4 deletions src/cargo/ops/cargo_clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
opts.config));
try!(src.update());
let root = try!(src.root_package());
let manifest = root.manifest();
let target_dir = opts.config.target_dir(&root);

// If we have a spec, then we need to delete some package,s otherwise, just
// remove the whole target directory and be done with it!
let spec = match opts.spec {
Some(spec) => spec,
None => return rm_rf(manifest.target_dir()),
None => return rm_rf(&target_dir),
};

// Load the lockfile (if one's available), and resolve spec to a pkgid
Expand All @@ -52,14 +52,14 @@ pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
let pkgs = PackageSet::new(&[]);
let profiles = Profiles::default();
let cx = try!(Context::new(&resolve, &srcs, &pkgs, opts.config,
Layout::at(root.absolute_target_dir()),
Layout::at(target_dir),
None, &pkg, BuildConfig::default(),
&profiles));

// And finally, clean everything out!
for target in pkg.targets().iter() {
// TODO: `cargo clean --release`
let layout = Layout::new(&root, opts.target, "debug");
let layout = Layout::new(opts.config, &root, opts.target, "debug");
try!(rm_rf(&layout.fingerprint(&pkg)));
let profiles = [Profile::default_dev(), Profile::default_test()];
for profile in profiles.iter() {
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/ops/cargo_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ pub fn doc(manifest_path: &Path,
}
};

let path = package.absolute_target_dir().join("doc").join(&name)
.join("index.html");
let target_dir = options.compile_opts.config.target_dir(&package);
let path = target_dir.join("doc").join(&name).join("index.html");
if fs::metadata(&path).is_ok() {
open_docs(&path);
}
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/ops/cargo_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ pub fn package(manifest_path: &Path,
}

let filename = format!("package/{}-{}.crate", pkg.name(), pkg.version());
let dst = pkg.absolute_target_dir().join(&filename);
let target_dir = config.target_dir(&pkg);
let dst = target_dir.join(&filename);
if fs::metadata(&dst).is_ok() { return Ok(Some(dst)) }

let mut bomb = Bomb { path: Some(dst.clone()) };
Expand Down Expand Up @@ -174,7 +175,6 @@ fn run_verify(config: &Config, pkg: &Package, tar: &Path)
});
let mut new_manifest = pkg.manifest().clone();
new_manifest.set_summary(new_summary.override_id(new_pkgid));
new_manifest.set_target_dir(dst.join("target"));
let new_pkg = Package::new(new_manifest, &manifest_path, &new_src);

// Now that we've rewritten all our path dependencies, compile it!
Expand Down
6 changes: 4 additions & 2 deletions src/cargo/ops/cargo_rustc/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use std::io;
use std::path::{PathBuf, Path};

use core::Package;
use util::Config;
use util::hex::short_hash;

pub struct Layout {
Expand All @@ -67,8 +68,9 @@ pub struct LayoutProxy<'a> {
}

impl Layout {
pub fn new(pkg: &Package, triple: Option<&str>, dest: &str) -> Layout {
let mut path = pkg.absolute_target_dir();
pub fn new(config: &Config, pkg: &Package, triple: Option<&str>,
dest: &str) -> Layout {
let mut path = config.target_dir(pkg);
// Flexible target specifications often point at filenames, so interpret
// the target triple as a Path and then just use the file stem as the
// component for the directory name.
Expand Down
9 changes: 4 additions & 5 deletions src/cargo/ops/cargo_rustc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ pub fn compile_targets<'a, 'cfg: 'a>(targets: &[(&'a Target, &'a Profile)],
} else {
deps.iter().find(|p| p.package_id() == resolve.root()).unwrap()
};
let host_layout = Layout::new(root, None, &dest);
let host_layout = Layout::new(config, root, None, &dest);
let target_layout = build_config.requested_target.as_ref().map(|target| {
layout::Layout::new(root, Some(&target), &dest)
layout::Layout::new(config, root, Some(&target), &dest)
});

let mut cx = try!(Context::new(resolve, sources, deps, config,
Expand Down Expand Up @@ -535,20 +535,19 @@ fn prepare_rustc(package: &Package, target: &Target, profile: &Profile,
fn rustdoc(package: &Package, target: &Target, profile: &Profile,
cx: &mut Context) -> CargoResult<Work> {
let kind = Kind::Target;
let mut doc_dir = cx.get_package(cx.resolve.root()).absolute_target_dir();
let mut rustdoc = try!(process(CommandType::Rustdoc, package, target, cx));
rustdoc.arg(&root_path(cx, package, target))
.cwd(cx.config.cwd())
.arg("--crate-name").arg(&target.crate_name());

let mut doc_dir = cx.config.target_dir(cx.get_package(cx.resolve.root()));
if let Some(target) = cx.requested_target() {
rustdoc.arg("--target").arg(target);
doc_dir.push(target);
}

doc_dir.push("doc");

rustdoc.arg("-o").arg(&doc_dir);
rustdoc.arg("-o").arg(doc_dir);

match cx.resolve.features(package.package_id()) {
Some(features) => {
Expand Down
44 changes: 38 additions & 6 deletions src/cargo/util/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};

use rustc_serialize::{Encodable,Encoder};
use toml;
use core::MultiShell;
use core::{MultiShell, Package};
use ops;
use util::{CargoResult, ChainError, internal, human};

Expand All @@ -30,6 +30,7 @@ pub struct Config {
cwd: PathBuf,
rustc: PathBuf,
rustdoc: PathBuf,
target_dir: Option<PathBuf>,
}

impl Config {
Expand All @@ -51,13 +52,12 @@ impl Config {
values_loaded: Cell::new(false),
rustc: PathBuf::from("rustc"),
rustdoc: PathBuf::from("rustdoc"),
target_dir: None,
};

cfg.rustc = try!(cfg.get_tool("rustc"));
cfg.rustdoc = try!(cfg.get_tool("rustdoc"));
let (rustc_version, rustc_host) = try!(ops::rustc_version(cfg.rustc()));
cfg.rustc_version = rustc_version;
cfg.rustc_host = rustc_host;
try!(cfg.scrape_tool_config());
try!(cfg.scrape_rustc_version());
try!(cfg.scrape_target_dir_config());

Ok(cfg)
}
Expand Down Expand Up @@ -108,6 +108,12 @@ impl Config {

pub fn cwd(&self) -> &Path { &self.cwd }

pub fn target_dir(&self, pkg: &Package) -> PathBuf {
self.target_dir.clone().unwrap_or_else(|| {
pkg.root().join("target")
})
}

pub fn get(&self, key: &str) -> CargoResult<Option<ConfigValue>> {
let vals = try!(self.values());
let mut parts = key.split('.').enumerate();
Expand Down Expand Up @@ -206,6 +212,32 @@ impl Config {
Ok(())
}

fn scrape_tool_config(&mut self) -> CargoResult<()> {
self.rustc = try!(self.get_tool("rustc"));
self.rustdoc = try!(self.get_tool("rustdoc"));
Ok(())
}

fn scrape_rustc_version(&mut self) -> CargoResult<()> {
let (rustc_version, rustc_host) = try!(ops::rustc_version(&self.rustc));
self.rustc_version = rustc_version;
self.rustc_host = rustc_host;
Ok(())
}

fn scrape_target_dir_config(&mut self) -> CargoResult<()> {
if let Some((dir, dir2)) = try!(self.get_string("build.target-dir")) {
let mut path = PathBuf::from(dir2);
path.pop();
path.pop();
path.push(dir);
self.target_dir = Some(path);
} else if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
self.target_dir = Some(self.cwd.join(dir));
}
Ok(())
}

fn get_tool(&self, tool: &str) -> CargoResult<PathBuf> {
let var = format!("build.{}", tool);
if let Some((tool, path)) = try!(self.get_string(&var)) {
Expand Down
2 changes: 0 additions & 2 deletions src/cargo/util/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,6 @@ impl TomlManifest {
let profiles = build_profiles(&self.profile);
let mut manifest = Manifest::new(summary,
targets,
layout.root.join("target"),
layout.root.join("doc"),
exclude,
include,
project.links.clone(),
Expand Down
9 changes: 6 additions & 3 deletions src/doc/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ proxy = "..." # HTTP proxy to use for HTTP requests (defaults to none)
timeout = 60000 # Timeout for each HTTP request, in milliseconds

[build]
jobs = 1 # number of jobs to run by default (default to # cpus)
rustc = "rustc" # path to the compiler to execute
rustdoc = "rustdoc" # path to the doc generator to execute
jobs = 1 # number of jobs to run by default (default to # cpus)
rustc = "rustc" # path to the compiler to execute
rustdoc = "rustdoc" # path to the doc generator to execute
target-dir = "target" # path of where to place all generated artifacts
```

# Environment Variables
Expand All @@ -92,3 +93,5 @@ Cargo recognizes a few global environment variables to configure how it runs:
compiler instead.
* `RUSTDOC` - Instead of running `rustdoc`, Cargo will execute this specified
`rustdoc` instance instead.
* `CARGO_TARGET_DIR` - Location of where to place all generated artifacts,
relative to the current working directory.
42 changes: 42 additions & 0 deletions tests/test_cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1821,3 +1821,45 @@ test!(ignore_dotfile {
assert_that(p.cargo("build"),
execs().with_status(0));
});

test!(custom_target_dir {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
"#)
.file("src/main.rs", "fn main() {}");
p.build();

let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);

assert_that(p.cargo("build").env("CARGO_TARGET_DIR", "foo/target"),
execs().with_status(0));
assert_that(&p.root().join("foo/target/debug").join(&exe_name),
existing_file());
assert_that(&p.root().join("target/debug").join(&exe_name),
is_not(existing_file()));

assert_that(p.cargo("build"),
execs().with_status(0));
assert_that(&p.root().join("foo/target/debug").join(&exe_name),
existing_file());
assert_that(&p.root().join("target/debug").join(&exe_name),
existing_file());

fs::create_dir(p.root().join(".cargo")).unwrap();
File::create(p.root().join(".cargo/config")).unwrap().write_all(br#"
[build]
target-dir = "bar/target"
"#).unwrap();
assert_that(p.cargo("build").env("CARGO_TARGET_DIR", "foo/target"),
execs().with_status(0));
assert_that(&p.root().join("bar/target/debug").join(&exe_name),
existing_file());
assert_that(&p.root().join("foo/target/debug").join(&exe_name),
existing_file());
assert_that(&p.root().join("target/debug").join(&exe_name),
existing_file());
});