@@ -2,6 +2,40 @@ use std::env;
2
2
use std:: process:: Command ;
3
3
use std:: str;
4
4
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
+
5
39
fn main ( ) {
6
40
// Avoid unnecessary re-building.
7
41
println ! ( "cargo:rerun-if-changed=build.rs" ) ;
@@ -11,6 +45,7 @@ fn main() {
11
45
let align_cargo_feature = env:: var ( "CARGO_FEATURE_ALIGN" ) . is_ok ( ) ;
12
46
let const_extern_fn_cargo_feature = env:: var ( "CARGO_FEATURE_CONST_EXTERN_FN" ) . is_ok ( ) ;
13
47
let libc_ci = env:: var ( "LIBC_CI" ) . is_ok ( ) ;
48
+ let libc_check_cfg = env:: var ( "LIBC_CHECK_CFG" ) . is_ok ( ) ;
14
49
15
50
if env:: var ( "CARGO_FEATURE_USE_STD" ) . is_ok ( ) {
16
51
println ! (
@@ -25,89 +60,107 @@ fn main() {
25
60
// On CI, we detect the actual FreeBSD version and match its ABI exactly,
26
61
// running tests to ensure that the ABI is correct.
27
62
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" ) ,
36
69
}
37
70
38
71
// On CI: deny all warnings
39
72
if libc_ci {
40
- println ! ( "cargo:rustc-cfg= libc_deny_warnings") ;
73
+ set_cfg ( " libc_deny_warnings") ;
41
74
}
42
75
43
76
// Rust >= 1.15 supports private module use:
44
77
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") ;
46
79
}
47
80
48
81
// Rust >= 1.19 supports unions:
49
82
if rustc_minor_ver >= 19 || rustc_dep_of_std {
50
- println ! ( "cargo:rustc-cfg= libc_union") ;
83
+ set_cfg ( " libc_union") ;
51
84
}
52
85
53
86
// Rust >= 1.24 supports const mem::size_of:
54
87
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") ;
56
89
}
57
90
58
91
// Rust >= 1.25 supports repr(align):
59
92
if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature {
60
- println ! ( "cargo:rustc-cfg= libc_align") ;
93
+ set_cfg ( " libc_align") ;
61
94
}
62
95
63
96
// Rust >= 1.26 supports i128 and u128:
64
97
if rustc_minor_ver >= 26 || rustc_dep_of_std {
65
- println ! ( "cargo:rustc-cfg= libc_int128") ;
98
+ set_cfg ( " libc_int128") ;
66
99
}
67
100
68
101
// Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it.
69
102
// Otherwise, it defines an incompatible type to retaining
70
103
// backwards-compatibility.
71
104
if rustc_minor_ver >= 30 || rustc_dep_of_std {
72
- println ! ( "cargo:rustc-cfg= libc_core_cvoid") ;
105
+ set_cfg ( " libc_core_cvoid") ;
73
106
}
74
107
75
108
// Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor).
76
109
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") ;
79
112
}
80
113
81
114
// Rust >= 1.40 supports #[non_exhaustive].
82
115
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" ) ;
84
122
}
85
123
86
124
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") ;
88
126
}
89
127
90
128
// Rust >= 1.37.0 allows underscores as anonymous constant names.
91
129
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") ;
93
131
}
94
132
95
133
// #[thread_local] is currently unstable
96
134
if rustc_dep_of_std {
97
- println ! ( "cargo:rustc-cfg= libc_thread_local") ;
135
+ set_cfg ( " libc_thread_local") ;
98
136
}
99
137
100
138
// Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C".
101
139
if rustc_minor_ver >= 62 {
102
- println ! ( "cargo:rustc-cfg= libc_const_extern_fn") ;
140
+ set_cfg ( " libc_const_extern_fn") ;
103
141
} else {
104
142
// Rust < 1.62.0 requires a crate feature and feature gate.
105
143
if const_extern_fn_cargo_feature {
106
144
if !is_nightly || rustc_minor_ver < 40 {
107
145
panic ! ( "const-extern-fn requires a nightly compiler >= 1.40" ) ;
108
146
}
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) ;
111
164
}
112
165
}
113
166
}
@@ -176,3 +229,10 @@ fn which_freebsd() -> Option<i32> {
176
229
_ => None ,
177
230
}
178
231
}
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