|
| 1 | +use std::env; |
| 2 | +use std::path::Path; |
| 3 | + |
| 4 | +fn main() { |
| 5 | + // Only rerun if this file changes; the script doesn't depend on our code |
| 6 | + println!("cargo:rerun-if-changed=build.rs"); |
| 7 | + |
| 8 | + let mut apple = env::var_os("CARGO_FEATURE_APPLE").is_some(); |
| 9 | + let mut compiler_rt = env::var_os("CARGO_FEATURE_COMPILER_RT").is_some(); |
| 10 | + let gnustep = env::var_os("CARGO_FEATURE_GNUSTEP_1_7").is_some(); |
| 11 | + let objfw = env::var_os("CARGO_FEATURE_OBJFW").is_some(); |
| 12 | + |
| 13 | + if let (false, false, false, false) = (apple, compiler_rt, gnustep, objfw) { |
| 14 | + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); |
| 15 | + if let "macos" | "ios" | "tvos" | "watchos" = &*target_os { |
| 16 | + apple = true; |
| 17 | + // Add cheaty #[cfg(feature = "apple")] directive |
| 18 | + println!("cargo:rustc-cfg=feature=\"apple\""); |
| 19 | + } else { |
| 20 | + compiler_rt = true; |
| 21 | + // Add cheaty #[cfg(feature = "compiler-rt")] directive |
| 22 | + println!("cargo:rustc-cfg=feature=\"compiler-rt\""); |
| 23 | + } |
| 24 | + } |
| 25 | + |
| 26 | + let mut cc_args = "-fblocks".to_owned(); |
| 27 | + |
| 28 | + match (apple, compiler_rt, gnustep, objfw) { |
| 29 | + (true, false, false, false) => { |
| 30 | + // Link to libclosure (internally called libsystem_blocks), which is |
| 31 | + // exported by libSystem.dylib. |
| 32 | + // |
| 33 | + // Note that System.framework is just a deprecated wrapper over the |
| 34 | + // dynamic library. |
| 35 | + println!("cargo:rustc-link-lib=dylib=System"); |
| 36 | + // Alternative: Only link to libsystem_blocks.dylib |
| 37 | + // println!("cargo:rustc-link-search=native=/usr/lib/system"); |
| 38 | + // println!("cargo:rustc-link-lib=dylib=system_blocks"); |
| 39 | + } |
| 40 | + (false, true, false, false) => { |
| 41 | + println!("cargo:rustc-link-lib=dylib=BlocksRuntime"); |
| 42 | + } |
| 43 | + (false, false, true, false) => { |
| 44 | + // Don't link to anything; objc2_sys already does that for us! |
| 45 | + |
| 46 | + // Add GNUStep compability headers to make `#include <Block.h>` |
| 47 | + // work (on newer GNUStep versions these headers are present) |
| 48 | + if !env::var_os("CARGO_FEATURE_GNUSTEP_2_0").is_some() { |
| 49 | + let compat_headers = |
| 50 | + Path::new(env!("CARGO_MANIFEST_DIR")).join("gnustep-compat-headers"); |
| 51 | + cc_args.push_str("-I"); |
| 52 | + cc_args.push_str(compat_headers.to_str().unwrap()); |
| 53 | + } |
| 54 | + } |
| 55 | + (false, false, false, true) => unimplemented!(), |
| 56 | + // Checked in if-let above |
| 57 | + (false, false, false, false) => unreachable!(), |
| 58 | + (_, _, _, _) => panic!("Invalid feature combination; only one runtime may be selected!"), |
| 59 | + } |
| 60 | + |
| 61 | + // Add DEP_BLOCK_CC_ARGS |
| 62 | + println!("cargo:cc_args={}", cc_args); |
| 63 | +} |
0 commit comments