Auto merge of #14404 - Ifropc:cargo_manifest_path, r=weihanglo

feat: add CARGO_MANIFEST_PATH env variable

Adds `CARGO_MANIFEST_PATH` variable as part of https://github.com/rust-lang/cargo/issues/12207
Context: `CARGO_MANIFEST_DIR` is not very useful, because there is no `Cargo.toml` file when running a cargo script. In cases when multiple scripts are stored in the same folder, we can't tell which script exactly is being run using `CARGO_MANIFEST_DIR`
This commit is contained in:
bors 2024-09-26 13:01:01 +00:00
commit 7cbdcf0b21
6 changed files with 50 additions and 8 deletions

View file

@ -356,6 +356,7 @@ impl<'gctx> Compilation<'gctx> {
// in BuildContext::target_metadata()
let rust_version = pkg.rust_version().as_ref().map(ToString::to_string);
cmd.env("CARGO_MANIFEST_DIR", pkg.root())
.env("CARGO_MANIFEST_PATH", pkg.manifest_path())
.env("CARGO_PKG_VERSION_MAJOR", &pkg.version().major.to_string())
.env("CARGO_PKG_VERSION_MINOR", &pkg.version().minor.to_string())
.env("CARGO_PKG_VERSION_PATCH", &pkg.version().patch.to_string())

View file

@ -279,6 +279,7 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
let debug = unit.profile.debuginfo.is_turned_on();
cmd.env("OUT_DIR", &script_out_dir)
.env("CARGO_MANIFEST_DIR", unit.pkg.root())
.env("CARGO_MANIFEST_PATH", unit.pkg.manifest_path())
.env("NUM_JOBS", &bcx.jobs().to_string())
.env("TARGET", bcx.target_data.short_name(&unit.kind))
.env("DEBUG", debug.to_string())

View file

@ -226,6 +226,7 @@ corresponding environment variable is set to the empty string, `""`.
* `CARGO` --- Path to the `cargo` binary performing the build.
* `CARGO_MANIFEST_DIR` --- The directory containing the manifest of your package.
* `CARGO_MANIFEST_PATH` --- The path to the manifest of your package.
* `CARGO_PKG_VERSION` --- The full version of your package.
* `CARGO_PKG_VERSION_MAJOR` --- The major version of your package.
* `CARGO_PKG_VERSION_MINOR` --- The minor version of your package.
@ -320,6 +321,7 @@ let out_dir = env::var("OUT_DIR").unwrap();
* `CARGO_MANIFEST_DIR` --- The directory containing the manifest for the package
being built (the package containing the build script). Also note that this is
the value of the current working directory of the build script when it starts.
* `CARGO_MANIFEST_PATH` --- The path to the manifest of your package.
* `CARGO_MANIFEST_LINKS` --- the manifest `links` value.
* `CARGO_MAKEFLAGS` --- Contains parameters needed for Cargo's [jobserver]
implementation to parallelize subprocesses. Rustc or cargo invocations from

View file

@ -1466,7 +1466,7 @@ This will not affect any hard-coded paths in the source code, such as in strings
Values in a non-empty array would be joined into a comma-separated list.
If the build script introduces absolute paths to built artifacts (such as by invoking a compiler),
the user may request them to be sanitized in different types of artifacts.
Common paths requiring sanitization include `OUT_DIR` and `CARGO_MANIFEST_DIR`,
Common paths requiring sanitization include `OUT_DIR`, `CARGO_MANIFEST_DIR` and `CARGO_MANIFEST_PATH`,
plus any other introduced by the build script, such as include directories.
## gc

View file

@ -1623,6 +1623,7 @@ fn crate_env_vars() {
static VERSION_PRE: &'static str = env!("CARGO_PKG_VERSION_PRE");
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static CARGO_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR");
static CARGO_MANIFEST_PATH: &'static str = env!("CARGO_MANIFEST_PATH");
static PKG_NAME: &'static str = env!("CARGO_PKG_NAME");
static HOMEPAGE: &'static str = env!("CARGO_PKG_HOMEPAGE");
static REPOSITORY: &'static str = env!("CARGO_PKG_REPOSITORY");
@ -1636,9 +1637,9 @@ fn crate_env_vars() {
fn main() {
let s = format!("{}-{}-{} @ {} in {}", VERSION_MAJOR,
let s = format!("{}-{}-{} @ {} in {} file {}", VERSION_MAJOR,
VERSION_MINOR, VERSION_PATCH, VERSION_PRE,
CARGO_MANIFEST_DIR);
CARGO_MANIFEST_DIR, CARGO_MANIFEST_PATH);
assert_eq!(s, foo::version());
println!("{}", s);
assert_eq!("foo", PKG_NAME);
@ -1672,12 +1673,13 @@ fn crate_env_vars() {
use std::path::PathBuf;
pub fn version() -> String {
format!("{}-{}-{} @ {} in {}",
format!("{}-{}-{} @ {} in {} file {}",
env!("CARGO_PKG_VERSION_MAJOR"),
env!("CARGO_PKG_VERSION_MINOR"),
env!("CARGO_PKG_VERSION_PATCH"),
env!("CARGO_PKG_VERSION_PRE"),
env!("CARGO_MANIFEST_DIR"))
env!("CARGO_MANIFEST_DIR"),
env!("CARGO_MANIFEST_PATH"))
}
pub fn check_no_int_test_env() {
@ -1793,7 +1795,7 @@ fn crate_env_vars() {
println!("bin");
p.process(&p.bin("foo-bar"))
.with_stdout_data(str![[r#"
0-5-1 @ alpha.1 in [ROOT]/foo
0-5-1 @ alpha.1 in [ROOT]/foo file [ROOT]/foo/Cargo.toml
"#]])
.run();
@ -1861,12 +1863,15 @@ fn cargo_rustc_current_dir_foreign_workspace_dep() {
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 manifest_path = Path::new(option_env!("CARGO_MANIFEST_PATH").expect("CARGO_MANIFEST_PATH"));
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_path = std::fs::canonicalize(current_dir.join(manifest_dir.clone()).join("Cargo.toml")).expect("CARGO_MANIFEST_PATH");
let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
assert_eq!(workspace_dir, manifest_dir);
assert_eq!(workspace_dir, manifest_dir.clone());
assert_eq!(manifest_dir.join("Cargo.toml"), manifest_path);
}
"#,
)
@ -1955,12 +1960,15 @@ fn cargo_rustc_current_dir_non_local_dep() {
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 manifest_path = Path::new(option_env!("CARGO_MANIFEST_PATH").expect("CARGO_MANIFEST_PATH"));
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_path = std::fs::canonicalize(current_dir.join(manifest_dir.clone()).join("Cargo.toml")).expect("CARGO_MANIFEST_PATH");
let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
assert_eq!(workspace_dir, manifest_dir);
assert_eq!(workspace_dir, manifest_dir.clone());
assert_eq!(manifest_dir.join("Cargo.toml"), manifest_path);
}
"#,
)

View file

@ -1317,3 +1317,33 @@ fn cmd_publish_with_embedded() {
"#]])
.run();
}
#[cargo_test]
fn manifest_path_env() {
let p = cargo_test_support::project()
.file(
"script.rs",
r#"#!/usr/bin/env cargo
fn main() {
let path = env!("CARGO_MANIFEST_PATH");
println!("CARGO_MANIFEST_PATH: {}", path);
}
"#,
)
.build();
p.cargo("-Zscript -v script.rs")
.masquerade_as_nightly_cargo(&["script"])
.with_stdout_data(str![[r#"
CARGO_MANIFEST_PATH: [ROOT]/foo/script.rs
"#]])
.with_stderr_data(str![[r#"
[WARNING] `package.edition` is unspecified, defaulting to `2021`
[COMPILING] script v0.0.0 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[RUNNING] `[ROOT]/home/.cargo/target/[HASH]/debug/script[EXE]`
"#]])
.run();
}