Skip to content

Commit

Permalink
Pass rustflags to artifacts built with implicit targets when using ta…
Browse files Browse the repository at this point in the history
…rget-applies-to-host
  • Loading branch information
gmorenz committed Jul 1, 2024
1 parent 741cf19 commit 57af9d0
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 34 deletions.
13 changes: 0 additions & 13 deletions src/cargo/core/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
31 changes: 25 additions & 6 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
5 changes: 1 addition & 4 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
6 changes: 3 additions & 3 deletions src/cargo/core/compiler/fingerprint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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| {
Expand Down Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
2 changes: 2 additions & 0 deletions src/cargo/core/compiler/standard_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 15 additions & 0 deletions src/cargo/core/compiler/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -198,6 +211,7 @@ impl UnitInterner {
kind: CompileKind,
mode: CompileMode,
features: Vec<InternedString>,
rustflags: Arc<[String]>,
is_std: bool,
dep_hash: u64,
artifact: IsArtifact,
Expand Down Expand Up @@ -231,6 +245,7 @@ impl UnitInterner {
kind,
mode,
features,
rustflags,
is_std,
dep_hash,
artifact,
Expand Down
1 change: 1 addition & 0 deletions src/cargo/core/compiler/unit_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
5 changes: 5 additions & 0 deletions src/cargo/ops/cargo_compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -399,6 +400,7 @@ pub fn create_bcx<'a, 'gctx>(
&pkg_set,
interner,
&profiles,
&target_data,
)?
} else {
Default::default()
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 5 additions & 2 deletions src/cargo/ops/cargo_compile/unit_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 10 additions & 5 deletions tests/testsuite/rustflags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1587,20 +1587,25 @@ fn host_config_rustflags_with_target() {
.arg("host.rustflags=[\"--cfg=foo\"]")
.run();
}

#[cargo_test]
fn target_applies_to_host_rustflags_works() {
// Ensures that rustflags are passed to the target when
// target_applies_to_host=false
let p = project().file("src/lib.rs", "").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", "-Z bogus")
.with_status(0)
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] failed to run `rustc` to learn about target-specific information
Caused by:
[..]bogus[..]
...
"#]])
.run();
}
}

0 comments on commit 57af9d0

Please # to comment.