Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add env variable to indicate the build type. #9532

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
11 changes: 10 additions & 1 deletion src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,9 @@ pub struct RustcTargetData<'cfg> {
target_config: HashMap<CompileTarget, TargetConfig>,
/// Information about the target platform that we're building for.
target_info: HashMap<CompileTarget, TargetInfo>,

/// True if a `--target` flag is passed.
is_cross: bool,
}

impl<'cfg> RustcTargetData<'cfg> {
Expand All @@ -834,13 +837,14 @@ impl<'cfg> RustcTargetData<'cfg> {
} else {
config.host_cfg_triple(&rustc.host)?
};
let is_cross = !requested_kinds.iter().any(CompileKind::is_host);

// This is a hack. The unit_dependency graph builder "pretends" that
// `CompileKind::Host` is `CompileKind::Target(host)` if the
// `--target` flag is not specified. Since the unit_dependency code
// needs access to the target config data, create a copy so that it
// can be found. See `rebuild_unit_graph_shared` for why this is done.
if requested_kinds.iter().any(CompileKind::is_host) {
if !is_cross {
let ct = CompileTarget::new(&rustc.host)?;
target_info.insert(ct, host_info.clone());
target_config.insert(ct, config.target_cfg_triple(&rustc.host)?);
Expand All @@ -854,6 +858,7 @@ impl<'cfg> RustcTargetData<'cfg> {
host_info,
target_config,
target_info,
is_cross,
};

// Get all kinds we currently know about.
Expand Down Expand Up @@ -954,6 +959,10 @@ impl<'cfg> RustcTargetData<'cfg> {
pub fn script_override(&self, lib_name: &str, kind: CompileKind) -> Option<&BuildOutput> {
self.target_config(kind).links_overrides.get(lib_name)
}

pub fn is_cross(&self) -> bool {
self.is_cross
}
}

/// Structure used to deal with Rustdoc fingerprinting
Expand Down
17 changes: 17 additions & 0 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
ProfileRoot::Debug => "debug",
},
)
.env(
"CARGO_BUILD_DEPENDENCY_TYPE",
match unit.kind.is_host() {
true => "host",
false => "target",
},
)
.env("HOST", &bcx.host_triple())
.env("RUSTC", &bcx.rustc().path)
.env("RUSTDOC", &*bcx.config.rustdoc()?)
Expand All @@ -211,6 +218,16 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
cmd.env(&var, value);
}

if !unit.kind.is_host() {
cmd.env(
"CARGO_BUILD_TYPE",
match &bcx.target_data.is_cross() {
true => "cross",
false => "native",
},
);
}

if let Some(linker) = &bcx.target_data.target_config(unit.kind).linker {
cmd.env(
"RUSTC_LINKER",
Expand Down
7 changes: 7 additions & 0 deletions src/doc/src/reference/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,13 @@ let out_dir = env::var("OUT_DIR").unwrap();
`out_dir` will now contain the value of `OUT_DIR`.

* `CARGO` — Path to the `cargo` binary performing the build.
* `CARGO_BUILD_TYPE` — The type of build being performed.
`cross` when the build target is overridden.
`native` when a build target is not specified(default).
Note: only present for `target` dependency types
* `CARGO_BUILD_DEPENDENCY_TYPE` — The type of build this is a dependency for.
`host` when the build target is for the host.
`target` when a build target is for the target.
* `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
Expand Down
234 changes: 233 additions & 1 deletion tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,11 @@ fn custom_build_env_vars() {
let rustdoc = env::var("RUSTDOC").unwrap();
assert_eq!(rustdoc, "rustdoc");

// TODO: Fix so that these are correct
// assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
// assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "native");
assert!(env::var("RUSTC_WRAPPER").is_err());
assert!(env::var("RUSTC_WORKSPACE_WRAPPER").is_err());

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

assert!(env::var("RUSTFLAGS").is_err());
Expand Down Expand Up @@ -348,6 +350,7 @@ fn custom_build_env_var_rustc_linker() {
use std::env;

fn main() {
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
assert!(env::var("RUSTC_LINKER").unwrap().ends_with("/path/to/linker"));
}
"#,
Expand Down Expand Up @@ -412,6 +415,7 @@ fn custom_build_env_var_rustc_linker_host_target() {
use std::env;

fn main() {
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
assert!(env::var("RUSTC_LINKER").unwrap().ends_with("/path/to/linker"));
}
"#,
Expand Down Expand Up @@ -447,6 +451,7 @@ fn custom_build_env_var_rustc_linker_host_target_env() {
use std::env;

fn main() {
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
assert!(env::var("RUSTC_LINKER").unwrap().ends_with("/path/to/linker"));
}
"#,
Expand Down Expand Up @@ -624,6 +629,7 @@ fn custom_build_env_var_rustc_linker_cross_arch_host() {
use std::env;

fn main() {
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
assert!(env::var("RUSTC_LINKER").unwrap().ends_with("/path/to/target/linker"));
}
"#,
Expand Down Expand Up @@ -1048,6 +1054,9 @@ fn overrides_and_links() {
r#"
use std::env;
fn main() {
// TODO: Fix so that these are correct
// assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
// assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "native");
assert_eq!(env::var("DEP_FOO_FOO").ok().expect("FOO missing"),
"bar");
assert_eq!(env::var("DEP_FOO_BAR").ok().expect("BAR missing"),
Expand Down Expand Up @@ -1153,6 +1162,9 @@ fn links_passes_env_vars() {
r#"
use std::env;
fn main() {
// TODO: Fix so that these are correct
// assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
// assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "native");
assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz");
}
Expand Down Expand Up @@ -1276,6 +1288,9 @@ fn rebuild_continues_to_pass_env_vars() {
r#"
use std::env;
fn main() {
// TODO: Fix so that these are correct
// assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
// assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "native");
assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz");
}
Expand Down Expand Up @@ -2336,6 +2351,223 @@ fn test_duplicate_deps() {
p.cargo("build").run();
}

#[cargo_test]
fn test_duplicate_shared_deps_native() {
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
authors = []
build = "build.rs"

[dependencies]
bar = { path = 'bar' }

[build-dependencies]
bar = { path = 'bar' }
"#,
)
.file(
"src/main.rs",
r#"
extern crate bar;
fn main() { bar::do_nothing() }
"#,
)
.file(
"build.rs",
r#"
extern crate bar;
use std::env;
fn main() {
bar::do_nothing();
// TODO: Fix so that these are correct
// assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
// assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "native");
}
"#,
)
.file(
"bar/Cargo.toml",
r#"
[project]
name = "bar"
version = "0.1.0"
authors = []
links = "foo"
build = "build.rs"
"#,
)
.file(
"bar/build.rs",
r#"
use std::env;
fn main() {
println!("cargo:foo=bar");
if env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap() == "host" {
assert!(env::var("CARGO_BUILD_TYPE").is_err());
} else {
assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "native");
}
}
"#,
)
.file("bar/src/lib.rs", "pub fn do_nothing() {}")
.build();

p.cargo("build -v").run();
}

#[cargo_test]
fn test_duplicate_shared_deps_host_cross() {
let target = rustc_host();
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
authors = []
build = "build.rs"

[dependencies]
bar = { path = 'bar' }

[build-dependencies]
bar = { path = 'bar' }
"#,
)
.file(
"src/main.rs",
r#"
extern crate bar;
fn main() { bar::do_nothing() }
"#,
)
.file(
"build.rs",
r#"
extern crate bar;
use std::env;
fn main() {
bar::do_nothing();
assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
}
"#,
)
.file(
"bar/Cargo.toml",
r#"
[project]
name = "bar"
version = "0.1.0"
authors = []
links = "foo"
build = "build.rs"
"#,
)
.file(
"bar/build.rs",
r#"
use std::env;
fn main() {
println!("cargo:foo=bar");
if env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap() == "host" {
assert!(env::var("CARGO_BUILD_TYPE").is_err());
} else {
assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
}
}
"#,
)
.file("bar/src/lib.rs", "pub fn do_nothing() {}")
.build();

p.cargo("build -v --target").arg(&target).run();
}

#[cargo_test]
fn test_duplicate_shared_deps_alt_cross() {
if cross_compile::disabled() {
return;
}
let cross_target = cross_compile::alternate();
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
authors = []
build = "build.rs"

[dependencies]
bar = { path = 'bar' }

[build-dependencies]
bar = { path = 'bar' }
"#,
)
.file(
"src/main.rs",
r#"
extern crate bar;
fn main() { bar::do_nothing() }
"#,
)
.file(
"build.rs",
r#"
extern crate bar;
use std::env;
fn main() {
bar::do_nothing();
assert_eq!(env::var("DEP_FOO_FOO").unwrap(), "bar");
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
}
"#,
)
.file(
"bar/Cargo.toml",
r#"
[project]
name = "bar"
version = "0.1.0"
authors = []
links = "foo"
build = "build.rs"
"#,
)
.file(
"bar/build.rs",
r#"
use std::env;
fn main() {
println!("cargo:foo=bar");
if env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap() == "host" {
assert!(env::var("CARGO_BUILD_TYPE").is_err());
} else {
assert_eq!(env::var("CARGO_BUILD_DEPENDENCY_TYPE").unwrap(), "target");
assert_eq!(env::var("CARGO_BUILD_TYPE").unwrap(), "cross");
}
}
"#,
)
.file("bar/src/lib.rs", "pub fn do_nothing() {}")
.build();

p.cargo("build --target").arg(&cross_target).run();
}

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