run_make_support/external_deps/
c_build.rs

1use std::path::PathBuf;
2
3use crate::artifact_names::{dynamic_lib_name, static_lib_name};
4use crate::external_deps::c_cxx_compiler::{cc, cxx};
5use crate::external_deps::llvm::llvm_ar;
6use crate::path_helpers::path;
7use crate::targets::{is_darwin, is_windows, is_windows_msvc};
8
9// FIXME(Oneirical): These native build functions should take a Path-based generic.
10
11/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
12/// Built from a C file.
13#[track_caller]
14pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
15    build_native_static_lib_internal(lib_name, false)
16}
17
18/// Builds an optimized static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
19/// Built from a C file.
20#[track_caller]
21pub fn build_native_static_lib_optimized(lib_name: &str) -> PathBuf {
22    build_native_static_lib_internal(lib_name, true)
23}
24
25#[track_caller]
26fn build_native_static_lib_internal(lib_name: &str, optimzed: bool) -> PathBuf {
27    let obj_file = if is_windows_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
28    let src = format!("{lib_name}.c");
29    let lib_path = static_lib_name(lib_name);
30
31    let mut cc = cc();
32    if !is_windows_msvc() {
33        cc.arg("-v");
34    }
35    if optimzed {
36        cc.optimize();
37    }
38    cc.arg("-c").out_exe(&obj_file).input(src).optimize().run();
39
40    let obj_file = if is_windows_msvc() {
41        PathBuf::from(format!("{lib_name}.obj"))
42    } else {
43        PathBuf::from(format!("{lib_name}.o"))
44    };
45    llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
46    path(lib_path)
47}
48
49/// Builds a dynamic lib. The filename is computed in a target-dependent manner, relying on
50/// [`std::env::consts::DLL_PREFIX`] and [`std::env::consts::DLL_EXTENSION`].
51#[track_caller]
52pub fn build_native_dynamic_lib(lib_name: &str) -> PathBuf {
53    let obj_file = if is_windows_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
54    let src = format!("{lib_name}.c");
55    let lib_path = dynamic_lib_name(lib_name);
56    if is_windows_msvc() {
57        cc().arg("-c").out_exe(&obj_file).input(src).run();
58    } else {
59        cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
60    };
61    let obj_file =
62        if is_windows_msvc() { format!("{lib_name}.obj") } else { format!("{lib_name}.o") };
63    if is_windows_msvc() {
64        let out_arg = format!("-out:{lib_path}");
65        cc().input(&obj_file).args(&["-link", "-dll", &out_arg]).run();
66    } else if is_darwin() {
67        cc().out_exe(&lib_path).input(&obj_file).args(&["-dynamiclib", "-Wl,-dylib"]).run();
68    } else if is_windows() {
69        cc().out_exe(&lib_path)
70            .input(&obj_file)
71            .args(&["-shared", &format!("-Wl,--out-implib={lib_path}.a")])
72            .run();
73    } else {
74        cc().out_exe(&lib_path).input(&obj_file).arg("-shared").run();
75    }
76    path(lib_path)
77}
78
79/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
80/// Built from a C++ file.
81#[track_caller]
82pub fn build_native_static_lib_cxx(lib_name: &str) -> PathBuf {
83    let obj_file = if is_windows_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
84    let src = format!("{lib_name}.cpp");
85    let lib_path = static_lib_name(lib_name);
86    if is_windows_msvc() {
87        cxx().arg("-EHs").arg("-c").out_exe(&obj_file).input(src).run();
88    } else {
89        cxx().arg("-c").out_exe(&obj_file).input(src).run();
90    };
91    let obj_file = if is_windows_msvc() {
92        PathBuf::from(format!("{lib_name}.obj"))
93    } else {
94        PathBuf::from(format!("{lib_name}.o"))
95    };
96    llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
97    path(lib_path)
98}