Skip to content

Commit d16631f

Browse files
committed
Add support for cargo:rustc-check-cfg in build script
1 parent 9c61a3d commit d16631f

File tree

5 files changed

+74
-6
lines changed

5 files changed

+74
-6
lines changed

src/cargo/core/compiler/context/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
235235
args.push(cfg.into());
236236
}
237237

238+
if !output.check_cfgs.is_empty() {
239+
args.push("-Zunstable-options".into());
240+
for check_cfg in &output.check_cfgs {
241+
args.push("--check-cfg".into());
242+
args.push(check_cfg.into());
243+
}
244+
}
245+
238246
for (lt, arg) in &output.linker_args {
239247
if lt.applies_to(&unit.target) {
240248
args.push("-C".into());

src/cargo/core/compiler/custom_build.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub struct BuildOutput {
2929
pub linker_args: Vec<(LinkType, String)>,
3030
/// Various `--cfg` flags to pass to the compiler.
3131
pub cfgs: Vec<String>,
32+
/// Various `--check-cfg` flags to pass to the compiler.
33+
pub check_cfgs: Vec<String>,
3234
/// Additional environment variables to run the compiler with.
3335
pub env: Vec<(String, String)>,
3436
/// Metadata to pass to the immediate dependencies.
@@ -322,6 +324,10 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
322324
paths::create_dir_all(&script_out_dir)?;
323325

324326
let nightly_features_allowed = cx.bcx.config.nightly_features_allowed;
327+
let extra_check_cfg = match cx.bcx.config.cli_unstable().check_cfg {
328+
Some((_, _, _, output)) => output,
329+
None => false,
330+
};
325331
let targets: Vec<Target> = unit.pkg.targets().to_vec();
326332
// Need a separate copy for the fresh closure.
327333
let targets_fresh = targets.clone();
@@ -432,6 +438,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
432438
&pkg_descr,
433439
&script_out_dir,
434440
&script_out_dir,
441+
extra_check_cfg,
435442
nightly_features_allowed,
436443
&targets,
437444
)?;
@@ -459,6 +466,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
459466
&pkg_descr,
460467
&prev_script_out_dir,
461468
&script_out_dir,
469+
extra_check_cfg,
462470
nightly_features_allowed,
463471
&targets_fresh,
464472
)?,
@@ -511,6 +519,7 @@ impl BuildOutput {
511519
pkg_descr: &str,
512520
script_out_dir_when_generated: &Path,
513521
script_out_dir: &Path,
522+
extra_check_cfg: bool,
514523
nightly_features_allowed: bool,
515524
targets: &[Target],
516525
) -> CargoResult<BuildOutput> {
@@ -521,6 +530,7 @@ impl BuildOutput {
521530
pkg_descr,
522531
script_out_dir_when_generated,
523532
script_out_dir,
533+
extra_check_cfg,
524534
nightly_features_allowed,
525535
targets,
526536
)
@@ -536,13 +546,15 @@ impl BuildOutput {
536546
pkg_descr: &str,
537547
script_out_dir_when_generated: &Path,
538548
script_out_dir: &Path,
549+
extra_check_cfg: bool,
539550
nightly_features_allowed: bool,
540551
targets: &[Target],
541552
) -> CargoResult<BuildOutput> {
542553
let mut library_paths = Vec::new();
543554
let mut library_links = Vec::new();
544555
let mut linker_args = Vec::new();
545556
let mut cfgs = Vec::new();
557+
let mut check_cfgs = Vec::new();
546558
let mut env = Vec::new();
547559
let mut metadata = Vec::new();
548560
let mut rerun_if_changed = Vec::new();
@@ -669,6 +681,13 @@ impl BuildOutput {
669681
linker_args.push((LinkType::All, value));
670682
}
671683
"rustc-cfg" => cfgs.push(value.to_string()),
684+
"rustc-check-cfg" => {
685+
if extra_check_cfg {
686+
check_cfgs.push(value.to_string());
687+
} else {
688+
warnings.push(format!("cargo:{} requires -Zcheck-cfg=output flag", key));
689+
}
690+
}
672691
"rustc-env" => {
673692
let (key, val) = BuildOutput::parse_rustc_env(&value, &whence)?;
674693
// Build scripts aren't allowed to set RUSTC_BOOTSTRAP.
@@ -728,6 +747,7 @@ impl BuildOutput {
728747
library_links,
729748
linker_args,
730749
cfgs,
750+
check_cfgs,
731751
env,
732752
metadata,
733753
rerun_if_changed,
@@ -968,6 +988,10 @@ fn prev_build_output(cx: &mut Context<'_, '_>, unit: &Unit) -> (Option<BuildOutp
968988
&unit.pkg.to_string(),
969989
&prev_script_out_dir,
970990
&script_out_dir,
991+
match cx.bcx.config.cli_unstable().check_cfg {
992+
Some((_, _, _, output)) => output,
993+
None => false,
994+
},
971995
cx.bcx.config.nightly_features_allowed,
972996
unit.pkg.targets(),
973997
)

src/cargo/core/compiler/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,12 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
411411
for cfg in &output.cfgs {
412412
rustc.arg("--cfg").arg(cfg);
413413
}
414+
if !output.check_cfgs.is_empty() {
415+
rustc.arg("-Zunstable-options");
416+
for check_cfg in &output.check_cfgs {
417+
rustc.arg("--check-cfg").arg(check_cfg);
418+
}
419+
}
414420
if pass_l_flag {
415421
for name in output.library_links.iter() {
416422
rustc.arg("-l").arg(name);
@@ -718,6 +724,12 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
718724
for cfg in output.cfgs.iter() {
719725
rustdoc.arg("--cfg").arg(cfg);
720726
}
727+
if !output.check_cfgs.is_empty() {
728+
rustdoc.arg("-Zunstable-options");
729+
for check_cfg in &output.check_cfgs {
730+
rustdoc.arg("--check-cfg").arg(check_cfg);
731+
}
732+
}
721733
for &(ref name, ref value) in output.env.iter() {
722734
rustdoc.env(name, value);
723735
}
@@ -1055,7 +1067,7 @@ fn features_args(unit: &Unit) -> Vec<OsString> {
10551067

10561068
/// Generate the --check-cfg arguments for the unit
10571069
fn check_cfg_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
1058-
if let Some((features, well_known_names, well_known_values)) =
1070+
if let Some((features, well_known_names, well_known_values, _output)) =
10591071
cx.bcx.config.cli_unstable().check_cfg
10601072
{
10611073
let mut args = Vec::with_capacity(unit.pkg.summary().features().len() * 2 + 4);

src/cargo/core/features.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ unstable_cli_options!(
641641
build_std_features: Option<Vec<String>> = ("Configure features enabled for the standard library itself when building the standard library"),
642642
config_include: bool = ("Enable the `include` key in config files"),
643643
credential_process: bool = ("Add a config setting to fetch registry authentication tokens by calling an external process"),
644-
check_cfg: Option<(/*features:*/ bool, /*well_known_names:*/ bool, /*well_known_values:*/ bool)> = ("Specify scope of compile-time checking of `cfg` names/values"),
644+
check_cfg: Option<(/*features:*/ bool, /*well_known_names:*/ bool, /*well_known_values:*/ bool, /*output:*/ bool)> = ("Specify scope of compile-time checking of `cfg` names/values"),
645645
doctest_in_workspace: bool = ("Compile doctests with paths relative to the workspace root"),
646646
doctest_xcompile: bool = ("Compile and run doctests for non-host target using runner config"),
647647
dual_proc_macros: bool = ("Build proc-macros for both the host and the target"),
@@ -783,22 +783,29 @@ impl CliUnstable {
783783
}
784784
}
785785

786-
fn parse_check_cfg(value: Option<&str>) -> CargoResult<Option<(bool, bool, bool)>> {
786+
fn parse_check_cfg(value: Option<&str>) -> CargoResult<Option<(bool, bool, bool, bool)>> {
787787
if let Some(value) = value {
788788
let mut features = false;
789789
let mut well_known_names = false;
790790
let mut well_known_values = false;
791+
let mut output = false;
791792

792793
for e in value.split(',') {
793794
match e {
794795
"features" => features = true,
795796
"names" => well_known_names = true,
796797
"values" => well_known_values = true,
797-
_ => bail!("flag -Zcheck-cfg only takes `features`, `names` or `values` as valid inputs"),
798+
"output" => output = true,
799+
_ => bail!("flag -Zcheck-cfg only takes `features`, `names`, `values` or `output` as valid inputs"),
798800
}
799801
}
800802

801-
Ok(Some((features, well_known_names, well_known_values)))
803+
Ok(Some((
804+
features,
805+
well_known_names,
806+
well_known_values,
807+
output,
808+
)))
802809
} else {
803810
Ok(None)
804811
}

src/cargo/util/config/target.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ fn load_config_table(config: &Config, prefix: &str) -> CargoResult<TargetConfig>
120120
// Links do not support environment variables.
121121
let target_key = ConfigKey::from_str(prefix);
122122
let links_overrides = match config.get_table(&target_key)? {
123-
Some(links) => parse_links_overrides(&target_key, links.val)?,
123+
Some(links) => parse_links_overrides(&target_key, links.val, config)?,
124124
None => BTreeMap::new(),
125125
};
126126
Ok(TargetConfig {
@@ -134,8 +134,14 @@ fn load_config_table(config: &Config, prefix: &str) -> CargoResult<TargetConfig>
134134
fn parse_links_overrides(
135135
target_key: &ConfigKey,
136136
links: HashMap<String, CV>,
137+
config: &Config,
137138
) -> CargoResult<BTreeMap<String, BuildOutput>> {
138139
let mut links_overrides = BTreeMap::new();
140+
let extra_check_cfg = match config.cli_unstable().check_cfg {
141+
Some((_, _, _, output)) => output,
142+
None => false,
143+
};
144+
139145
for (lib_name, value) in links {
140146
// Skip these keys, it shares the namespace with `TargetConfig`.
141147
match lib_name.as_str() {
@@ -200,6 +206,17 @@ fn parse_links_overrides(
200206
let list = value.list(key)?;
201207
output.cfgs.extend(list.iter().map(|v| v.0.clone()));
202208
}
209+
"rustc-check-cfg" => {
210+
if extra_check_cfg {
211+
let list = value.list(key)?;
212+
output.check_cfgs.extend(list.iter().map(|v| v.0.clone()));
213+
} else {
214+
config.shell().warn(format!(
215+
"target config `{}.{}` requires -Zcheck-cfg=output flag",
216+
target_key, key
217+
))?;
218+
}
219+
}
203220
"rustc-env" => {
204221
for (name, val) in value.table(key)?.0 {
205222
let val = val.string(name)?.0;

0 commit comments

Comments
 (0)