revive_llvm_builder/
builtins.rs

1//! Utilities for compiling the LLVM compiler-rt builtins.
2
3use crate::utils::path_windows_to_unix as to_unix;
4use std::{env::consts::EXE_EXTENSION, process::Command};
5
6/// Static CFLAGS variable passed to the compiler building the compiler-rt builtins.
7const C_FLAGS: [&str; 6] = [
8    "--target=riscv64",
9    "-march=rv64emac",
10    "-mabi=lp64e",
11    "-mcpu=generic-rv64",
12    "-nostdlib",
13    "-nodefaultlibs",
14];
15
16/// Static CMAKE arguments for building the compiler-rt builtins.
17const CMAKE_STATIC_ARGS: [&str; 14] = [
18    "-DCOMPILER_RT_BUILD_BUILTINS='On'",
19    "-DCOMPILER_RT_BUILD_LIBFUZZER='Off'",
20    "-DCOMPILER_RT_BUILD_MEMPROF='Off'",
21    "-DCOMPILER_RT_BUILD_PROFILE='Off'",
22    "-DCOMPILER_RT_BUILD_SANITIZERS='Off'",
23    "-DCOMPILER_RT_BUILD_XRAY='Off'",
24    "-DCOMPILER_RT_DEFAULT_TARGET_ONLY='On'",
25    "-DCOMPILER_RT_BAREMETAL_BUILD='On'",
26    "-DCMAKE_BUILD_WITH_INSTALL_RPATH=1",
27    "-DCMAKE_EXPORT_COMPILE_COMMANDS='On'",
28    "-DCMAKE_SYSTEM_NAME='unknown'",
29    "-DCMAKE_C_COMPILER_TARGET='riscv64'",
30    "-DCMAKE_ASM_COMPILER_TARGET='riscv64'",
31    "-DCMAKE_CXX_COMPILER_TARGET='riscv64'",
32];
33
34/// Dynamic cmake arguments for building the compiler-rt builtins.
35fn cmake_dynamic_args(
36    build_type: crate::BuildType,
37    target_env: crate::target_env::TargetEnv,
38) -> anyhow::Result<[String; 13]> {
39    let llvm_compiler_rt_target = crate::LLVMPath::llvm_target_compiler_rt()?;
40
41    // The Emscripten target needs to use the host LLVM tools.
42    let llvm_target_host = if target_env == crate::target_env::TargetEnv::Emscripten {
43        crate::LLVMPath::llvm_build_host()?
44    } else {
45        crate::LLVMPath::llvm_target_final()?
46    };
47
48    let mut clang_path = llvm_target_host.to_path_buf();
49    clang_path.push("bin/clang");
50    clang_path.set_extension(EXE_EXTENSION);
51
52    let mut clangxx_path = llvm_target_host.to_path_buf();
53    clangxx_path.push("bin/clang++");
54    clangxx_path.set_extension(EXE_EXTENSION);
55
56    let mut llvm_config_path = llvm_target_host.to_path_buf();
57    llvm_config_path.push("bin/llvm-config");
58    llvm_config_path.set_extension(EXE_EXTENSION);
59
60    let mut ar_path = llvm_target_host.to_path_buf();
61    ar_path.push("bin/llvm-ar");
62    ar_path.set_extension(EXE_EXTENSION);
63
64    let mut nm_path = llvm_target_host.to_path_buf();
65    nm_path.push("bin/llvm-nm");
66    nm_path.set_extension(EXE_EXTENSION);
67
68    let mut ranlib_path = llvm_target_host.to_path_buf();
69    ranlib_path.push("bin/llvm-ranlib");
70    ranlib_path.set_extension(EXE_EXTENSION);
71
72    let mut linker_path = llvm_target_host.to_path_buf();
73    linker_path.push("bin/ld.lld");
74    linker_path.set_extension(EXE_EXTENSION);
75
76    Ok([
77        format!(
78            "-DCMAKE_INSTALL_PREFIX='{}'",
79            llvm_compiler_rt_target.to_string_lossy().as_ref(),
80        ),
81        format!("-DCMAKE_BUILD_TYPE='{build_type}'"),
82        format!(
83            "-DCOMPILER_RT_TEST_COMPILER='{}'",
84            clang_path.to_string_lossy()
85        ),
86        format!("-DCMAKE_C_FLAGS='{}'", C_FLAGS.join(" ")),
87        format!("-DCMAKE_ASM_FLAGS='{}'", C_FLAGS.join(" ")),
88        format!("-DCMAKE_CXX_FLAGS='{}'", C_FLAGS.join(" ")),
89        format!(
90            "-DCMAKE_C_COMPILER='{}'",
91            to_unix(clang_path.clone())?.display()
92        ),
93        format!("-DCMAKE_ASM_COMPILER='{}'", to_unix(clang_path)?.display()),
94        format!(
95            "-DCMAKE_CXX_COMPILER='{}'",
96            to_unix(clangxx_path)?.display()
97        ),
98        format!("-DCMAKE_AR='{}'", to_unix(ar_path)?.display()),
99        format!("-DCMAKE_NM='{}'", to_unix(nm_path)?.display()),
100        format!("-DCMAKE_RANLIB='{}'", to_unix(ranlib_path)?.display()),
101        format!(
102            "-DLLVM_CONFIG_PATH='{}'",
103            llvm_config_path.to_string_lossy()
104        ),
105    ])
106}
107
108/// Build the compiler-rt builtins library.
109pub fn build(
110    build_type: crate::BuildType,
111    target_env: crate::target_env::TargetEnv,
112    default_target: Option<crate::TargetTriple>,
113    extra_args: &[String],
114    ccache_variant: Option<crate::ccache_variant::CcacheVariant>,
115    sanitizer: Option<crate::sanitizer::Sanitizer>,
116) -> anyhow::Result<()> {
117    log::info!("building compiler-rt for rv64emac");
118
119    crate::utils::check_presence("cmake")?;
120    crate::utils::check_presence("ninja")?;
121
122    let llvm_module_compiler_rt = crate::LLVMPath::llvm_module_compiler_rt()?;
123    let llvm_compiler_rt_build = crate::LLVMPath::llvm_build_compiler_rt()?;
124
125    crate::utils::command(
126        std::process::Command::new("cmake")
127            .args([
128                "-S",
129                llvm_module_compiler_rt.to_string_lossy().as_ref(),
130                "-B",
131                llvm_compiler_rt_build.to_string_lossy().as_ref(),
132                "-G",
133                "Ninja",
134            ])
135            .args(CMAKE_STATIC_ARGS)
136            .args(cmake_dynamic_args(build_type, target_env)?)
137            .args(extra_args)
138            .args(crate::platforms::shared::shared_build_opts_ccache(
139                ccache_variant,
140            ))
141            .args(crate::platforms::shared::shared_build_opts_default_target(
142                default_target,
143            ))
144            .args(crate::platforms::shared::shared_build_opts_sanitizers(
145                sanitizer,
146            )),
147        "LLVM compiler-rt building cmake",
148    )?;
149
150    crate::utils::command(
151        Command::new("cmake").args([
152            "--build",
153            llvm_compiler_rt_build.to_string_lossy().as_ref(),
154            "--target",
155            "install",
156            "--config",
157            build_type.to_string().as_str(),
158        ]),
159        "Building",
160    )?;
161
162    Ok(())
163}