Skip to content

Commit 61424d6

Browse files
committed
Auto merge of #14205 - gmorenz:links_overrides_in_unit, r=weihanglo
Fix passing of links-overrides with target-applies-to-host and an implicit target ### What does this PR try to resolve? This fixes the link-overrides half of #14195, both the panic, and the fact that the field is being discarded, the latter of which caused the former as discussed in [the issue](#14195 (comment)). It does so following the blueprint laid out in #13900 - which is also in my opinion the current best summary of the broader context. ### How should we test and review this PR? For reviewing, comparing to the changes in #13900 might be useful. ### Additional information I'm pushing a PR for the other half of #14195 simultaneously. I thought it better to keep the PRs small since they're independent, though if merged simultaneously there will be a conflict over the ordering of fields in `Unit`.
2 parents 913d4b8 + 9098072 commit 61424d6

File tree

9 files changed

+68
-26
lines changed

9 files changed

+68
-26
lines changed

src/cargo/core/compiler/build_context/target_info.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
//! * [`TargetInfo::rustc_outputs`] to get a list of supported file types.
99
1010
use crate::core::compiler::apply_env_config;
11-
use crate::core::compiler::{
12-
BuildOutput, BuildRunner, CompileKind, CompileMode, CompileTarget, CrateType,
13-
};
11+
use crate::core::compiler::{BuildRunner, CompileKind, CompileMode, CompileTarget, CrateType};
1412
use crate::core::{Dependency, Package, Target, TargetKind, Workspace};
1513
use crate::util::context::{GlobalContext, StringList, TargetConfig};
1614
use crate::util::interning::InternedString;
@@ -1038,14 +1036,6 @@ impl<'gctx> RustcTargetData<'gctx> {
10381036
CompileKind::Target(s) => &self.target_config[&s],
10391037
}
10401038
}
1041-
1042-
/// If a build script is overridden, this returns the `BuildOutput` to use.
1043-
///
1044-
/// `lib_name` is the `links` library name and `kind` is whether it is for
1045-
/// Host or Target.
1046-
pub fn script_override(&self, lib_name: &str, kind: CompileKind) -> Option<&BuildOutput> {
1047-
self.target_config(kind).links_overrides.get(lib_name)
1048-
}
10491039
}
10501040

10511041
/// Structure used to deal with Rustdoc fingerprinting

src/cargo/core/compiler/custom_build.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const OLD_CARGO_WARNING_SYNTAX: &str = "cargo:warning=";
6161
/// [the doc]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargo-warning
6262
const NEW_CARGO_WARNING_SYNTAX: &str = "cargo::warning=";
6363
/// Contains the parsed output of a custom build script.
64-
#[derive(Clone, Debug, Hash, Default)]
64+
#[derive(Clone, Debug, Hash, Default, PartialEq, Eq, PartialOrd, Ord)]
6565
pub struct BuildOutput {
6666
/// Paths to pass to rustc with the `-L` flag.
6767
pub library_paths: Vec<PathBuf>,
@@ -160,7 +160,7 @@ pub struct BuildDeps {
160160
/// See the [build script documentation][1] for more.
161161
///
162162
/// [1]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargorustc-link-argflag
163-
#[derive(Clone, Hash, Debug, PartialEq, Eq)]
163+
#[derive(Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
164164
pub enum LinkArgTarget {
165165
/// Represents `cargo::rustc-link-arg=FLAG`.
166166
All,
@@ -1168,11 +1168,7 @@ pub fn build_map(build_runner: &mut BuildRunner<'_, '_>) -> CargoResult<()> {
11681168
// If there is a build script override, pre-fill the build output.
11691169
if unit.mode.is_run_custom_build() {
11701170
if let Some(links) = unit.pkg.manifest().links() {
1171-
if let Some(output) = build_runner
1172-
.bcx
1173-
.target_data
1174-
.script_override(links, unit.kind)
1175-
{
1171+
if let Some(output) = unit.links_overrides.get(links) {
11761172
let metadata = build_runner.get_run_build_script_metadata(unit);
11771173
build_runner.build_script_outputs.lock().unwrap().insert(
11781174
unit.pkg.package_id(),

src/cargo/core/compiler/standard_lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ pub fn generate_std_roots(
219219
features.clone(),
220220
target_data.info(*kind).rustflags.clone(),
221221
target_data.info(*kind).rustdocflags.clone(),
222+
target_data.target_config(*kind).links_overrides.clone(),
222223
/*is_std*/ true,
223224
/*dep_hash*/ 0,
224225
IsArtifact::No,

src/cargo/core/compiler/unit.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ use crate::util::hex::short_hash;
99
use crate::util::interning::InternedString;
1010
use crate::util::GlobalContext;
1111
use std::cell::RefCell;
12-
use std::collections::HashSet;
12+
use std::collections::{BTreeMap, HashSet};
1313
use std::fmt;
1414
use std::hash::{Hash, Hasher};
1515
use std::ops::Deref;
1616
use std::rc::Rc;
1717
use std::sync::Arc;
1818

19+
use super::BuildOutput;
20+
1921
/// All information needed to define a unit.
2022
///
2123
/// A unit is an object that has enough information so that cargo knows how to build it.
@@ -82,6 +84,12 @@ pub struct UnitInner {
8284
/// [`BuildContext::extra_args_for`]: crate::core::compiler::build_context::BuildContext::extra_args_for
8385
/// [`TargetInfo.rustdocflags`]: crate::core::compiler::build_context::TargetInfo::rustdocflags
8486
pub rustdocflags: Arc<[String]>,
87+
/// Build script override for the given library name.
88+
///
89+
/// Any package with a `links` value for the given library name will skip
90+
/// running its build script and instead use the given output from the
91+
/// config file.
92+
pub links_overrides: Rc<BTreeMap<String, BuildOutput>>,
8593
// if `true`, the dependency is an artifact dependency, requiring special handling when
8694
// calculating output directories, linkage and environment variables provided to builds.
8795
pub artifact: IsArtifact,
@@ -176,6 +184,7 @@ impl fmt::Debug for Unit {
176184
.field("features", &self.features)
177185
.field("rustflags", &self.rustflags)
178186
.field("rustdocflags", &self.rustdocflags)
187+
.field("links_overrides", &self.links_overrides)
179188
.field("artifact", &self.artifact.is_true())
180189
.field(
181190
"artifact_target_for_features",
@@ -225,6 +234,7 @@ impl UnitInterner {
225234
features: Vec<InternedString>,
226235
rustflags: Arc<[String]>,
227236
rustdocflags: Arc<[String]>,
237+
links_overrides: Rc<BTreeMap<String, BuildOutput>>,
228238
is_std: bool,
229239
dep_hash: u64,
230240
artifact: IsArtifact,
@@ -260,6 +270,7 @@ impl UnitInterner {
260270
features,
261271
rustflags,
262272
rustdocflags,
273+
links_overrides,
263274
is_std,
264275
dep_hash,
265276
artifact,

src/cargo/core/compiler/unit_dependencies.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,7 @@ fn compute_deps_custom_build(
457457
state: &State<'_, '_>,
458458
) -> CargoResult<Vec<UnitDep>> {
459459
if let Some(links) = unit.pkg.manifest().links() {
460-
if state
461-
.target_data
462-
.script_override(links, unit.kind)
463-
.is_some()
464-
{
460+
if unit.links_overrides.get(links).is_some() {
465461
// Overridden build scripts don't have any dependencies.
466462
return Ok(Vec::new());
467463
}
@@ -861,6 +857,11 @@ fn new_unit_dep_with_profile(
861857
features,
862858
state.target_data.info(kind).rustflags.clone(),
863859
state.target_data.info(kind).rustdocflags.clone(),
860+
state
861+
.target_data
862+
.target_config(kind)
863+
.links_overrides
864+
.clone(),
864865
state.is_std,
865866
/*dep_hash*/ 0,
866867
artifact.map_or(IsArtifact::No, |_| IsArtifact::Yes),

src/cargo/ops/cargo_compile/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ fn traverse_and_share(
698698
unit.features.clone(),
699699
unit.rustflags.clone(),
700700
unit.rustdocflags.clone(),
701+
unit.links_overrides.clone(),
701702
unit.is_std,
702703
unit.dep_hash,
703704
unit.artifact,
@@ -725,6 +726,7 @@ fn traverse_and_share(
725726
unit.features.clone(),
726727
unit.rustflags.clone(),
727728
unit.rustdocflags.clone(),
729+
unit.links_overrides.clone(),
728730
unit.is_std,
729731
new_dep_hash,
730732
unit.artifact,
@@ -888,6 +890,7 @@ fn override_rustc_crate_types(
888890
unit.features.clone(),
889891
unit.rustflags.clone(),
890892
unit.rustdocflags.clone(),
893+
unit.links_overrides.clone(),
891894
unit.is_std,
892895
unit.dep_hash,
893896
unit.artifact,

src/cargo/ops/cargo_compile/unit_generator.rs

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ impl<'a> UnitGenerator<'a, '_> {
173173
features.clone(),
174174
self.target_data.info(kind).rustflags.clone(),
175175
self.target_data.info(kind).rustdocflags.clone(),
176+
self.target_data.target_config(kind).links_overrides.clone(),
176177
/*is_std*/ false,
177178
/*dep_hash*/ 0,
178179
IsArtifact::No,

src/cargo/util/context/target.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::util::CargoResult;
44
use serde::Deserialize;
55
use std::collections::{BTreeMap, HashMap};
66
use std::path::PathBuf;
7+
use std::rc::Rc;
78

89
/// Config definition of a `[target.'cfg(…)']` table.
910
///
@@ -36,7 +37,7 @@ pub struct TargetConfig {
3637
/// Any package with a `links` value for the given library name will skip
3738
/// running its build script and instead use the given output from the
3839
/// config file.
39-
pub links_overrides: BTreeMap<String, BuildOutput>,
40+
pub links_overrides: Rc<BTreeMap<String, BuildOutput>>,
4041
}
4142

4243
/// Loads all of the `target.'cfg()'` tables.
@@ -128,7 +129,7 @@ fn load_config_table(gctx: &GlobalContext, prefix: &str) -> CargoResult<TargetCo
128129
rustflags,
129130
rustdocflags,
130131
linker,
131-
links_overrides,
132+
links_overrides: Rc::new(links_overrides),
132133
})
133134
}
134135

tests/testsuite/build_script.rs

+38
Original file line numberDiff line numberDiff line change
@@ -5777,3 +5777,41 @@ hello
57775777
"#]])
57785778
.run();
57795779
}
5780+
5781+
#[cargo_test]
5782+
fn links_overrides_with_target_applies_to_host() {
5783+
let p = project()
5784+
.file(
5785+
"Cargo.toml",
5786+
r#"
5787+
[package]
5788+
name = "mylib-sys"
5789+
edition = "2021"
5790+
version = "0.0.1"
5791+
authors = []
5792+
links = "mylib"
5793+
"#,
5794+
)
5795+
.file("src/lib.rs", "")
5796+
.file("build.rs", "bad file")
5797+
.build();
5798+
5799+
p.cargo("build -v")
5800+
.masquerade_as_nightly_cargo(&["target-applies-to-host"])
5801+
.args(&[
5802+
"-Ztarget-applies-to-host",
5803+
"--config",
5804+
"target-applies-to-host=false",
5805+
])
5806+
.args(&[
5807+
"--config",
5808+
&format!(r#"target.{}.mylib.rustc-link-search=["foo"]"#, rustc_host()),
5809+
])
5810+
.with_stderr_data(str![[r#"
5811+
[COMPILING] mylib-sys v0.0.1 ([ROOT]/foo)
5812+
[RUNNING] `rustc --crate-name mylib_sys [..] -L foo`
5813+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
5814+
5815+
"#]])
5816+
.run();
5817+
}

0 commit comments

Comments
 (0)