6
6
//!
7
7
//! Reference: <https://doc.rust-lang.org/stable/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts>
8
8
9
- use std:: env:: var_os;
10
9
use std:: path:: PathBuf ;
11
10
12
11
use crate :: ident:: { is_ascii_ident, is_crate_name, is_feature_name} ;
12
+ use crate :: output:: rerun_if_env_changed;
13
+
14
+ /// [`ProcessEnv`] wrapper that implicit calls [`rerun_if_env_changed`]
15
+ const ENV : RerunIfEnvChanged < ProcessEnv > = RerunIfEnvChanged :: new ( ) ;
16
+
17
+ /// Abstraction over environment variables
18
+ trait Env {
19
+ /// Fetches the environment variable `key`, returning `None` if the variable isn’t set or if
20
+ /// there is another error.
21
+ ///
22
+ /// It may return `None` if the environment variable’s name contains the equal sign character
23
+ /// (`=`) or the NUL character.
24
+ ///
25
+ /// Note that this function will not check if the environment variable is valid Unicode.
26
+ fn get ( & self , key : & str ) -> Option < std:: ffi:: OsString > ;
27
+
28
+ /// Checks the environment variable `key` is present
29
+ ///
30
+ /// It may not be considered present if the environment variable’s name contains the equal sign character
31
+ /// (`=`) or the NUL character.
32
+ fn is_present ( & self , key : & str ) -> bool ;
33
+ }
34
+
35
+ /// Fetches environment variables from the current process
36
+ struct ProcessEnv ;
37
+
38
+ impl Env for ProcessEnv {
39
+ fn get ( & self , key : & str ) -> Option < std:: ffi:: OsString > {
40
+ std:: env:: var_os ( key)
41
+ }
42
+
43
+ fn is_present ( & self , key : & str ) -> bool {
44
+ self . get ( key) . is_some ( )
45
+ }
46
+ }
47
+
48
+ /// [`Env`] wrapper that implicitly calls [`rerun_if_env_changed`]
49
+ struct RerunIfEnvChanged < E : Env > ( E ) ;
50
+
51
+ impl RerunIfEnvChanged < ProcessEnv > {
52
+ const fn new ( ) -> Self {
53
+ Self ( ProcessEnv )
54
+ }
55
+ }
56
+
57
+ impl < E : Env > Env for RerunIfEnvChanged < E > {
58
+ #[ track_caller]
59
+ fn get ( & self , key : & str ) -> Option < std:: ffi:: OsString > {
60
+ rerun_if_env_changed ( key) ;
61
+ self . 0 . get ( key)
62
+ }
63
+
64
+ #[ track_caller]
65
+ fn is_present ( & self , key : & str ) -> bool {
66
+ self . get ( key) . is_some ( )
67
+ }
68
+ }
13
69
14
70
/// Path to the `cargo` binary performing the build.
15
71
#[ track_caller]
@@ -30,7 +86,7 @@ pub fn cargo_manifest_dir() -> PathBuf {
30
86
/// The path to the manifest of your package.
31
87
#[ track_caller]
32
88
pub fn cargo_manifest_path ( ) -> PathBuf {
33
- var_os ( "CARGO_MANIFEST_PATH" )
89
+ ENV . get ( "CARGO_MANIFEST_PATH" )
34
90
. map ( to_path)
35
91
. unwrap_or_else ( || {
36
92
let mut path = cargo_manifest_dir ( ) ;
@@ -42,7 +98,7 @@ pub fn cargo_manifest_path() -> PathBuf {
42
98
/// The manifest `links` value.
43
99
#[ track_caller]
44
100
pub fn cargo_manifest_links ( ) -> Option < String > {
45
- var_os ( "CARGO_MANIFEST_LINKS" ) . map ( to_string)
101
+ ENV . get ( "CARGO_MANIFEST_LINKS" ) . map ( to_string)
46
102
}
47
103
48
104
/// Contains parameters needed for Cargo’s [jobserver] implementation to parallelize
@@ -57,7 +113,7 @@ pub fn cargo_manifest_links() -> Option<String> {
57
113
/// [jobserver]: https://www.gnu.org/software/make/manual/html_node/Job-Slots.html
58
114
#[ track_caller]
59
115
pub fn cargo_makeflags ( ) -> Option < String > {
60
- var_os ( "CARGO_MAKEFLAGS" ) . map ( to_string)
116
+ ENV . get ( "CARGO_MAKEFLAGS" ) . map ( to_string)
61
117
}
62
118
63
119
/// For each activated feature of the package being built, this will be `true`.
@@ -68,7 +124,7 @@ pub fn cargo_feature(name: &str) -> bool {
68
124
}
69
125
let name = name. to_uppercase ( ) . replace ( '-' , "_" ) ;
70
126
let key = format ! ( "CARGO_FEATURE_{name}" ) ;
71
- is_present ( & key)
127
+ ENV . is_present ( & key)
72
128
}
73
129
74
130
/// For each [configuration option] of the package being built, this will contain
@@ -82,7 +138,7 @@ pub fn cargo_feature(name: &str) -> bool {
82
138
#[ track_caller]
83
139
pub fn cargo_cfg ( cfg : & str ) -> Option < Vec < String > > {
84
140
let var = cargo_cfg_var ( cfg) ;
85
- var_os ( & var) . map ( |v| to_strings ( v, ',' ) )
141
+ ENV . get ( & var) . map ( |v| to_strings ( v, ',' ) )
86
142
}
87
143
88
144
#[ track_caller]
@@ -112,7 +168,7 @@ mod cfg {
112
168
#[ cfg( any( ) ) ]
113
169
#[ track_caller]
114
170
pub fn cargo_cfg_clippy ( ) -> bool {
115
- is_present ( "CARGO_CFG_CLIPPY" )
171
+ ENV . is_present ( "CARGO_CFG_CLIPPY" )
116
172
}
117
173
118
174
/// If we are compiling with debug assertions enabled.
@@ -123,25 +179,25 @@ mod cfg {
123
179
#[ cfg( any( ) ) ]
124
180
#[ track_caller]
125
181
pub fn cargo_cfg_debug_assertions ( ) -> bool {
126
- is_present ( "CARGO_CFG_DEBUG_ASSERTIONS" )
182
+ ENV . is_present ( "CARGO_CFG_DEBUG_ASSERTIONS" )
127
183
}
128
184
129
185
#[ cfg( any( ) ) ]
130
186
#[ track_caller]
131
187
pub fn cargo_cfg_doc ( ) -> bool {
132
- is_present ( "CARGO_CFG_DOC" )
188
+ ENV . is_present ( "CARGO_CFG_DOC" )
133
189
}
134
190
135
191
#[ cfg( any( ) ) ]
136
192
#[ track_caller]
137
193
pub fn cargo_cfg_docsrs ( ) -> bool {
138
- is_present ( "CARGO_CFG_DOCSRS" )
194
+ ENV . is_present ( "CARGO_CFG_DOCSRS" )
139
195
}
140
196
141
197
#[ cfg( any( ) ) ]
142
198
#[ track_caller]
143
199
pub fn cargo_cfg_doctest ( ) -> bool {
144
- is_present ( "CARGO_CFG_DOCTEST" )
200
+ ENV . is_present ( "CARGO_CFG_DOCTEST" )
145
201
}
146
202
147
203
/// The level of detail provided by derived [`Debug`] implementations.
@@ -155,15 +211,15 @@ mod cfg {
155
211
#[ cfg( any( ) ) ]
156
212
#[ track_caller]
157
213
pub fn cargo_cfg_miri ( ) -> bool {
158
- is_present ( "CARGO_CFG_MIRI" )
214
+ ENV . is_present ( "CARGO_CFG_MIRI" )
159
215
}
160
216
161
217
/// If we are compiling with overflow checks enabled.
162
218
#[ doc = unstable ! ( cfg_overflow_checks, 111466 ) ]
163
219
#[ cfg( feature = "unstable" ) ]
164
220
#[ track_caller]
165
221
pub fn cargo_cfg_overflow_checks ( ) -> bool {
166
- is_present ( "CARGO_CFG_OVERFLOW_CHECKS" )
222
+ ENV . is_present ( "CARGO_CFG_OVERFLOW_CHECKS" )
167
223
}
168
224
169
225
/// The [panic strategy](https://doc.rust-lang.org/stable/reference/conditional-compilation.html#panic).
@@ -175,7 +231,7 @@ mod cfg {
175
231
/// If the crate is being compiled as a procedural macro.
176
232
#[ track_caller]
177
233
pub fn cargo_cfg_proc_macro ( ) -> bool {
178
- is_present ( "CARGO_CFG_PROC_MACRO" )
234
+ ENV . is_present ( "CARGO_CFG_PROC_MACRO" )
179
235
}
180
236
181
237
/// The target relocation model.
@@ -189,31 +245,31 @@ mod cfg {
189
245
#[ cfg( any( ) ) ]
190
246
#[ track_caller]
191
247
pub fn cargo_cfg_rustfmt ( ) -> bool {
192
- is_present ( "CARGO_CFG_RUSTFMT" )
248
+ ENV . is_present ( "CARGO_CFG_RUSTFMT" )
193
249
}
194
250
195
251
/// Sanitizers enabled for the crate being compiled.
196
252
#[ doc = unstable ! ( cfg_sanitize, 39699 ) ]
197
253
#[ cfg( feature = "unstable" ) ]
198
254
#[ track_caller]
199
255
pub fn cargo_cfg_sanitize ( ) -> Option < Vec < String > > {
200
- var_os ( "CARGO_CFG_SANITIZE" ) . map ( |v| to_strings ( v, ',' ) )
256
+ ENV . get ( "CARGO_CFG_SANITIZE" ) . map ( |v| to_strings ( v, ',' ) )
201
257
}
202
258
203
259
/// If CFI sanitization is generalizing pointers.
204
260
#[ doc = unstable ! ( cfg_sanitizer_cfi, 89653 ) ]
205
261
#[ cfg( feature = "unstable" ) ]
206
262
#[ track_caller]
207
263
pub fn cargo_cfg_sanitizer_cfi_generalize_pointers ( ) -> bool {
208
- is_present ( "CARGO_CFG_SANITIZER_CFI_GENERALIZE_POINTERS" )
264
+ ENV . is_present ( "CARGO_CFG_SANITIZER_CFI_GENERALIZE_POINTERS" )
209
265
}
210
266
211
267
/// If CFI sanitization is normalizing integers.
212
268
#[ doc = unstable ! ( cfg_sanitizer_cfi, 89653 ) ]
213
269
#[ cfg( feature = "unstable" ) ]
214
270
#[ track_caller]
215
271
pub fn cargo_cfg_sanitizer_cfi_normalize_integers ( ) -> bool {
216
- is_present ( "CARGO_CFG_SANITIZER_CFI_NORMALIZE_INTEGERS" )
272
+ ENV . is_present ( "CARGO_CFG_SANITIZER_CFI_NORMALIZE_INTEGERS" )
217
273
}
218
274
219
275
/// Disambiguation of the [target ABI](https://doc.rust-lang.org/stable/reference/conditional-compilation.html#target_abi)
@@ -309,7 +365,7 @@ mod cfg {
309
365
#[ cfg( feature = "unstable" ) ]
310
366
#[ track_caller]
311
367
pub fn cargo_cfg_target_thread_local ( ) -> bool {
312
- is_present ( "CARGO_CFG_TARGET_THREAD_LOCAL" )
368
+ ENV . is_present ( "CARGO_CFG_TARGET_THREAD_LOCAL" )
313
369
}
314
370
315
371
/// The [target vendor](https://doc.rust-lang.org/stable/reference/conditional-compilation.html#target_vendor).
@@ -321,27 +377,27 @@ mod cfg {
321
377
#[ cfg( any( ) ) ]
322
378
#[ track_caller]
323
379
pub fn cargo_cfg_test ( ) -> bool {
324
- is_present ( "CARGO_CFG_TEST" )
380
+ ENV . is_present ( "CARGO_CFG_TEST" )
325
381
}
326
382
327
383
/// If we are compiling with UB checks enabled.
328
384
#[ doc = unstable ! ( cfg_ub_checks, 123499 ) ]
329
385
#[ cfg( feature = "unstable" ) ]
330
386
#[ track_caller]
331
387
pub fn cargo_cfg_ub_checks ( ) -> bool {
332
- is_present ( "CARGO_CFG_UB_CHECKS" )
388
+ ENV . is_present ( "CARGO_CFG_UB_CHECKS" )
333
389
}
334
390
335
391
/// Set on [unix-like platforms](https://doc.rust-lang.org/stable/reference/conditional-compilation.html#unix-and-windows).
336
392
#[ track_caller]
337
393
pub fn cargo_cfg_unix ( ) -> bool {
338
- is_present ( "CARGO_CFG_UNIX" )
394
+ ENV . is_present ( "CARGO_CFG_UNIX" )
339
395
}
340
396
341
397
/// Set on [windows-like platforms](https://doc.rust-lang.org/stable/reference/conditional-compilation.html#unix-and-windows).
342
398
#[ track_caller]
343
399
pub fn cargo_cfg_windows ( ) -> bool {
344
- is_present ( "CARGO_CFG_WINDOWS" )
400
+ ENV . is_present ( "CARGO_CFG_WINDOWS" )
345
401
}
346
402
}
347
403
@@ -428,7 +484,7 @@ pub fn dep_metadata(name: &str, key: &str) -> Option<String> {
428
484
let name = name. to_uppercase ( ) . replace ( '-' , "_" ) ;
429
485
let key = key. to_uppercase ( ) . replace ( '-' , "_" ) ;
430
486
let key = format ! ( "DEP_{name}_{key}" ) ;
431
- var_os ( & key) . map ( to_string)
487
+ ENV . get ( & key) . map ( to_string)
432
488
}
433
489
434
490
/// The compiler that Cargo has resolved to use.
@@ -448,7 +504,7 @@ pub fn rustdoc() -> PathBuf {
448
504
/// [`build.rustc-wrapper`]: https://doc.rust-lang.org/stable/cargo/reference/config.html#buildrustc-wrapper
449
505
#[ track_caller]
450
506
pub fn rustc_wrapper ( ) -> Option < PathBuf > {
451
- var_os ( "RUSTC_WRAPPER" ) . map ( to_path)
507
+ ENV . get ( "RUSTC_WRAPPER" ) . map ( to_path)
452
508
}
453
509
454
510
/// The rustc wrapper, if any, that Cargo is using for workspace members. See
@@ -457,15 +513,15 @@ pub fn rustc_wrapper() -> Option<PathBuf> {
457
513
/// [`build.rustc-workspace-wrapper`]: https://doc.rust-lang.org/stable/cargo/reference/config.html#buildrustc-workspace-wrapper
458
514
#[ track_caller]
459
515
pub fn rustc_workspace_wrapper ( ) -> Option < PathBuf > {
460
- var_os ( "RUSTC_WORKSPACE_WRAPPER" ) . map ( to_path)
516
+ ENV . get ( "RUSTC_WORKSPACE_WRAPPER" ) . map ( to_path)
461
517
}
462
518
463
519
/// The linker that Cargo has resolved to use for the current target, if specified.
464
520
///
465
521
/// [`target.*.linker`]: https://doc.rust-lang.org/stable/cargo/reference/config.html#targettriplelinker
466
522
#[ track_caller]
467
523
pub fn rustc_linker ( ) -> Option < PathBuf > {
468
- var_os ( "RUSTC_LINKER" ) . map ( to_path)
524
+ ENV . get ( "RUSTC_LINKER" ) . map ( to_path)
469
525
}
470
526
471
527
/// Extra flags that Cargo invokes rustc with. See [`build.rustflags`].
@@ -561,13 +617,10 @@ pub fn cargo_pkg_readme() -> Option<PathBuf> {
561
617
to_opt ( var_or_panic ( "CARGO_PKG_README" ) ) . map ( to_path)
562
618
}
563
619
564
- fn is_present ( key : & str ) -> bool {
565
- var_os ( key) . is_some ( )
566
- }
567
-
568
620
#[ track_caller]
569
621
fn var_or_panic ( key : & str ) -> std:: ffi:: OsString {
570
- var_os ( key) . unwrap_or_else ( || panic ! ( "cargo environment variable `{key}` is missing" ) )
622
+ ENV . get ( key)
623
+ . unwrap_or_else ( || panic ! ( "cargo environment variable `{key}` is missing" ) )
571
624
}
572
625
573
626
fn to_path ( value : std:: ffi:: OsString ) -> PathBuf {
0 commit comments