@@ -2,6 +2,40 @@ use std::env;
22use std:: process:: Command ;
33use std:: str;
44
5+ // List of cfgs this build script is allowed to set. The list is needed to support check-cfg, as we
6+ // need to know all the possible cfgs that this script will set. If you need to set another cfg
7+ // make sure to add it to this list as well.
8+ const ALLOWED_CFGS : & ' static [ & ' static str ] = & [
9+ "freebsd10" ,
10+ "freebsd11" ,
11+ "freebsd12" ,
12+ "freebsd13" ,
13+ "freebsd14" ,
14+ "libc_align" ,
15+ "libc_cfg_target_vendor" ,
16+ "libc_const_extern_fn" ,
17+ "libc_const_extern_fn_unstable" ,
18+ "libc_const_size_of" ,
19+ "libc_core_cvoid" ,
20+ "libc_deny_warnings" ,
21+ "libc_int128" ,
22+ "libc_long_array" ,
23+ "libc_non_exhaustive" ,
24+ "libc_packedN" ,
25+ "libc_priv_mod_use" ,
26+ "libc_ptr_addr_of" ,
27+ "libc_thread_local" ,
28+ "libc_underscore_const_names" ,
29+ "libc_union" ,
30+ ] ;
31+
32+ // Extra values to allow for check-cfg.
33+ const CHECK_CFG_EXTRA : & ' static [ ( & ' static str , & ' static [ & ' static str ] ) ] = & [
34+ ( "target_os" , & [ "switch" , "aix" , "ohos" ] ) ,
35+ ( "target_env" , & [ "illumos" , "wasi" , "aix" , "ohos" ] ) ,
36+ ( "target_arch" , & [ "loongarch64" ] ) ,
37+ ] ;
38+
539fn main ( ) {
640 // Avoid unnecessary re-building.
741 println ! ( "cargo:rerun-if-changed=build.rs" ) ;
@@ -11,6 +45,7 @@ fn main() {
1145 let align_cargo_feature = env:: var ( "CARGO_FEATURE_ALIGN" ) . is_ok ( ) ;
1246 let const_extern_fn_cargo_feature = env:: var ( "CARGO_FEATURE_CONST_EXTERN_FN" ) . is_ok ( ) ;
1347 let libc_ci = env:: var ( "LIBC_CI" ) . is_ok ( ) ;
48+ let libc_check_cfg = env:: var ( "LIBC_CHECK_CFG" ) . is_ok ( ) ;
1449
1550 if env:: var ( "CARGO_FEATURE_USE_STD" ) . is_ok ( ) {
1651 println ! (
@@ -25,89 +60,107 @@ fn main() {
2560 // On CI, we detect the actual FreeBSD version and match its ABI exactly,
2661 // running tests to ensure that the ABI is correct.
2762 match which_freebsd ( ) {
28- Some ( 10 ) if libc_ci || rustc_dep_of_std => {
29- println ! ( "cargo:rustc-cfg=freebsd10" )
30- }
31- Some ( 11 ) if libc_ci => println ! ( "cargo:rustc-cfg=freebsd11" ) ,
32- Some ( 12 ) if libc_ci => println ! ( "cargo:rustc-cfg=freebsd12" ) ,
33- Some ( 13 ) if libc_ci => println ! ( "cargo:rustc-cfg=freebsd13" ) ,
34- Some ( 14 ) if libc_ci => println ! ( "cargo:rustc-cfg=freebsd14" ) ,
35- Some ( _) | None => println ! ( "cargo:rustc-cfg=freebsd11" ) ,
63+ Some ( 10 ) if libc_ci || rustc_dep_of_std => set_cfg ( "freebsd10" ) ,
64+ Some ( 11 ) if libc_ci => set_cfg ( "freebsd11" ) ,
65+ Some ( 12 ) if libc_ci => set_cfg ( "freebsd12" ) ,
66+ Some ( 13 ) if libc_ci => set_cfg ( "freebsd13" ) ,
67+ Some ( 14 ) if libc_ci => set_cfg ( "freebsd14" ) ,
68+ Some ( _) | None => set_cfg ( "freebsd11" ) ,
3669 }
3770
3871 // On CI: deny all warnings
3972 if libc_ci {
40- println ! ( "cargo:rustc-cfg= libc_deny_warnings") ;
73+ set_cfg ( " libc_deny_warnings") ;
4174 }
4275
4376 // Rust >= 1.15 supports private module use:
4477 if rustc_minor_ver >= 15 || rustc_dep_of_std {
45- println ! ( "cargo:rustc-cfg= libc_priv_mod_use") ;
78+ set_cfg ( " libc_priv_mod_use") ;
4679 }
4780
4881 // Rust >= 1.19 supports unions:
4982 if rustc_minor_ver >= 19 || rustc_dep_of_std {
50- println ! ( "cargo:rustc-cfg= libc_union") ;
83+ set_cfg ( " libc_union") ;
5184 }
5285
5386 // Rust >= 1.24 supports const mem::size_of:
5487 if rustc_minor_ver >= 24 || rustc_dep_of_std {
55- println ! ( "cargo:rustc-cfg= libc_const_size_of") ;
88+ set_cfg ( " libc_const_size_of") ;
5689 }
5790
5891 // Rust >= 1.25 supports repr(align):
5992 if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature {
60- println ! ( "cargo:rustc-cfg= libc_align") ;
93+ set_cfg ( " libc_align") ;
6194 }
6295
6396 // Rust >= 1.26 supports i128 and u128:
6497 if rustc_minor_ver >= 26 || rustc_dep_of_std {
65- println ! ( "cargo:rustc-cfg= libc_int128") ;
98+ set_cfg ( " libc_int128") ;
6699 }
67100
68101 // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it.
69102 // Otherwise, it defines an incompatible type to retaining
70103 // backwards-compatibility.
71104 if rustc_minor_ver >= 30 || rustc_dep_of_std {
72- println ! ( "cargo:rustc-cfg= libc_core_cvoid") ;
105+ set_cfg ( " libc_core_cvoid") ;
73106 }
74107
75108 // Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor).
76109 if rustc_minor_ver >= 33 || rustc_dep_of_std {
77- println ! ( "cargo:rustc-cfg= libc_packedN") ;
78- println ! ( "cargo:rustc-cfg= libc_cfg_target_vendor") ;
110+ set_cfg ( " libc_packedN") ;
111+ set_cfg ( " libc_cfg_target_vendor") ;
79112 }
80113
81114 // Rust >= 1.40 supports #[non_exhaustive].
82115 if rustc_minor_ver >= 40 || rustc_dep_of_std {
83- println ! ( "cargo:rustc-cfg=libc_non_exhaustive" ) ;
116+ set_cfg ( "libc_non_exhaustive" ) ;
117+ }
118+
119+ // Rust >= 1.47 supports long array:
120+ if rustc_minor_ver >= 47 || rustc_dep_of_std {
121+ set_cfg ( "libc_long_array" ) ;
84122 }
85123
86124 if rustc_minor_ver >= 51 || rustc_dep_of_std {
87- println ! ( "cargo:rustc-cfg= libc_ptr_addr_of") ;
125+ set_cfg ( " libc_ptr_addr_of") ;
88126 }
89127
90128 // Rust >= 1.37.0 allows underscores as anonymous constant names.
91129 if rustc_minor_ver >= 37 || rustc_dep_of_std {
92- println ! ( "cargo:rustc-cfg= libc_underscore_const_names") ;
130+ set_cfg ( " libc_underscore_const_names") ;
93131 }
94132
95133 // #[thread_local] is currently unstable
96134 if rustc_dep_of_std {
97- println ! ( "cargo:rustc-cfg= libc_thread_local") ;
135+ set_cfg ( " libc_thread_local") ;
98136 }
99137
100138 // Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C".
101139 if rustc_minor_ver >= 62 {
102- println ! ( "cargo:rustc-cfg= libc_const_extern_fn") ;
140+ set_cfg ( " libc_const_extern_fn") ;
103141 } else {
104142 // Rust < 1.62.0 requires a crate feature and feature gate.
105143 if const_extern_fn_cargo_feature {
106144 if !is_nightly || rustc_minor_ver < 40 {
107145 panic ! ( "const-extern-fn requires a nightly compiler >= 1.40" ) ;
108146 }
109- println ! ( "cargo:rustc-cfg=libc_const_extern_fn_unstable" ) ;
110- println ! ( "cargo:rustc-cfg=libc_const_extern_fn" ) ;
147+ set_cfg ( "libc_const_extern_fn_unstable" ) ;
148+ set_cfg ( "libc_const_extern_fn" ) ;
149+ }
150+ }
151+
152+ // check-cfg is a nightly cargo/rustc feature to warn when unknown cfgs are used across the
153+ // codebase. libc can configure it if the appropriate environment variable is passed. Since
154+ // rust-lang/rust enforces it, this is useful when using a custom libc fork there.
155+ //
156+ // https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg
157+ if libc_check_cfg {
158+ for cfg in ALLOWED_CFGS {
159+ println ! ( "cargo:rustc-check-cfg=values({})" , cfg) ;
160+ }
161+ for & ( name, values) in CHECK_CFG_EXTRA {
162+ let values = values. join ( "\" ,\" " ) ;
163+ println ! ( "cargo:rustc-check-cfg=values({},\" {}\" )" , name, values) ;
111164 }
112165 }
113166}
@@ -176,3 +229,10 @@ fn which_freebsd() -> Option<i32> {
176229 _ => None ,
177230 }
178231}
232+
233+ fn set_cfg ( cfg : & str ) {
234+ if !ALLOWED_CFGS . contains ( & cfg) {
235+ panic ! ( "trying to set cfg {}, but it is not in ALLOWED_CFGS" , cfg) ;
236+ }
237+ println ! ( "cargo:rustc-cfg={}" , cfg) ;
238+ }
0 commit comments