Pass rustflags to artifacts built with implicit targets when using target-applies-to-host

This commit is contained in:
Greg Morenz 2024-05-10 17:25:17 -04:00
parent a547d19af7
commit 07c9f77ecd
11 changed files with 65 additions and 32 deletions

View File

@ -134,19 +134,6 @@ impl<'a, 'gctx> BuildContext<'a, 'gctx> {
self.build_config.jobs
}
/// Extra compiler flags to pass to `rustc` for a given unit.
///
/// Although it depends on the caller, in the current Cargo implementation,
/// these flags take precedence over those from [`BuildContext::extra_args_for`].
///
/// As of now, these flags come from environment variables and configurations.
/// See [`TargetInfo.rustflags`] for more on how Cargo collects them.
///
/// [`TargetInfo.rustflags`]: TargetInfo::rustflags
pub fn rustflags_args(&self, unit: &Unit) -> &[String] {
&self.target_data.info(unit.kind).rustflags
}
/// Extra compiler flags to pass to `rustdoc` for a given unit.
///
/// Although it depends on the caller, in the current Cargo implementation,

View File

@ -23,6 +23,7 @@ use std::cell::RefCell;
use std::collections::hash_map::{Entry, HashMap};
use std::path::{Path, PathBuf};
use std::str::{self, FromStr};
use std::sync::Arc;
/// Information about the platform target gleaned from querying rustc.
///
@ -52,7 +53,7 @@ pub struct TargetInfo {
/// target libraries.
pub sysroot_target_libdir: PathBuf,
/// Extra flags to pass to `rustc`, see [`extra_args`].
pub rustflags: Vec<String>,
pub rustflags: Arc<[String]>,
/// Extra flags to pass to `rustdoc`, see [`extra_args`].
pub rustdocflags: Vec<String>,
/// Whether or not rustc (stably) supports the `--check-cfg` flag.
@ -312,7 +313,7 @@ impl TargetInfo {
crate_types: RefCell::new(map),
sysroot,
sysroot_target_libdir,
rustflags,
rustflags: rustflags.into(),
rustdocflags: extra_args(
gctx,
requested_kinds,
@ -867,7 +868,10 @@ pub struct RustcTargetData<'gctx> {
/// Build information for the "host", which is information about when
/// `rustc` is invoked without a `--target` flag. This is used for
/// procedural macros, build scripts, etc.
/// selecting a linker, and applying link overrides.
///
/// The configuration read into this depends on whether or not
/// `target-applies-to-host=true`.
host_config: TargetConfig,
/// Information about the host platform.
host_info: TargetInfo,
@ -889,7 +893,10 @@ impl<'gctx> RustcTargetData<'gctx> {
let mut target_config = HashMap::new();
let mut target_info = HashMap::new();
let target_applies_to_host = gctx.target_applies_to_host()?;
let host_target = CompileTarget::new(&rustc.host)?;
let host_info = TargetInfo::new(gctx, requested_kinds, &rustc, CompileKind::Host)?;
// This config is used for link overrides and choosing a linker.
let host_config = if target_applies_to_host {
gctx.target_cfg_triple(&rustc.host)?
} else {
@ -902,9 +909,21 @@ impl<'gctx> RustcTargetData<'gctx> {
// 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) {
let ct = CompileTarget::new(&rustc.host)?;
target_info.insert(ct, host_info.clone());
target_config.insert(ct, gctx.target_cfg_triple(&rustc.host)?);
target_config.insert(host_target, gctx.target_cfg_triple(&rustc.host)?);
// If target_applies_to_host is true, the host_info is the target info,
// otherwise we need to build target info for the target.
if target_applies_to_host {
target_info.insert(host_target, host_info.clone());
} else {
let host_target_info = TargetInfo::new(
gctx,
requested_kinds,
&rustc,
CompileKind::Target(host_target),
)?;
target_info.insert(host_target, host_target_info);
}
};
let mut res = RustcTargetData {

View File

@ -352,10 +352,7 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
cmd.env("RUSTC_WORKSPACE_WRAPPER", wrapper);
}
}
cmd.env(
"CARGO_ENCODED_RUSTFLAGS",
bcx.rustflags_args(unit).join("\x1f"),
);
cmd.env("CARGO_ENCODED_RUSTFLAGS", unit.rustflags.join("\x1f"));
cmd.env_remove("RUSTFLAGS");
if build_runner.bcx.ws.gctx().extra_verbose() {

View File

@ -1417,7 +1417,7 @@ fn calculate_normal(
let extra_flags = if unit.mode.is_doc() || unit.mode.is_doc_scrape() {
build_runner.bcx.rustdocflags_args(unit)
} else {
build_runner.bcx.rustflags_args(unit)
&unit.rustflags
}
.to_vec();
@ -1512,7 +1512,7 @@ fn calculate_run_custom_build(
An I/O error happened. Please make sure you can access the file.
By default, if your project contains a build script, cargo scans all files in
it to determine whether a rebuild is needed. If you don't expect to access the
it to determine whether a rebuild is needed. If you don't expect to access the
file, specify `rerun-if-changed` in your build script.
See https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed for more information.";
pkg_fingerprint(build_runner.bcx, &unit.pkg).map_err(|err| {
@ -1542,7 +1542,7 @@ See https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-change
.collect::<CargoResult<Vec<_>>>()?
};
let rustflags = build_runner.bcx.rustflags_args(unit).to_vec();
let rustflags = unit.rustflags.to_vec();
Ok(Fingerprint {
local: Mutex::new(local),

View File

@ -683,7 +683,7 @@ fn prepare_rustc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResult
base.inherit_jobserver(&build_runner.jobserver);
build_deps_args(&mut base, build_runner, unit)?;
add_cap_lints(build_runner.bcx, unit, &mut base);
base.args(build_runner.bcx.rustflags_args(unit));
base.args(&unit.rustflags);
if build_runner.bcx.gctx.cli_unstable().binary_dep_depinfo {
base.arg("-Z").arg("binary-dep-depinfo");
}

View File

@ -178,6 +178,7 @@ pub fn generate_std_roots(
package_set: &PackageSet<'_>,
interner: &UnitInterner,
profiles: &Profiles,
target_data: &RustcTargetData<'_>,
) -> CargoResult<HashMap<CompileKind, Vec<Unit>>> {
// Generate the root Units for the standard library.
let std_ids = crates
@ -216,6 +217,7 @@ pub fn generate_std_roots(
*kind,
mode,
features.clone(),
target_data.info(*kind).rustflags.clone(),
/*is_std*/ true,
/*dep_hash*/ 0,
IsArtifact::No,

View File

@ -14,6 +14,7 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;
/// All information needed to define a unit.
///
@ -59,6 +60,17 @@ pub struct UnitInner {
/// The `cfg` features to enable for this unit.
/// This must be sorted.
pub features: Vec<InternedString>,
/// Extra compiler flags to pass to `rustc` for a given unit.
///
/// Although it depends on the caller, in the current Cargo implementation,
/// these flags take precedence over those from [`BuildContext::extra_args_for`].
///
/// As of now, these flags come from environment variables and configurations.
/// See [`TargetInfo.rustflags`] for more on how Cargo collects them.
///
/// [`BuildContext::extra_args_for`]: crate::core::compiler::build_context::BuildContext::extra_args_for
/// [`TargetInfo.rustflags`]: crate::core::compiler::build_context::TargetInfo::rustflags
pub rustflags: Arc<[String]>,
// 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,
@ -151,6 +163,7 @@ impl fmt::Debug for Unit {
.field("kind", &self.kind)
.field("mode", &self.mode)
.field("features", &self.features)
.field("rustflags", &self.rustflags)
.field("artifact", &self.artifact.is_true())
.field(
"artifact_target_for_features",
@ -198,6 +211,7 @@ impl UnitInterner {
kind: CompileKind,
mode: CompileMode,
features: Vec<InternedString>,
rustflags: Arc<[String]>,
is_std: bool,
dep_hash: u64,
artifact: IsArtifact,
@ -231,6 +245,7 @@ impl UnitInterner {
kind,
mode,
features,
rustflags,
is_std,
dep_hash,
artifact,

View File

@ -859,6 +859,7 @@ fn new_unit_dep_with_profile(
kind,
mode,
features,
state.target_data.info(kind).rustflags.clone(),
state.is_std,
/*dep_hash*/ 0,
artifact.map_or(IsArtifact::No, |_| IsArtifact::Yes),

View File

@ -360,6 +360,7 @@ pub fn create_bcx<'a, 'gctx>(
let generator = UnitGenerator {
ws,
packages: &to_builds,
target_data: &target_data,
filter,
requested_kinds: &build_config.requested_kinds,
explicit_host_kind,
@ -399,6 +400,7 @@ pub fn create_bcx<'a, 'gctx>(
&pkg_set,
interner,
&profiles,
&target_data,
)?
} else {
Default::default()
@ -694,6 +696,7 @@ fn traverse_and_share(
to_host.unwrap(),
unit.mode,
unit.features.clone(),
unit.rustflags.clone(),
unit.is_std,
unit.dep_hash,
unit.artifact,
@ -719,6 +722,7 @@ fn traverse_and_share(
canonical_kind,
unit.mode,
unit.features.clone(),
unit.rustflags.clone(),
unit.is_std,
new_dep_hash,
unit.artifact,
@ -880,6 +884,7 @@ fn override_rustc_crate_types(
unit.kind,
unit.mode,
unit.features.clone(),
unit.rustflags.clone(),
unit.is_std,
unit.dep_hash,
unit.artifact,

View File

@ -4,8 +4,8 @@ use std::fmt::Write;
use crate::core::compiler::rustdoc::RustdocScrapeExamples;
use crate::core::compiler::unit_dependencies::IsArtifact;
use crate::core::compiler::UnitInterner;
use crate::core::compiler::{CompileKind, CompileMode, Unit};
use crate::core::compiler::{RustcTargetData, UnitInterner};
use crate::core::dependency::DepKind;
use crate::core::profiles::{Profiles, UnitFor};
use crate::core::resolver::features::{self, FeaturesFor};
@ -47,6 +47,7 @@ struct Proposal<'a> {
pub(super) struct UnitGenerator<'a, 'gctx> {
pub ws: &'a Workspace<'gctx>,
pub packages: &'a [&'a Package],
pub target_data: &'a RustcTargetData<'gctx>,
pub filter: &'a CompileFilter,
pub requested_kinds: &'a [CompileKind],
pub explicit_host_kind: CompileKind,
@ -162,13 +163,15 @@ impl<'a> UnitGenerator<'a, '_> {
unit_for,
kind,
);
let kind = kind.for_target(target);
self.interner.intern(
pkg,
target,
profile,
kind.for_target(target),
kind,
target_mode,
features.clone(),
self.target_data.info(kind).rustflags.clone(),
/*is_std*/ false,
/*dep_hash*/ 0,
IsArtifact::No,

View File

@ -1599,14 +1599,18 @@ fn target_applies_to_host_rustflags_works() {
)
.build();
// Use RUSTFLAGS to pass an argument that would generate an error
// but it is ignored.
// Use RUSTFLAGS to pass an argument that will generate an error.
p.cargo("check")
.masquerade_as_nightly_cargo(&["target-applies-to-host"])
.arg("-Ztarget-applies-to-host")
.env("CARGO_TARGET_APPLIES_TO_HOST", "false")
.env("RUSTFLAGS", r#"--cfg feature="flag""#)
.with_status(0)
.with_status(101)
.with_stderr_data(
"[CHECKING] foo v0.0.1 ([ROOT]/foo)
[ERROR] flag passed
...",
)
.run();
}