mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
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](https://github.com/rust-lang/cargo/issues/14195#issuecomment-2211481773). 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`.
This commit is contained in:
commit
61424d6040
@ -8,9 +8,7 @@
|
||||
//! * [`TargetInfo::rustc_outputs`] to get a list of supported file types.
|
||||
|
||||
use crate::core::compiler::apply_env_config;
|
||||
use crate::core::compiler::{
|
||||
BuildOutput, BuildRunner, CompileKind, CompileMode, CompileTarget, CrateType,
|
||||
};
|
||||
use crate::core::compiler::{BuildRunner, CompileKind, CompileMode, CompileTarget, CrateType};
|
||||
use crate::core::{Dependency, Package, Target, TargetKind, Workspace};
|
||||
use crate::util::context::{GlobalContext, StringList, TargetConfig};
|
||||
use crate::util::interning::InternedString;
|
||||
@ -1038,14 +1036,6 @@ impl<'gctx> RustcTargetData<'gctx> {
|
||||
CompileKind::Target(s) => &self.target_config[&s],
|
||||
}
|
||||
}
|
||||
|
||||
/// If a build script is overridden, this returns the `BuildOutput` to use.
|
||||
///
|
||||
/// `lib_name` is the `links` library name and `kind` is whether it is for
|
||||
/// Host or Target.
|
||||
pub fn script_override(&self, lib_name: &str, kind: CompileKind) -> Option<&BuildOutput> {
|
||||
self.target_config(kind).links_overrides.get(lib_name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Structure used to deal with Rustdoc fingerprinting
|
||||
|
@ -61,7 +61,7 @@ const OLD_CARGO_WARNING_SYNTAX: &str = "cargo:warning=";
|
||||
/// [the doc]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargo-warning
|
||||
const NEW_CARGO_WARNING_SYNTAX: &str = "cargo::warning=";
|
||||
/// Contains the parsed output of a custom build script.
|
||||
#[derive(Clone, Debug, Hash, Default)]
|
||||
#[derive(Clone, Debug, Hash, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct BuildOutput {
|
||||
/// Paths to pass to rustc with the `-L` flag.
|
||||
pub library_paths: Vec<PathBuf>,
|
||||
@ -160,7 +160,7 @@ pub struct BuildDeps {
|
||||
/// See the [build script documentation][1] for more.
|
||||
///
|
||||
/// [1]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargorustc-link-argflag
|
||||
#[derive(Clone, Hash, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum LinkArgTarget {
|
||||
/// Represents `cargo::rustc-link-arg=FLAG`.
|
||||
All,
|
||||
@ -1168,11 +1168,7 @@ pub fn build_map(build_runner: &mut BuildRunner<'_, '_>) -> CargoResult<()> {
|
||||
// If there is a build script override, pre-fill the build output.
|
||||
if unit.mode.is_run_custom_build() {
|
||||
if let Some(links) = unit.pkg.manifest().links() {
|
||||
if let Some(output) = build_runner
|
||||
.bcx
|
||||
.target_data
|
||||
.script_override(links, unit.kind)
|
||||
{
|
||||
if let Some(output) = unit.links_overrides.get(links) {
|
||||
let metadata = build_runner.get_run_build_script_metadata(unit);
|
||||
build_runner.build_script_outputs.lock().unwrap().insert(
|
||||
unit.pkg.package_id(),
|
||||
|
@ -219,6 +219,7 @@ pub fn generate_std_roots(
|
||||
features.clone(),
|
||||
target_data.info(*kind).rustflags.clone(),
|
||||
target_data.info(*kind).rustdocflags.clone(),
|
||||
target_data.target_config(*kind).links_overrides.clone(),
|
||||
/*is_std*/ true,
|
||||
/*dep_hash*/ 0,
|
||||
IsArtifact::No,
|
||||
|
@ -9,13 +9,15 @@ use crate::util::hex::short_hash;
|
||||
use crate::util::interning::InternedString;
|
||||
use crate::util::GlobalContext;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::BuildOutput;
|
||||
|
||||
/// All information needed to define a unit.
|
||||
///
|
||||
/// A unit is an object that has enough information so that cargo knows how to build it.
|
||||
@ -82,6 +84,12 @@ pub struct UnitInner {
|
||||
/// [`BuildContext::extra_args_for`]: crate::core::compiler::build_context::BuildContext::extra_args_for
|
||||
/// [`TargetInfo.rustdocflags`]: crate::core::compiler::build_context::TargetInfo::rustdocflags
|
||||
pub rustdocflags: Arc<[String]>,
|
||||
/// Build script override for the given library name.
|
||||
///
|
||||
/// Any package with a `links` value for the given library name will skip
|
||||
/// running its build script and instead use the given output from the
|
||||
/// config file.
|
||||
pub links_overrides: Rc<BTreeMap<String, BuildOutput>>,
|
||||
// if `true`, the dependency is an artifact dependency, requiring special handling when
|
||||
// calculating output directories, linkage and environment variables provided to builds.
|
||||
pub artifact: IsArtifact,
|
||||
@ -176,6 +184,7 @@ impl fmt::Debug for Unit {
|
||||
.field("features", &self.features)
|
||||
.field("rustflags", &self.rustflags)
|
||||
.field("rustdocflags", &self.rustdocflags)
|
||||
.field("links_overrides", &self.links_overrides)
|
||||
.field("artifact", &self.artifact.is_true())
|
||||
.field(
|
||||
"artifact_target_for_features",
|
||||
@ -225,6 +234,7 @@ impl UnitInterner {
|
||||
features: Vec<InternedString>,
|
||||
rustflags: Arc<[String]>,
|
||||
rustdocflags: Arc<[String]>,
|
||||
links_overrides: Rc<BTreeMap<String, BuildOutput>>,
|
||||
is_std: bool,
|
||||
dep_hash: u64,
|
||||
artifact: IsArtifact,
|
||||
@ -260,6 +270,7 @@ impl UnitInterner {
|
||||
features,
|
||||
rustflags,
|
||||
rustdocflags,
|
||||
links_overrides,
|
||||
is_std,
|
||||
dep_hash,
|
||||
artifact,
|
||||
|
@ -457,11 +457,7 @@ fn compute_deps_custom_build(
|
||||
state: &State<'_, '_>,
|
||||
) -> CargoResult<Vec<UnitDep>> {
|
||||
if let Some(links) = unit.pkg.manifest().links() {
|
||||
if state
|
||||
.target_data
|
||||
.script_override(links, unit.kind)
|
||||
.is_some()
|
||||
{
|
||||
if unit.links_overrides.get(links).is_some() {
|
||||
// Overridden build scripts don't have any dependencies.
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
@ -861,6 +857,11 @@ fn new_unit_dep_with_profile(
|
||||
features,
|
||||
state.target_data.info(kind).rustflags.clone(),
|
||||
state.target_data.info(kind).rustdocflags.clone(),
|
||||
state
|
||||
.target_data
|
||||
.target_config(kind)
|
||||
.links_overrides
|
||||
.clone(),
|
||||
state.is_std,
|
||||
/*dep_hash*/ 0,
|
||||
artifact.map_or(IsArtifact::No, |_| IsArtifact::Yes),
|
||||
|
@ -698,6 +698,7 @@ fn traverse_and_share(
|
||||
unit.features.clone(),
|
||||
unit.rustflags.clone(),
|
||||
unit.rustdocflags.clone(),
|
||||
unit.links_overrides.clone(),
|
||||
unit.is_std,
|
||||
unit.dep_hash,
|
||||
unit.artifact,
|
||||
@ -725,6 +726,7 @@ fn traverse_and_share(
|
||||
unit.features.clone(),
|
||||
unit.rustflags.clone(),
|
||||
unit.rustdocflags.clone(),
|
||||
unit.links_overrides.clone(),
|
||||
unit.is_std,
|
||||
new_dep_hash,
|
||||
unit.artifact,
|
||||
@ -888,6 +890,7 @@ fn override_rustc_crate_types(
|
||||
unit.features.clone(),
|
||||
unit.rustflags.clone(),
|
||||
unit.rustdocflags.clone(),
|
||||
unit.links_overrides.clone(),
|
||||
unit.is_std,
|
||||
unit.dep_hash,
|
||||
unit.artifact,
|
||||
|
@ -173,6 +173,7 @@ impl<'a> UnitGenerator<'a, '_> {
|
||||
features.clone(),
|
||||
self.target_data.info(kind).rustflags.clone(),
|
||||
self.target_data.info(kind).rustdocflags.clone(),
|
||||
self.target_data.target_config(kind).links_overrides.clone(),
|
||||
/*is_std*/ false,
|
||||
/*dep_hash*/ 0,
|
||||
IsArtifact::No,
|
||||
|
@ -4,6 +4,7 @@ use crate::util::CargoResult;
|
||||
use serde::Deserialize;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Config definition of a `[target.'cfg(…)']` table.
|
||||
///
|
||||
@ -36,7 +37,7 @@ pub struct TargetConfig {
|
||||
/// Any package with a `links` value for the given library name will skip
|
||||
/// running its build script and instead use the given output from the
|
||||
/// config file.
|
||||
pub links_overrides: BTreeMap<String, BuildOutput>,
|
||||
pub links_overrides: Rc<BTreeMap<String, BuildOutput>>,
|
||||
}
|
||||
|
||||
/// Loads all of the `target.'cfg()'` tables.
|
||||
@ -128,7 +129,7 @@ fn load_config_table(gctx: &GlobalContext, prefix: &str) -> CargoResult<TargetCo
|
||||
rustflags,
|
||||
rustdocflags,
|
||||
linker,
|
||||
links_overrides,
|
||||
links_overrides: Rc::new(links_overrides),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -5777,3 +5777,41 @@ hello
|
||||
"#]])
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn links_overrides_with_target_applies_to_host() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "mylib-sys"
|
||||
edition = "2021"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
links = "mylib"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file("build.rs", "bad file")
|
||||
.build();
|
||||
|
||||
p.cargo("build -v")
|
||||
.masquerade_as_nightly_cargo(&["target-applies-to-host"])
|
||||
.args(&[
|
||||
"-Ztarget-applies-to-host",
|
||||
"--config",
|
||||
"target-applies-to-host=false",
|
||||
])
|
||||
.args(&[
|
||||
"--config",
|
||||
&format!(r#"target.{}.mylib.rustc-link-search=["foo"]"#, rustc_host()),
|
||||
])
|
||||
.with_stderr_data(str![[r#"
|
||||
[COMPILING] mylib-sys v0.0.1 ([ROOT]/foo)
|
||||
[RUNNING] `rustc --crate-name mylib_sys [..] -L foo`
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]])
|
||||
.run();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user