Skip to content

Commit

Permalink
Add support for CARGO_TARGET_DIR_PREFIX
Browse files Browse the repository at this point in the history
This change adds support for a new environment variable,
CARGO_TARGET_DIR_PREFIX, to cargo. This variable, when set, is treated
as a prefix to the target directory.
This change addresses rust-lang#5544.

TODO: Definitely not finished. This patch needs more tests and may need
      additional config.toml support (?).
  • Loading branch information
d-e-s-o committed May 20, 2018
1 parent a1a4ad3 commit 8282fa2
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/cargo/util/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use core::{CliUnstable, Shell, SourceId, Workspace};
use ops;
use url::Url;
use util::errors::{internal, CargoResult, CargoResultExt};
use util::important_paths::find_root_manifest_for_wd;
use util::paths;
use util::toml as cargo_toml;
use util::Filesystem;
Expand Down Expand Up @@ -290,6 +291,25 @@ impl Config {
Ok(Some(dir.clone()))
} else if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
Ok(Some(Filesystem::new(self.cwd.join(dir))))
} else if let Some(dir) = env::var_os("CARGO_TARGET_DIR_PREFIX") {
let prefix = Path::new(&dir);
if !prefix.is_absolute() {
bail!("CARGO_TARGET_DIR_PREFIX must describe an absolute path");
}
// We need to take into consideration that `self.cwd` may
// point to a directory other than the one containing
// Cargo.toml. We definitely want to stay relative to the
// latter.
let mut cwd = find_root_manifest_for_wd(&self.cwd)?;
let result = cwd.pop();
assert!(result);

match cwd.strip_prefix("/") {
Ok(cwd) => Ok(Some(Filesystem::new(prefix.join(&cwd).join("target")))),
// FIXME: This logic is probably not safe on Windows. Not sure how
// to make a path relative there.
Err(_) => bail!("Current directory must be an absolute path"),
}
} else if let Some(val) = self.get_path("build.target-dir")? {
let val = self.cwd.join(val.val);
Ok(Some(Filesystem::new(val)))
Expand Down
4 changes: 4 additions & 0 deletions src/doc/src/reference/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ system:
checkouts of crates. By default these are stored under `$HOME/.cargo`, but
this variable overrides the location of this directory. Once a crate is cached
it is not removed by the clean command.
* `CARGO_TARGET_DIR_PREFIX` — Prefix to the location where to place all
generated artifacts. The current working directory will be appended to this
prefix to form the final path for generated artifacts. Note that
`CARGO_TARGET_DIR`, if set, takes precedence over this variable.
* `CARGO_TARGET_DIR` — Location of where to place all generated artifacts,
relative to the current working directory.
* `RUSTC` — Instead of running `rustc`, Cargo will execute this specified
Expand Down
57 changes: 57 additions & 0 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3006,6 +3006,63 @@ fn explicit_color_config_is_propagated_to_rustc() {
).run();
}

#[test]
fn custom_target_dir_prefix() {
fn test(cwd: &str) {
let tmpdir = tempfile::Builder::new()
.tempdir()
.unwrap()
.path()
.to_path_buf();

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

let root = p.root();
let root_suffix = root.strip_prefix("/").unwrap();
let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);

p.cargo("build")
.env("CARGO_TARGET_DIR_PREFIX", tmpdir.clone())
.cwd(p.root().join(cwd))
.run();

assert!(
tmpdir
.clone()
.join(root_suffix)
.join("target/debug")
.join(&exe_name)
.is_file()
);
assert!(!&p.root().join("target/debug").join(&exe_name).is_file());

p.cargo("build").run();
assert!(
tmpdir
.clone()
.join(root_suffix)
.join("target/debug")
.join(&exe_name)
.is_file()
);
assert!(&p.root().join("target/debug").join(&exe_name).is_file())
};

test(".");
test("src");
}

#[test]
fn compiler_json_error_format() {
let p = project()
Expand Down
1 change: 1 addition & 0 deletions tests/testsuite/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
.env_remove("GIT_AUTHOR_EMAIL")
.env_remove("GIT_COMMITTER_NAME")
.env_remove("GIT_COMMITTER_EMAIL")
.env_remove("CARGO_TARGET_DIR_PREFIX") // we assume no prefix
.env_remove("CARGO_TARGET_DIR") // we assume 'target'
.env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows
p
Expand Down

0 comments on commit 8282fa2

Please sign in to comment.