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 Oct 6, 2018
1 parent 96a2c7d commit 139e200
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/cargo/util/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,17 @@ 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");
}
match self.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!("CARGO_TARGET_DIR_PREFIX must describe 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
58 changes: 58 additions & 0 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3602,6 +3602,64 @@ fn dotdir_root() {
assert_that(p.cargo("build"), execs().with_status(0));
}

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

let p = project("foo")
.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);

assert_that(
p.cargo("build")
.env("CARGO_TARGET_DIR_PREFIX", tmpdir.clone()),
execs().with_status(0),
);
assert_that(
tmpdir
.clone()
.join(root_suffix)
.join("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(
tmpdir
.clone()
.join(root_suffix)
.join("target/debug")
.join(&exe_name),
existing_file(),
);
assert_that(
&p.root().join("target/debug").join(&exe_name),
existing_file(),
);
}

#[test]
fn custom_target_dir_env() {
let p = project("foo")
Expand Down
1 change: 1 addition & 0 deletions tests/testsuite/cargotest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,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
return p;
Expand Down

0 comments on commit 139e200

Please sign in to comment.