Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/cargo-test-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,14 @@ pub fn is_nightly() -> bool {
&& (vv.contains("-nightly") || vv.contains("-dev"))
}

pub fn rustc_release() -> &'static str {
RUSTC_INFO
.verbose_version
.lines()
.find_map(|line| line.strip_prefix("release: "))
.expect("verbose version has release: field")
}

pub fn process<T: AsRef<OsStr>>(t: T) -> ProcessBuilder {
_process(t.as_ref())
}
Expand Down
22 changes: 22 additions & 0 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,28 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
}
}

// Also inform the build script of the rustc compiler context.
if let Some(wrapper) = bcx.rustc().wrapper.as_ref() {
cmd.env("RUSTC_WRAPPER", wrapper);
}
cmd.env("RUSTFLAGS", bcx.rustflags_args(unit).join(" "));
let version = crate::version();
cmd.env(
"CARGO_VERSION",
format!("{}.{}.{}", version.major, version.minor, version.patch),
);
cmd.env("CARGO_VERSION_MAJOR", version.major.to_string());
cmd.env("CARGO_VERSION_MINOR", version.minor.to_string());
cmd.env("CARGO_VERSION_PATCH", version.patch.to_string());
let version = &bcx.rustc().version;
cmd.env(
"RUSTC_VERSION",
format!("{}.{}.{}", version.major, version.minor, version.patch),
);
cmd.env("RUSTC_VERSION_MAJOR", version.major.to_string());
cmd.env("RUSTC_VERSION_MINOR", version.minor.to_string());
cmd.env("RUSTC_VERSION_PATCH", version.patch.to_string());

// Gather the set of native dependencies that this package has along with
// some other variables to close over.
//
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 @@ -334,11 +334,15 @@ let out_dir = env::var("OUT_DIR").unwrap();
* `RUSTC`, `RUSTDOC` — the compiler and documentation generator that Cargo has
resolved to use, passed to the build script so it might
use it as well.
* `CARGO_RUSTC_WRAPPER` — the `rustc` wrapper, if any, that Cargo is using.
See [`build.rustc-wrapper`].
* `RUSTC_LINKER` — The path to the linker binary that Cargo has resolved to use
for the current target, if specified. The linker can be
changed by editing `.cargo/config.toml`; see the documentation
about [cargo configuration][cargo-config] for more
information.
* `CARGO_RUSTFLAGS` — the `RUSTFLAGS` that Cargo invokes `rustc` with.
See [`build.rustflags`].
* `CARGO_PKG_<var>` - The package information variables, with the same names and values as are [provided during crate building][variables set for crates].

[unix-like platforms]: ../../reference/conditional-compilation.html#unix-and-windows
Expand Down
108 changes: 105 additions & 3 deletions tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
use cargo_test_support::compare::assert_match_exact;
use cargo_test_support::paths::CargoPathExt;
use cargo_test_support::registry::Package;
use cargo_test_support::tools;
use cargo_test_support::{basic_manifest, cross_compile, is_coarse_mtime, project};
use cargo_test_support::{rustc_host, sleep_ms, slow_cpu_multiplier, symlink_supported};
use cargo_test_support::{
rustc_host, rustc_release, sleep_ms, slow_cpu_multiplier, symlink_supported,
};
use cargo_util::paths::remove_dir_all;
use std::env;
use std::fs;
Expand Down Expand Up @@ -79,10 +82,11 @@ fn custom_build_env_vars() {
)
.file("bar/src/lib.rs", "pub fn hello() {}");

let cargo_version = cargo::version();
let rustc_version = semver::Version::parse(rustc_release()).unwrap();
let file_content = format!(
r#"
use std::env;
use std::io::prelude::*;
use std::path::Path;

fn main() {{
Expand Down Expand Up @@ -115,21 +119,119 @@ fn custom_build_env_vars() {
let rustdoc = env::var("RUSTDOC").unwrap();
assert_eq!(rustdoc, "rustdoc");

assert!(env::var("RUSTC_WRAPPER").is_err());

assert!(env::var("RUSTC_LINKER").is_err());

let rustflags = env::var("RUSTFLAGS").unwrap();
assert_eq!(rustflags, "");

let version = env::var("CARGO_VERSION").unwrap();
assert_eq!(version, "{1}.{2}.{3}", "bad cargo version");
let version = env::var("CARGO_VERSION_MAJOR").unwrap();
assert_eq!(version, "{1}");
let version = env::var("CARGO_VERSION_MINOR").unwrap();
assert_eq!(version, "{2}");
let version = env::var("CARGO_VERSION_PATCH").unwrap();
assert_eq!(version, "{3}");

let version = env::var("RUSTC_VERSION").unwrap();
assert_eq!(version, "{4}.{5}.{6}", "bad rust version");
let version = env::var("RUSTC_VERSION_MAJOR").unwrap();
assert_eq!(version, "{4}");
let version = env::var("RUSTC_VERSION_MINOR").unwrap();
assert_eq!(version, "{5}");
let version = env::var("RUSTC_VERSION_PATCH").unwrap();
assert_eq!(version, "{6}");
}}
"#,
p.root()
.join("target")
.join("debug")
.join("build")
.display()
.display(),
cargo_version.major,
cargo_version.minor,
cargo_version.patch,
rustc_version.major,
rustc_version.minor,
rustc_version.patch,
);

let p = p.file("bar/build.rs", &file_content).build();

p.cargo("build --features bar_feat").run();
}

#[cargo_test]
fn custom_build_env_var_rustflags() {
let rustflags = "--cfg=special";
let rustflags_alt = "--cfg=notspecial";
let p = project()
.file(
".cargo/config",
&format!(
r#"
[build]
rustflags = ["{}"]
"#,
rustflags
),
)
.file(
"build.rs",
&format!(
r#"
use std::env;

fn main() {{
// Static assertion that exactly one of the cfg paths is always taken.
let x;
#[cfg(special)]
{{ assert_eq!(env::var("RUSTFLAGS").unwrap(), "{}"); x = String::new(); }}
#[cfg(notspecial)]
{{ assert_eq!(env::var("RUSTFLAGS").unwrap(), "{}"); x = String::new(); }}
let _ = x;
}}
"#,
rustflags, rustflags_alt,
),
)
.file("src/lib.rs", "")
.build();

p.cargo("check").run();

// RUSTFLAGS overrides build.rustflags, so --cfg=special shouldn't be passed
p.cargo("check").env("RUSTFLAGS", rustflags_alt).run();
}

#[cargo_test]
fn custom_build_env_var_rustc_wrapper() {
let wrapper = tools::echo_wrapper();
let p = project()
.file(
"build.rs",
r#"
use std::env;

fn main() {{
assert_eq!(
env::var("RUSTC_WRAPPER").unwrap(),
env::var("CARGO_RUSTC_WRAPPER_CHECK").unwrap()
);
}}
"#,
)
.file("src/lib.rs", "")
.build();

p.cargo("check")
.env("CARGO_BUILD_RUSTC_WRAPPER", &wrapper)
.env("CARGO_RUSTC_WRAPPER_CHECK", &wrapper)
.run();
}

#[cargo_test]
fn custom_build_env_var_rustc_linker() {
if cross_compile::disabled() {
Expand Down