1 extern crate cc;
2 
find_assembly(arch: &str, endian: &str, os: &str, env: &str) -> Option<(&'static str, bool)>3 fn find_assembly(arch: &str, endian: &str, os: &str, env: &str) -> Option<(&'static str, bool)> {
4     match (arch, endian, os, env) {
5         // The implementations for stack switching exist, but, officially, doing so without Fibers
6         // is not supported in Windows. For x86_64 the implementation actually works locally,
7         // but failed tests in CI (???). Might want to have a feature for experimental support
8         // here.
9         ("x86", _, "windows", "msvc") => Some(("src/arch/x86_msvc.asm", false)),
10         ("x86_64", _, "windows", "msvc") => Some(("src/arch/x86_64_msvc.asm", false)),
11         ("arm", _, "windows", "msvc") => Some(("src/arch/arm_armasm.asm", false)),
12         ("aarch64", _, "windows", "msvc") => Some(("src/arch/aarch64_armasm.asm", false)),
13         ("x86", _, "windows", _) => Some(("src/arch/x86_windows_gnu.s", false)),
14         ("x86_64", _, "windows", _) => Some(("src/arch/x86_64_windows_gnu.s", false)),
15 
16         ("x86", _, _, _) => Some(("src/arch/x86.s", true)),
17         ("x86_64", _, _, _) => Some(("src/arch/x86_64.s", true)),
18         ("arm", _, _, _) => Some(("src/arch/arm_aapcs.s", true)),
19         ("aarch64", _, _, _) => Some(("src/arch/aarch_aapcs64.s", true)),
20         ("powerpc", _, _, _) => Some(("src/arch/powerpc32.s", true)),
21         ("powerpc64", "little", _, _) => Some(("src/arch/powerpc64_openpower.s", true)),
22         ("powerpc64", _, _, _) => Some(("src/arch/powerpc64.s", true)),
23         ("s390x", _, _, _) => Some(("src/arch/zseries_linux.s", true)),
24         ("mips", _, _, _) => Some(("src/arch/mips_eabi.s", true)),
25         ("mips64", _, _, _) => Some(("src/arch/mips64_eabi.s", true)),
26         ("sparc64", _, _, _) => Some(("src/arch/sparc64.s", true)),
27         ("sparc", _, _, _) => Some(("src/arch/sparc_sysv.s", true)),
28         ("riscv32", _, _, _) => Some(("src/arch/riscv.s", true)),
29         ("riscv64", _, _, _) => Some(("src/arch/riscv64.s", true)),
30 
31         // The implementations exist, but the compilers are unlikely be able to work with this.
32         // ("wasm32",     _,        "unknown", _) => Some(("src/arch/wasm32.s", false)),
33         // ("wasm32",     _,        "wasi",    _) => Some(("src/arch/wasm32.s", false)),
34         _ => None,
35     }
36 }
37 
main()38 fn main() {
39     let arch = ::std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
40     let env = ::std::env::var("CARGO_CFG_TARGET_ENV").unwrap();
41     let os = ::std::env::var("CARGO_CFG_TARGET_OS").unwrap();
42     let endian = ::std::env::var("CARGO_CFG_TARGET_ENDIAN").unwrap();
43     let asm = if let Some((asm, canswitch)) = find_assembly(&arch, &endian, &os, &env) {
44         println!("cargo:rustc-cfg=asm");
45         if canswitch {
46             println!("cargo:rustc-cfg=switchable_stack")
47         }
48         asm
49     } else {
50         println!(
51             "cargo:warning=Target {}-{}-{} has no assembly files!",
52             arch, os, env
53         );
54         return;
55     };
56 
57     let mut cfg = cc::Build::new();
58     let msvc = cfg.get_compiler().is_like_msvc();
59 
60     if !msvc {
61         cfg.flag("-xassembler-with-cpp");
62     }
63     cfg.file(asm);
64 
65     cfg.define(&*format!("CFG_TARGET_OS_{}", os), None);
66     cfg.define(&*format!("CFG_TARGET_ARCH_{}", arch), None);
67     cfg.define(&*format!("CFG_TARGET_ENV_{}", env), None);
68 
69     cfg.compile("libpsm_s.a");
70 }
71