1fb6c1f39Sopenharmony_ciuse std::env;
2fb6c1f39Sopenharmony_ci
3fb6c1f39Sopenharmony_cifn main() {
4fb6c1f39Sopenharmony_ci    enable_simd_optimizations();
5fb6c1f39Sopenharmony_ci    enable_libc();
6fb6c1f39Sopenharmony_ci}
7fb6c1f39Sopenharmony_ci
8fb6c1f39Sopenharmony_ci// This adds various simd cfgs if this compiler and target support it.
9fb6c1f39Sopenharmony_ci//
10fb6c1f39Sopenharmony_ci// This can be disabled with RUSTFLAGS="--cfg memchr_disable_auto_simd", but
11fb6c1f39Sopenharmony_ci// this is generally only intended for testing.
12fb6c1f39Sopenharmony_ci//
13fb6c1f39Sopenharmony_ci// On targets which don't feature SSE2, this is disabled, as LLVM wouln't know
14fb6c1f39Sopenharmony_ci// how to work with SSE2 operands. Enabling SSE4.2 and AVX on SSE2-only targets
15fb6c1f39Sopenharmony_ci// is not a problem. In that case, the fastest option will be chosen at
16fb6c1f39Sopenharmony_ci// runtime.
17fb6c1f39Sopenharmony_cifn enable_simd_optimizations() {
18fb6c1f39Sopenharmony_ci    if is_env_set("CARGO_CFG_MEMCHR_DISABLE_AUTO_SIMD") {
19fb6c1f39Sopenharmony_ci        return;
20fb6c1f39Sopenharmony_ci    }
21fb6c1f39Sopenharmony_ci    let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
22fb6c1f39Sopenharmony_ci    match &arch[..] {
23fb6c1f39Sopenharmony_ci        "x86_64" => {
24fb6c1f39Sopenharmony_ci            if !target_has_feature("sse2") {
25fb6c1f39Sopenharmony_ci                return;
26fb6c1f39Sopenharmony_ci            }
27fb6c1f39Sopenharmony_ci            println!("cargo:rustc-cfg=memchr_runtime_simd");
28fb6c1f39Sopenharmony_ci            println!("cargo:rustc-cfg=memchr_runtime_sse2");
29fb6c1f39Sopenharmony_ci            println!("cargo:rustc-cfg=memchr_runtime_sse42");
30fb6c1f39Sopenharmony_ci            println!("cargo:rustc-cfg=memchr_runtime_avx");
31fb6c1f39Sopenharmony_ci        }
32fb6c1f39Sopenharmony_ci        "wasm32" | "wasm64" => {
33fb6c1f39Sopenharmony_ci            if !target_has_feature("simd128") {
34fb6c1f39Sopenharmony_ci                return;
35fb6c1f39Sopenharmony_ci            }
36fb6c1f39Sopenharmony_ci            println!("cargo:rustc-cfg=memchr_runtime_simd");
37fb6c1f39Sopenharmony_ci            println!("cargo:rustc-cfg=memchr_runtime_wasm128");
38fb6c1f39Sopenharmony_ci        }
39fb6c1f39Sopenharmony_ci        _ => {}
40fb6c1f39Sopenharmony_ci    }
41fb6c1f39Sopenharmony_ci}
42fb6c1f39Sopenharmony_ci
43fb6c1f39Sopenharmony_ci// This adds a `memchr_libc` cfg if and only if libc can be used, if no other
44fb6c1f39Sopenharmony_ci// better option is available.
45fb6c1f39Sopenharmony_ci//
46fb6c1f39Sopenharmony_ci// This could be performed in the source code, but it's simpler to do it once
47fb6c1f39Sopenharmony_ci// here and consolidate it into one cfg knob.
48fb6c1f39Sopenharmony_ci//
49fb6c1f39Sopenharmony_ci// Basically, we use libc only if its enabled and if we aren't targeting a
50fb6c1f39Sopenharmony_ci// known bad platform. For example, wasm32 doesn't have a libc and the
51fb6c1f39Sopenharmony_ci// performance of memchr on Windows is seemingly worse than the fallback
52fb6c1f39Sopenharmony_ci// implementation.
53fb6c1f39Sopenharmony_cifn enable_libc() {
54fb6c1f39Sopenharmony_ci    const NO_ARCH: &'static [&'static str] = &["wasm32", "windows"];
55fb6c1f39Sopenharmony_ci    const NO_ENV: &'static [&'static str] = &["sgx"];
56fb6c1f39Sopenharmony_ci
57fb6c1f39Sopenharmony_ci    if !is_feature_set("LIBC") {
58fb6c1f39Sopenharmony_ci        return;
59fb6c1f39Sopenharmony_ci    }
60fb6c1f39Sopenharmony_ci
61fb6c1f39Sopenharmony_ci    let arch = match env::var("CARGO_CFG_TARGET_ARCH") {
62fb6c1f39Sopenharmony_ci        Err(_) => return,
63fb6c1f39Sopenharmony_ci        Ok(arch) => arch,
64fb6c1f39Sopenharmony_ci    };
65fb6c1f39Sopenharmony_ci    let env = match env::var("CARGO_CFG_TARGET_ENV") {
66fb6c1f39Sopenharmony_ci        Err(_) => return,
67fb6c1f39Sopenharmony_ci        Ok(env) => env,
68fb6c1f39Sopenharmony_ci    };
69fb6c1f39Sopenharmony_ci    if NO_ARCH.contains(&&*arch) || NO_ENV.contains(&&*env) {
70fb6c1f39Sopenharmony_ci        return;
71fb6c1f39Sopenharmony_ci    }
72fb6c1f39Sopenharmony_ci
73fb6c1f39Sopenharmony_ci    println!("cargo:rustc-cfg=memchr_libc");
74fb6c1f39Sopenharmony_ci}
75fb6c1f39Sopenharmony_ci
76fb6c1f39Sopenharmony_cifn is_feature_set(name: &str) -> bool {
77fb6c1f39Sopenharmony_ci    is_env_set(&format!("CARGO_FEATURE_{}", name))
78fb6c1f39Sopenharmony_ci}
79fb6c1f39Sopenharmony_ci
80fb6c1f39Sopenharmony_cifn is_env_set(name: &str) -> bool {
81fb6c1f39Sopenharmony_ci    env::var_os(name).is_some()
82fb6c1f39Sopenharmony_ci}
83fb6c1f39Sopenharmony_ci
84fb6c1f39Sopenharmony_cifn target_has_feature(feature: &str) -> bool {
85fb6c1f39Sopenharmony_ci    env::var("CARGO_CFG_TARGET_FEATURE")
86fb6c1f39Sopenharmony_ci        .map(|features| features.contains(feature))
87fb6c1f39Sopenharmony_ci        .unwrap_or(false)
88fb6c1f39Sopenharmony_ci}
89