mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Auto merge of #12996 - epage:current_dir, r=weihanglo
feat: Add `CARGO_RUSTC_CURRENT_DIR` (unstable) ### What does this PR try to resolve? This is an alternative to #12158's `CARGO_WORKSPACE_DIR` that was implementing the solution to #3946 that previously discussed in the cargo team meeting. `CARGO_WORKSPACE_DIR` is a bit awkward to document / describe because its the effective workspace directory of the thing being built. If the thing being built doesn't have a workspace, it falls back to `CARGO_MANIFEST_DIR`. It would also be hard to take into account what the `CARGO_WORKSPACE_DIR` would be for path dependencies into foreign workspaces *and* it wouldn't solve the problem the user is having. What the user really wants is the CWD of rustc when it is invoked. This is much simpler to describe and is accurate when using a path dependency to a foreign package. Because the CWD is a much simpler mechanism to talk about, I figured we could diverge from our prior consensus and make it always present, rather than limiting it to tests. ### How should we test and review this PR? The preparatory refactor commits have explanation for why they were to help ### Additional information Remaining work for #3946: get this stabilized
This commit is contained in:
commit
9b13310ca5
@ -662,6 +662,15 @@ fn prepare_rustc(cx: &Context<'_, '_>, unit: &Unit) -> CargoResult<ProcessBuilde
|
||||
let mut base = cx
|
||||
.compilation
|
||||
.rustc_process(unit, is_primary, is_workspace)?;
|
||||
build_base_args(cx, &mut base, unit)?;
|
||||
|
||||
base.inherit_jobserver(&cx.jobserver);
|
||||
build_deps_args(&mut base, cx, unit)?;
|
||||
add_cap_lints(cx.bcx, unit, &mut base);
|
||||
base.args(cx.bcx.rustflags_args(unit));
|
||||
if cx.bcx.config.cli_unstable().binary_dep_depinfo {
|
||||
base.arg("-Z").arg("binary-dep-depinfo");
|
||||
}
|
||||
|
||||
if is_primary {
|
||||
base.env("CARGO_PRIMARY_PACKAGE", "1");
|
||||
@ -671,15 +680,17 @@ fn prepare_rustc(cx: &Context<'_, '_>, unit: &Unit) -> CargoResult<ProcessBuilde
|
||||
let tmp = cx.files().layout(unit.kind).prepare_tmp()?;
|
||||
base.env("CARGO_TARGET_TMPDIR", tmp.display().to_string());
|
||||
}
|
||||
|
||||
base.inherit_jobserver(&cx.jobserver);
|
||||
build_base_args(cx, &mut base, unit)?;
|
||||
build_deps_args(&mut base, cx, unit)?;
|
||||
add_cap_lints(cx.bcx, unit, &mut base);
|
||||
base.args(cx.bcx.rustflags_args(unit));
|
||||
if cx.bcx.config.cli_unstable().binary_dep_depinfo {
|
||||
base.arg("-Z").arg("binary-dep-depinfo");
|
||||
if cx.bcx.config.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()),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(base)
|
||||
}
|
||||
|
||||
|
@ -265,6 +265,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 target]: cargo-targets.md
|
||||
[binaries]: cargo-targets.md#binaries
|
||||
|
@ -1545,6 +1545,11 @@ fn crate_env_vars() {
|
||||
|
||||
// Verify CARGO_TARGET_TMPDIR isn't set for bins
|
||||
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
|
||||
|
||||
// Verify CARGO_RUSTC_CURRENT_DIR is set for examples
|
||||
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
@ -1581,14 +1586,26 @@ fn crate_env_vars() {
|
||||
// Check that CARGO_TARGET_TMPDIR isn't set for lib code
|
||||
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
|
||||
env::var("CARGO_TARGET_TMPDIR").unwrap_err();
|
||||
|
||||
// Verify CARGO_RUSTC_CURRENT_DIR is set for examples
|
||||
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn env() {
|
||||
fn unit_env_cargo_target_tmpdir() {
|
||||
// Check that CARGO_TARGET_TMPDIR isn't set for unit tests
|
||||
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
|
||||
env::var("CARGO_TARGET_TMPDIR").unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_env_cargo_rustc_current_dir() {
|
||||
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
@ -1605,6 +1622,11 @@ fn crate_env_vars() {
|
||||
|
||||
// Verify CARGO_TARGET_TMPDIR isn't set for examples
|
||||
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
|
||||
|
||||
// Verify CARGO_RUSTC_CURRENT_DIR is set for examples
|
||||
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
@ -1612,9 +1634,16 @@ fn crate_env_vars() {
|
||||
"tests/env.rs",
|
||||
r#"
|
||||
#[test]
|
||||
fn env() {
|
||||
fn integration_env_cargo_target_tmpdir() {
|
||||
foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integration_env_cargo_rustc_current_dir() {
|
||||
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
@ -1627,9 +1656,16 @@ fn crate_env_vars() {
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn env(_: &mut Bencher) {
|
||||
fn bench_env_cargo_target_tmpdir(_: &mut Bencher) {
|
||||
foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bench_env_cargo_rustc_current_dir() {
|
||||
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.build()
|
||||
@ -1638,7 +1674,9 @@ fn crate_env_vars() {
|
||||
};
|
||||
|
||||
println!("build");
|
||||
p.cargo("build -v").run();
|
||||
p.cargo("build -v")
|
||||
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
|
||||
.run();
|
||||
|
||||
println!("bin");
|
||||
p.process(&p.bin("foo-bar"))
|
||||
@ -1646,17 +1684,177 @@ fn crate_env_vars() {
|
||||
.run();
|
||||
|
||||
println!("example");
|
||||
p.cargo("run --example ex-env-vars -v").run();
|
||||
p.cargo("run --example ex-env-vars -v")
|
||||
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
|
||||
.run();
|
||||
|
||||
println!("test");
|
||||
p.cargo("test -v").run();
|
||||
p.cargo("test -v")
|
||||
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
|
||||
.run();
|
||||
|
||||
if is_nightly() {
|
||||
println!("bench");
|
||||
p.cargo("bench -v").run();
|
||||
p.cargo("bench -v")
|
||||
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
|
||||
.run();
|
||||
}
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn cargo_rustc_current_dir_foreign_workspace_dep() {
|
||||
let foo = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
baz.path = "../baz"
|
||||
baz_member.path = "../baz/baz_member"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
let _baz = project()
|
||||
.at("baz")
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["baz_member"]
|
||||
|
||||
[package]
|
||||
name = "baz"
|
||||
version = "0.1.0"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"tests/env.rs",
|
||||
r#"
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn baz_env() {
|
||||
let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
|
||||
let current_dir = std::env::current_dir().expect("current_dir");
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR");
|
||||
let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
|
||||
assert_eq!(workspace_dir, manifest_dir);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"baz_member/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "baz_member"
|
||||
version = "0.1.0"
|
||||
authors = []
|
||||
"#,
|
||||
)
|
||||
.file("baz_member/src/lib.rs", "")
|
||||
.file(
|
||||
"baz_member/tests/env.rs",
|
||||
r#"
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn baz_member_env() {
|
||||
let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.build();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn cargo_rustc_current_dir_non_local_dep() {
|
||||
Package::new("bar", "0.1.0")
|
||||
.file(
|
||||
"tests/bar_env.rs",
|
||||
r#"
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn bar_env() {
|
||||
let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
|
||||
let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
|
||||
let current_dir = std::env::current_dir().expect("current_dir");
|
||||
let file_path = workspace_dir.join(file!());
|
||||
assert!(file_path.exists(), "{}", file_path.display());
|
||||
let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR");
|
||||
let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
|
||||
assert_eq!(workspace_dir, manifest_dir);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.publish();
|
||||
|
||||
let p = project()
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
|
||||
[dependencies]
|
||||
bar = "0.1.0"
|
||||
"#,
|
||||
)
|
||||
.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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user