Skip to content

Commit e1c9bcf

Browse files
committed
Don't use $CARGO_BUILD_TARGET in cargo metadata
This commit fixes a (five year old!) regression in `cargo metadata` where if `--filter-platform` isn't explicitly specified it will accidentally read `$CARGO_BUILD_TARGET` (or `build.target` configuration) and use that as the default `--filter-platform`. The reason for this is that the calculation for targets changed in #8167 and while the shared function makes sense for other commands such as `cargo build` the targets have a different meaning in `cargo metadata` so a slightly different set of functionality is desired. This commit fixes the issue by introducing a new constructor for the list of `CompileKind` variants where the fallback of "if nothing is specified" is explicitly chosen.
1 parent bf43053 commit e1c9bcf

File tree

4 files changed

+77
-7
lines changed

4 files changed

+77
-7
lines changed

src/cargo/core/compiler/compile_kind.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ pub enum CompileKind {
2929
Target(CompileTarget),
3030
}
3131

32+
/// Fallback behavior in the
33+
/// [`CompileKindFallback::from_requested_targets_with_fallback`] function when
34+
/// no targets are specified.
35+
pub enum CompileKindFallback {
36+
/// The build configuration is consulted to find the default target, such as
37+
/// `$CARGO_BUILD_TARGET` or reading `build.target`.
38+
BuildConfig,
39+
40+
/// Only the host should be returned when targets aren't explicitly
41+
/// specified. This is used by `cargo metadata` for example where "only
42+
/// host" has a special meaning in terms of the returned metadata.
43+
JustHost,
44+
}
45+
3246
impl CompileKind {
3347
pub fn is_host(&self) -> bool {
3448
matches!(self, CompileKind::Host)
@@ -53,6 +67,21 @@ impl CompileKind {
5367
pub fn from_requested_targets(
5468
gctx: &GlobalContext,
5569
targets: &[String],
70+
) -> CargoResult<Vec<CompileKind>> {
71+
CompileKind::from_requested_targets_with_fallback(
72+
gctx,
73+
targets,
74+
CompileKindFallback::BuildConfig,
75+
)
76+
}
77+
78+
/// Same as [`CompileKind::from_requested_targets`] except that if `targets`
79+
/// doesn't explicitly mention anything the behavior of what to return is
80+
/// controlled by the `fallback` argument.
81+
pub fn from_requested_targets_with_fallback(
82+
gctx: &GlobalContext,
83+
targets: &[String],
84+
fallback: CompileKindFallback,
5685
) -> CargoResult<Vec<CompileKind>> {
5786
let dedup = |targets: &[String]| {
5887
Ok(targets
@@ -70,9 +99,11 @@ impl CompileKind {
7099
return dedup(targets);
71100
}
72101

73-
let kinds = match &gctx.build_config()?.target {
74-
None => Ok(vec![CompileKind::Host]),
75-
Some(build_target_config) => dedup(&build_target_config.values(gctx)?),
102+
let kinds = match (fallback, &gctx.build_config()?.target) {
103+
(_, None) | (CompileKindFallback::JustHost, _) => Ok(vec![CompileKind::Host]),
104+
(CompileKindFallback::BuildConfig, Some(build_target_config)) => {
105+
dedup(&build_target_config.values(gctx)?)
106+
}
76107
};
77108

78109
kinds

src/cargo/core/compiler/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub use self::build_context::{
7676
use self::build_plan::BuildPlan;
7777
pub use self::build_runner::{BuildRunner, Metadata, UnitHash};
7878
pub use self::compilation::{Compilation, Doctest, UnitOutput};
79-
pub use self::compile_kind::{CompileKind, CompileTarget};
79+
pub use self::compile_kind::{CompileKind, CompileKindFallback, CompileTarget};
8080
pub use self::crate_type::CrateType;
8181
pub use self::custom_build::LinkArgTarget;
8282
pub use self::custom_build::{BuildOutput, BuildScriptOutputs, BuildScripts};

src/cargo/ops/cargo_output_metadata.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::core::compiler::artifact::match_artifacts_kind_with_targets;
2-
use crate::core::compiler::{CompileKind, RustcTargetData};
2+
use crate::core::compiler::{CompileKind, CompileKindFallback, RustcTargetData};
33
use crate::core::dependency::DepKind;
44
use crate::core::package::SerializedPackage;
55
use crate::core::resolver::{features::CliFeatures, HasDevUnits, Resolve};
@@ -132,8 +132,16 @@ fn build_resolve_graph(
132132
) -> CargoResult<(Vec<SerializedPackage>, MetadataResolve)> {
133133
// TODO: Without --filter-platform, features are being resolved for `host` only.
134134
// How should this work?
135-
let requested_kinds =
136-
CompileKind::from_requested_targets(ws.gctx(), &metadata_opts.filter_platforms)?;
135+
//
136+
// Otherwise note that "just host" is used as the fallback here if
137+
// `filter_platforms` is empty to intentionally avoid reading
138+
// `$CARGO_BUILD_TARGET` (or `build.target`) which makes sense for other
139+
// subcommands like `cargo build` but does not fit with this command.
140+
let requested_kinds = CompileKind::from_requested_targets_with_fallback(
141+
ws.gctx(),
142+
&metadata_opts.filter_platforms,
143+
CompileKindFallback::JustHost,
144+
)?;
137145
let mut target_data = RustcTargetData::new(ws, &requested_kinds)?;
138146
// Resolve entire workspace.
139147
let specs = Packages::All(Vec::new()).to_package_id_specs(ws)?;

tests/testsuite/metadata.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4954,3 +4954,34 @@ local-time = 1979-05-27
49544954
)
49554955
.run();
49564956
}
4957+
4958+
#[cargo_test]
4959+
fn metadata_ignores_build_target_configuration() -> anyhow::Result<()> {
4960+
let p = project()
4961+
.file(
4962+
"Cargo.toml",
4963+
r#"
4964+
[package]
4965+
name = "foo"
4966+
4967+
[target.'cfg(something)'.dependencies]
4968+
foobar = "0.0.1"
4969+
"#,
4970+
)
4971+
.file("src/lib.rs", "")
4972+
.build();
4973+
Package::new("foobar", "0.0.1").publish();
4974+
4975+
let output1 = p
4976+
.cargo("metadata -q --format-version 1")
4977+
.exec_with_output()?;
4978+
let output2 = p
4979+
.cargo("metadata -q --format-version 1")
4980+
.env("CARGO_BUILD_TARGET", rustc_host())
4981+
.exec_with_output()?;
4982+
assert!(
4983+
output1.stdout == output2.stdout,
4984+
"metadata should not change when `CARGO_BUILD_TARGET` is set",
4985+
);
4986+
Ok(())
4987+
}

0 commit comments

Comments
 (0)