summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-08 08:29:13 +0000
committerbors <bors@rust-lang.org>2023-03-08 08:29:13 +0000
commit89ec88197af91a1a59d0666e474edaed3a6b4aca (patch)
treeb7c273771e8c129b0b9229a72c875014d731c4cb
parent3363d43574db04c805388566fc1456f9e02ad01d (diff)
parentd63eedc3a3fe078e0aa32ba5a329f10d2e63c18d (diff)
downloadrust-libc-89ec88197af91a1a59d0666e474edaed3a6b4aca.tar.gz
Auto merge of #3037 - ferrocene:pa-check-cfg, r=JohnTitor
Add support for the unstable `check-cfg` feature behind an environment variable `check-cfg` ([Rust](https://doc.rust-lang.org/stable/unstable-book/compiler-flags/check-cfg.html), [Cargo](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg)) is an unstable features that warns when you write an unknown `#[cfg]` (likely due to a typo). The feature works out of the box for default cfgs and features provided by Cargo, but requires providing the list of extra cfgs when custom ones are used. This PR adds the `LIBC_CHECK_CFG` environment variable. When enabled, the build script will use the `cargo:rustc-check-cfg` println to instruct the compiler of all the possible cfgs set by libc. The build script was also refactored to ensure all cfgs are accounted for, and a CI job using `-Z check-cfg` was added. This PR is best reviewed commit-by-commit. ## Why is this needed? The main motivation for this PR is that `rust-lang/rust` enforces `check-cfg` across the whole codebase. Normally this is not a problem for dependencies like `libc`, as Cargo caps the lints and thus doesn't show the generated warnings. When developing support for new targets though, it's helpful to use a custom libc fork to develop the libc port and the std port together. Unfortunately doing that today results in a bunch of compilation errors, since lints are not capped with `path` dependencies. My goal with this PR is to address that shortcoming, as we'd then be able to set the `LIBC_CHECK_CFG=1` environment variable in the Rust build system and remove the compilation errors. This PR might also be helpful for libc maintainers, as the CI check might spot typos in `#[cfg]`s.
-rw-r--r--.github/workflows/bors.yml17
-rw-r--r--build.rs105
2 files changed, 97 insertions, 25 deletions
diff --git a/.github/workflows/bors.yml b/.github/workflows/bors.yml
index 49a06de686..e4e342a1b3 100644
--- a/.github/workflows/bors.yml
+++ b/.github/workflows/bors.yml
@@ -317,6 +317,23 @@ jobs:
run: LIBC_CI=1 TOOLCHAIN=${{ matrix.toolchain }} WIN_TARGET=${{ matrix.target }} sh ./ci/build.sh
shell: bash
+ check_cfg:
+ permissions:
+ actions: write # to cancel workflows (rust-lang/simpleinfra/github-actions/cancel-outdated-builds)
+ contents: read # to fetch code (actions/checkout)
+
+ name: "Check #[cfg]s"
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master
+ with:
+ github_token: "${{ secrets.GITHUB_TOKEN }}"
+ - uses: actions/checkout@v3
+ - name: Setup Rust toolchain
+ run: TOOLCHAIN=nightly sh ./ci/install-rust.sh
+ - name: Build with check-cfg
+ run: LIBC_CI=1 LIBC_CHECK_CFG=1 cargo build -Z unstable-options -Z check-cfg=features,names,values,output
+
docs:
permissions:
actions: write # to cancel workflows (rust-lang/simpleinfra/github-actions/cancel-outdated-builds)
diff --git a/build.rs b/build.rs
index e97be1a6ab..e60672a761 100644
--- a/build.rs
+++ b/build.rs
@@ -2,6 +2,40 @@ use std::env;
use std::process::Command;
use std::str;
+// List of cfgs this build script is allowed to set. The list is needed to support check-cfg, as we
+// need to know all the possible cfgs that this script will set. If you need to set another cfg
+// make sure to add it to this list as well.
+const ALLOWED_CFGS: &'static [&'static str] = &[
+ "freebsd10",
+ "freebsd11",
+ "freebsd12",
+ "freebsd13",
+ "freebsd14",
+ "libc_align",
+ "libc_cfg_target_vendor",
+ "libc_const_extern_fn",
+ "libc_const_extern_fn_unstable",
+ "libc_const_size_of",
+ "libc_core_cvoid",
+ "libc_deny_warnings",
+ "libc_int128",
+ "libc_long_array",
+ "libc_non_exhaustive",
+ "libc_packedN",
+ "libc_priv_mod_use",
+ "libc_ptr_addr_of",
+ "libc_thread_local",
+ "libc_underscore_const_names",
+ "libc_union",
+];
+
+// Extra values to allow for check-cfg.
+const CHECK_CFG_EXTRA: &'static [(&'static str, &'static [&'static str])] = &[
+ ("target_os", &["switch", "aix", "ohos"]),
+ ("target_env", &["illumos", "wasi", "aix", "ohos"]),
+ ("target_arch", &["loongarch64"]),
+];
+
fn main() {
// Avoid unnecessary re-building.
println!("cargo:rerun-if-changed=build.rs");
@@ -11,6 +45,7 @@ fn main() {
let align_cargo_feature = env::var("CARGO_FEATURE_ALIGN").is_ok();
let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok();
let libc_ci = env::var("LIBC_CI").is_ok();
+ let libc_check_cfg = env::var("LIBC_CHECK_CFG").is_ok();
if env::var("CARGO_FEATURE_USE_STD").is_ok() {
println!(
@@ -25,94 +60,107 @@ fn main() {
// On CI, we detect the actual FreeBSD version and match its ABI exactly,
// running tests to ensure that the ABI is correct.
match which_freebsd() {
- Some(10) if libc_ci || rustc_dep_of_std => {
- println!("cargo:rustc-cfg=freebsd10")
- }
- Some(11) if libc_ci => println!("cargo:rustc-cfg=freebsd11"),
- Some(12) if libc_ci => println!("cargo:rustc-cfg=freebsd12"),
- Some(13) if libc_ci => println!("cargo:rustc-cfg=freebsd13"),
- Some(14) if libc_ci => println!("cargo:rustc-cfg=freebsd14"),
- Some(_) | None => println!("cargo:rustc-cfg=freebsd11"),
+ Some(10) if libc_ci || rustc_dep_of_std => set_cfg("freebsd10"),
+ Some(11) if libc_ci => set_cfg("freebsd11"),
+ Some(12) if libc_ci => set_cfg("freebsd12"),
+ Some(13) if libc_ci => set_cfg("freebsd13"),
+ Some(14) if libc_ci => set_cfg("freebsd14"),
+ Some(_) | None => set_cfg("freebsd11"),
}
// On CI: deny all warnings
if libc_ci {
- println!("cargo:rustc-cfg=libc_deny_warnings");
+ set_cfg("libc_deny_warnings");
}
// Rust >= 1.15 supports private module use:
if rustc_minor_ver >= 15 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_priv_mod_use");
+ set_cfg("libc_priv_mod_use");
}
// Rust >= 1.19 supports unions:
if rustc_minor_ver >= 19 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_union");
+ set_cfg("libc_union");
}
// Rust >= 1.24 supports const mem::size_of:
if rustc_minor_ver >= 24 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_const_size_of");
+ set_cfg("libc_const_size_of");
}
// Rust >= 1.25 supports repr(align):
if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature {
- println!("cargo:rustc-cfg=libc_align");
+ set_cfg("libc_align");
}
// Rust >= 1.26 supports i128 and u128:
if rustc_minor_ver >= 26 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_int128");
+ set_cfg("libc_int128");
}
// Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it.
// Otherwise, it defines an incompatible type to retaining
// backwards-compatibility.
if rustc_minor_ver >= 30 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_core_cvoid");
+ set_cfg("libc_core_cvoid");
}
// Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor).
if rustc_minor_ver >= 33 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_packedN");
- println!("cargo:rustc-cfg=libc_cfg_target_vendor");
+ set_cfg("libc_packedN");
+ set_cfg("libc_cfg_target_vendor");
}
// Rust >= 1.40 supports #[non_exhaustive].
if rustc_minor_ver >= 40 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_non_exhaustive");
+ set_cfg("libc_non_exhaustive");
}
// Rust >= 1.47 supports long array:
if rustc_minor_ver >= 47 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_long_array");
+ set_cfg("libc_long_array");
}
if rustc_minor_ver >= 51 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_ptr_addr_of");
+ set_cfg("libc_ptr_addr_of");
}
// Rust >= 1.37.0 allows underscores as anonymous constant names.
if rustc_minor_ver >= 37 || rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_underscore_const_names");
+ set_cfg("libc_underscore_const_names");
}
// #[thread_local] is currently unstable
if rustc_dep_of_std {
- println!("cargo:rustc-cfg=libc_thread_local");
+ set_cfg("libc_thread_local");
}
// Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C".
if rustc_minor_ver >= 62 {
- println!("cargo:rustc-cfg=libc_const_extern_fn");
+ set_cfg("libc_const_extern_fn");
} else {
// Rust < 1.62.0 requires a crate feature and feature gate.
if const_extern_fn_cargo_feature {
if !is_nightly || rustc_minor_ver < 40 {
panic!("const-extern-fn requires a nightly compiler >= 1.40");
}
- println!("cargo:rustc-cfg=libc_const_extern_fn_unstable");
- println!("cargo:rustc-cfg=libc_const_extern_fn");
+ set_cfg("libc_const_extern_fn_unstable");
+ set_cfg("libc_const_extern_fn");
+ }
+ }
+
+ // check-cfg is a nightly cargo/rustc feature to warn when unknown cfgs are used across the
+ // codebase. libc can configure it if the appropriate environment variable is passed. Since
+ // rust-lang/rust enforces it, this is useful when using a custom libc fork there.
+ //
+ // https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg
+ if libc_check_cfg {
+ for cfg in ALLOWED_CFGS {
+ println!("cargo:rustc-check-cfg=values({})", cfg);
+ }
+ for &(name, values) in CHECK_CFG_EXTRA {
+ let values = values.join("\",\"");
+ println!("cargo:rustc-check-cfg=values({},\"{}\")", name, values);
}
}
}
@@ -181,3 +229,10 @@ fn which_freebsd() -> Option<i32> {
_ => None,
}
}
+
+fn set_cfg(cfg: &str) {
+ if !ALLOWED_CFGS.contains(&cfg) {
+ panic!("trying to set cfg {}, but it is not in ALLOWED_CFGS", cfg);
+ }
+ println!("cargo:rustc-cfg={}", cfg);
+}