@@ -70,7 +70,7 @@ pub struct Source {
7070 items : HashMap < String , Vec < ( syn:: Item , SourceLocation ) > > ,
7171 // Configuration needed to build a CfgFilter at iteration time
7272 features_constant : Option < String > ,
73- target_triple_env_var : Option < String > ,
73+ target_triple : Option < String > ,
7474 features_list : Vec < String > , // normalized list from features.txt
7575}
7676
@@ -95,7 +95,7 @@ impl Source {
9595 fn build_internal (
9696 input_dir : & Path ,
9797 features_constant : Option < String > ,
98- target_triple_env_var : Option < String > ,
98+ target_triple : Option < String > ,
9999 ) -> Self {
100100 if let Some ( source) = DOCTEST_SOURCE . with ( |source| ( * source. borrow ( ) ) . clone ( ) ) {
101101 return source;
@@ -130,7 +130,7 @@ impl Source {
130130 items,
131131 features_constant,
132132 features_list,
133- target_triple_env_var ,
133+ target_triple ,
134134 }
135135 }
136136
@@ -164,7 +164,7 @@ impl Source {
164164 ) ,
165165 ] ) ,
166166 features_constant : None ,
167- target_triple_env_var : None ,
167+ target_triple : None ,
168168 features_list : Vec :: new ( ) ,
169169 } ;
170170 DOCTEST_SOURCE . with ( |cell| {
@@ -282,20 +282,9 @@ impl Source {
282282 . join ( " " ) ;
283283 builder = builder. predefined_features ( qualified_const, features_list) ;
284284 }
285- if let Some ( env_var) = & self . target_triple_env_var {
286- let target = std:: env:: var ( env_var) . unwrap_or_else ( |_| {
287- panic ! (
288- "Environment variable {} is not set. \
289- Ensure that the build script sets it to the target triple.",
290- env_var
291- )
292- } ) ;
293- let target_triple = TargetTriple :: parse ( & target) . unwrap_or_else ( |e| {
294- panic ! (
295- "Failed to parse target triple '{}' from environment variable {}: {}" ,
296- target, env_var, e
297- )
298- } ) ;
285+ if let Some ( target) = & self . target_triple {
286+ let target_triple = TargetTriple :: parse ( target)
287+ . unwrap_or_else ( |e| panic ! ( "Failed to parse target triple '{}': {}" , target, e) ) ;
299288 builder = builder
300289 . enable_target_arch ( target_triple. arch ( ) )
301290 . enable_target_os ( target_triple. os ( ) )
@@ -400,15 +389,16 @@ fn read_features_from_out_dir(input_dir: &Path) -> Vec<String> {
400389pub struct Builder {
401390 input_dir : PathBuf ,
402391 features_constant : Option < String > ,
403- target_triple_env_var : Option < String > ,
392+ target_triple : Option < String > ,
404393}
405394
406395impl Builder {
407396 fn new < P : AsRef < Path > > ( input_dir : P ) -> Self {
397+ let target_triple = std:: env:: var ( "TARGET" ) . or ( std:: env:: var ( "HOST" ) ) . ok ( ) ;
408398 Self {
409399 input_dir : input_dir. as_ref ( ) . to_path_buf ( ) ,
410400 features_constant : Some ( "FEATURES" . to_string ( ) ) ,
411- target_triple_env_var : Some ( "TARGET" . to_string ( ) ) ,
401+ target_triple ,
412402 }
413403 }
414404
@@ -448,54 +438,58 @@ impl Builder {
448438 self
449439 }
450440
451- /// Enables filtering source code by target-triple which is usually
452- /// passed to `build.rs` in `TARGET` environment variable.
453- /// Accepts the name of the environment variable as an optional string.
454- /// Default value is `TARGET`.
441+ /// Enables filtering source code by target-triple. This is
442+ /// useful if some binding generators or custom tools over them
443+ /// encounter problems with build conditions in the source code.
444+ ///
445+ /// Accepts the target triple string.
446+ ///
447+ /// Default value is the value of the environment variable
448+ /// `TARGET` or `HOST` if `TARGET` is not set.
455449 ///
456450 /// Pass `None` to disable target filtering.
457451 ///
458452 /// When enabled, the code will be filtered by the target triple specified
459- /// (architecture, vendor, os, env). By default filtering is performed
460- /// by the value from the `TARGET` environment variable which contains
461- /// the target triple for the library.
453+ /// (architecture, vendor, os, env).
462454 ///
463455 /// It's useful to mention that it's hard to imagine a scenario
464- /// when it's necessary to change the environment variable name .
456+ /// when it's necessary to change the target triple .
465457 /// The `Source` object is used in the final crate, the one which builds the
466- /// no-mangle library and the language bindings (e.g. C headers). On this
467- /// stage the `TARGET` environment variable contains real target triple
468- /// even in cross-compilation scenarios. Passing the real target in the
469- /// other variable's name, e.g:
458+ /// no-mangle library. On this stage the `TARGET` environment variable contains
459+ /// real target triple for cross-compilation scenarios.
460+ ///
461+ /// There is the case when build.rs is not aware of the cross-compilation
462+ /// target: the build.rs for library in [build-dependencies] section.
463+ /// This is the situation which the "ffi" crate found itself in. So sometimes
464+ /// for correct code generation it's necessary to inform the underlying "ffi"
465+ /// crate about the real target in a way like this:
466+ ///
470467 /// ```ignore
471468 /// CROSS_TARGET=x86_64-pc-windows-gnu cargo build --target x86_64-pc-windows-gnu
472469 /// ```
473- /// sometimes is necessary to inform the underlying "ffi" crate about the
474- /// real target triple, because it's compiled as a `build.rs` dependency on
475- /// the host platform and therefore it's target is the host.
476- /// But the `Source` is not called on this stage, so normally the access to
477- /// this `CROSS_TARGET` variable is not needed.
478- /// But for the sake of completeness the ability to use any environment variable
479- /// is provided.
480- /// It's also possible to just create standalone `CfgFilter` object
470+ ///
471+ /// But in typical situation this doesn't affect the `Source` object which
472+ /// reads the data prepared by "ffi" crate on the following stage.
473+ ///
474+ /// So this `Some(<target-triple>)` is added mostly for API completeness,
475+ /// typical usage if this function will be with `None` argument to disable
476+ /// filtering by target triple if it's necessary to see the original
477+ /// collected code.
478+ ///
479+ /// Notice also that it's possible to just create standalone `CfgFilter` object
481480 /// with necessary configuration and insert into the iterator chain.
482481 #[ roxygen]
483482 pub fn enable_target_filtering (
484483 mut self ,
485- /// Full name of the environment variable which contains the target triple
486- /// to which the code is generated
484+ /// The target triple to filter collected sources
487485 name : Option < impl Into < String > > ,
488486 ) -> Self {
489- self . target_triple_env_var = name. map ( |n| n. into ( ) ) ;
487+ self . target_triple = name. map ( |n| n. into ( ) ) ;
490488 self
491489 }
492490
493491 /// Build the `Source` instance
494492 pub fn build ( self ) -> Source {
495- Source :: build_internal (
496- & self . input_dir ,
497- self . features_constant ,
498- self . target_triple_env_var ,
499- )
493+ Source :: build_internal ( & self . input_dir , self . features_constant , self . target_triple )
500494 }
501495}
0 commit comments