Skip to content

Commit

Permalink
feat: Stablize CARGO_RUSTC_CURRENT_DIR
Browse files Browse the repository at this point in the history
This provides what cargo sets as the `current_dir` for the `rustc`
process.
While `std::file!` is unspecified in what it is relative to,
it is relatively safe, it is generally relative to `rustc`s
`current_dir`.

This can be useful for snapshot testing.
For example, `snapbox` has been using this macro on nightly since
assert-rs/snapbox#247, falling back to finding a parent of
`CARGO_MANIFEST_DIR`, if present.
This has been in use in Cargo since rust-lang#13441.

This was added in rust-lang#12996.
Relevant points discussed in that issue:
- This diverged from the original proposal from the Cargo team of having
  a `CARGO_WORKSPACE_DIR` that is the "workspace" of the package being
  built (ie registry packages would map to `CARGO_MANIFEST_DIR`).
  In looking at the `std::file!` use case, `CARGO_MANIFEST_DIR`, no
  matter how we defined it, would only sort of work because no sane
  definition of that maps to `rustc`'s `current_dir`.a
  This instead focuses on the mechanism currently being used.
- Using "current dir" in the name is meant to be consistent with
  `std::env::current_dir`.
- I can go either way on `CARGO_RUSTC` vs `RUSTC`.  Existing related
  variables:
  - `RUSTC`
  - `RUSTC_WRAPPER`
  - `RUSTC_WORKSPACE_WRAPPER`
  - `RUSTFLAGS` (no `C`)
  - `CARGO_CACHE_RUSTC_INFO`

Note that rust-lang#3946 was overly broad and covered many use cases.
One of those was for packages to look up information on their
dependents.
Issue rust-lang#13484 is being left open to track that.

Fixes rust-lang#3946
  • Loading branch information
epage committed Mar 26, 2024
1 parent 84dc5dc commit d60e025
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 48 deletions.
18 changes: 8 additions & 10 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,16 +696,14 @@ fn prepare_rustc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResult
let tmp = build_runner.files().layout(unit.kind).prepare_tmp()?;
base.env("CARGO_TARGET_TMPDIR", tmp.display().to_string());
}
if build_runner.bcx.gctx.nightly_features_allowed {
// This must come after `build_base_args` (which calls `add_path_args`) so that the `cwd`
// is set correctly.
base.env(
"CARGO_RUSTC_CURRENT_DIR",
base.get_cwd()
.map(|c| c.display().to_string())
.unwrap_or(String::new()),
);
}
// This must come after `build_base_args` (which calls `add_path_args`) so that the `cwd`
// is set correctly.
base.env(
"CARGO_RUSTC_CURRENT_DIR",
base.get_cwd()
.map(|c| c.display().to_string())
.unwrap_or(String::new()),
);

Ok(base)
}
Expand Down
2 changes: 1 addition & 1 deletion src/doc/src/reference/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ corresponding environment variable is set to the empty string, `""`.
where integration tests or benchmarks are free to put any data needed by
the tests/benches. Cargo initially creates this directory but doesn't
manage its content in any way, this is the responsibility of the test code.
* `CARGO_RUSTC_CURRENT_DIR` --- This is a path that `rustc` is invoked from **(nightly only)**.
* `CARGO_RUSTC_CURRENT_DIR` --- This is a path that `rustc` is invoked from

[Cargo target]: cargo-targets.md
[binaries]: cargo-targets.md#binaries
Expand Down
41 changes: 4 additions & 37 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1748,30 +1748,22 @@ fn crate_env_vars() {
};

println!("build");
p.cargo("build -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
p.cargo("build -v").run();

println!("bin");
p.process(&p.bin("foo-bar"))
.with_stdout("0-5-1 @ alpha.1 in [CWD]")
.run();

println!("example");
p.cargo("run --example ex-env-vars -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
p.cargo("run --example ex-env-vars -v").run();

println!("test");
p.cargo("test -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
p.cargo("test -v").run();

if is_nightly() {
println!("bench");
p.cargo("bench -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
p.cargo("bench -v").run();
}
}

Expand Down Expand Up @@ -1857,11 +1849,9 @@ fn cargo_rustc_current_dir_foreign_workspace_dep() {

// Verify it works from a different workspace
foo.cargo("test -p baz")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.with_stdout_contains("running 1 test\ntest baz_env ... ok")
.run();
foo.cargo("test -p baz_member")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.with_stdout_contains("running 1 test\ntest baz_member_env ... ok")
.run();
}
Expand Down Expand Up @@ -1906,33 +1896,10 @@ fn cargo_rustc_current_dir_non_local_dep() {
.build();

p.cargo("test -p bar")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.with_stdout_contains("running 1 test\ntest bar_env ... ok")
.run();
}

#[cargo_test]
fn cargo_rustc_current_dir_is_not_stable() {
if is_nightly() {
return;
}
let p = project()
.file(
"tests/env.rs",
r#"
use std::path::Path;
#[test]
fn env() {
assert_eq!(option_env!("CARGO_RUSTC_CURRENT_DIR"), None);
}
"#,
)
.build();

p.cargo("test").run();
}

#[cargo_test]
fn crate_authors_env_vars() {
let p = project()
Expand Down

0 comments on commit d60e025

Please sign in to comment.