compiler_llvm_builder/platforms/
shared.rs

1//!
2//! The shared options for building various platforms.
3//!
4
5use std::path::Path;
6use std::process::Command;
7
8use crate::ccache_variant::CcacheVariant;
9use crate::sanitizer::Sanitizer;
10use crate::target_triple::TargetTriple;
11
12/// The build options shared by all platforms.
13pub const SHARED_BUILD_OPTS: [&str; 19] = [
14    "-DPACKAGE_VENDOR='Matter Labs'",
15    "-DCMAKE_BUILD_WITH_INSTALL_RPATH=1",
16    "-DLLVM_BUILD_DOCS='Off'",
17    "-DLLVM_INCLUDE_DOCS='Off'",
18    "-DLLVM_INCLUDE_BENCHMARKS='Off'",
19    "-DLLVM_INCLUDE_EXAMPLES='Off'",
20    "-DLLVM_ENABLE_DOXYGEN='Off'",
21    "-DLLVM_ENABLE_SPHINX='Off'",
22    "-DLLVM_ENABLE_OCAMLDOC='Off'",
23    "-DLLVM_ENABLE_ZLIB='Off'",
24    "-DLLVM_ENABLE_ZSTD='Off'",
25    "-DLLVM_ENABLE_LIBXML2='Off'",
26    "-DLLVM_ENABLE_BINDINGS='Off'",
27    "-DLLVM_ENABLE_TERMINFO='Off'",
28    "-DLLVM_ENABLE_LIBEDIT='Off'",
29    "-DLLVM_ENABLE_LIBPFM='Off'",
30    "-DCMAKE_EXPORT_COMPILE_COMMANDS='On'",
31    "-DPython3_FIND_REGISTRY='LAST'", // Use Python version from $PATH, not from registry
32    "-DBUG_REPORT_URL='https://github.com/matter-labs/era-compiler-llvm/issues/'",
33];
34
35/// The build options shared by all platforms except MUSL.
36pub const SHARED_BUILD_OPTS_NOT_MUSL: [&str; 4] = [
37    "-DLLVM_OPTIMIZED_TABLEGEN='On'",
38    "-DLLVM_BUILD_RUNTIME='Off'",
39    "-DLLVM_BUILD_RUNTIMES='Off'",
40    "-DLLVM_INCLUDE_RUNTIMES='Off'",
41];
42
43///
44/// The shared build options to treat warnings as errors.
45///
46/// Disabled on Windows due to the following upstream issue with MSYS2 with mingw-w64:
47/// ProgramTest.cpp:23:15: error: '__p__environ' redeclared without 'dllimport' attribute
48///
49pub fn shared_build_opts_werror() -> Vec<String> {
50    vec![format!(
51        "-DLLVM_ENABLE_WERROR='{}'",
52        if cfg!(target_os = "windows") {
53            "Off"
54        } else {
55            "On"
56        },
57    )]
58}
59
60///
61/// The build options to set the default target.
62///
63pub fn shared_build_opts_default_target(target: Option<TargetTriple>) -> Vec<String> {
64    match target {
65        Some(target) => vec![format!(
66            "-DLLVM_DEFAULT_TARGET_TRIPLE='{}'",
67            target.to_string()
68        )],
69        None => vec![format!(
70            "-DLLVM_DEFAULT_TARGET_TRIPLE='{}'",
71            TargetTriple::EraVM
72        )],
73    }
74}
75
76///
77/// The `musl` building sequence.
78///
79pub fn build_musl(build_directory: &Path, target_directory: &Path) -> anyhow::Result<()> {
80    std::fs::create_dir_all(build_directory)?;
81    std::fs::create_dir_all(target_directory)?;
82
83    crate::utils::command(
84        Command::new("../configure")
85            .current_dir(build_directory)
86            .arg(format!("--prefix={}", target_directory.to_string_lossy()))
87            .arg(format!(
88                "--syslibdir={}/lib/",
89                target_directory.to_string_lossy()
90            ))
91            .arg("--enable-wrapper='clang'"),
92        "MUSL configuring",
93    )?;
94    crate::utils::command(
95        Command::new("make")
96            .current_dir(build_directory)
97            .arg("-j")
98            .arg(num_cpus::get().to_string()),
99        "MUSL building",
100    )?;
101    crate::utils::command(
102        Command::new("make")
103            .current_dir(build_directory)
104            .arg("install"),
105        "MUSL installing",
106    )?;
107
108    let mut include_directory = target_directory.to_path_buf();
109    include_directory.push("include/");
110
111    let mut asm_include_directory = include_directory.clone();
112    asm_include_directory.push("asm/");
113    std::fs::create_dir_all(asm_include_directory.as_path())?;
114
115    let mut types_header_path = asm_include_directory.clone();
116    types_header_path.push("types.h");
117
118    let copy_options = fs_extra::dir::CopyOptions {
119        overwrite: true,
120        copy_inside: true,
121        ..Default::default()
122    };
123    fs_extra::dir::copy("/usr/include/linux", include_directory, &copy_options)?;
124
125    let copy_options = fs_extra::dir::CopyOptions {
126        overwrite: true,
127        copy_inside: true,
128        content_only: true,
129        ..Default::default()
130    };
131    fs_extra::dir::copy(
132        "/usr/include/asm-generic",
133        asm_include_directory.as_path(),
134        &copy_options,
135    )?;
136
137    let arch_asm_path = format!("/usr/include/{}-linux-gnu/asm", std::env::consts::ARCH);
138    let copy_options = fs_extra::file::CopyOptions::new().overwrite(true);
139    for file in [
140        "byteorder.h",
141        "ptrace.h",
142        "hwcap.h",
143        "sve_context.h",
144        "unistd_64.h",
145    ]
146    .into_iter()
147    {
148        let source = std::path::PathBuf::from(arch_asm_path.as_str()).join(file);
149        let destination = asm_include_directory.join(file);
150        if source.exists() {
151            fs_extra::file::copy(source.as_path(), destination.as_path(), &copy_options)?;
152        }
153    }
154
155    crate::utils::command(
156        Command::new("sed")
157            .arg("-i")
158            .arg("s/asm-generic/asm/")
159            .arg(types_header_path),
160        "types_header asm signature replacement",
161    )?;
162
163    Ok(())
164}
165
166///
167/// The build options to enable assertions.
168///
169pub fn shared_build_opts_assertions(enabled: bool) -> Vec<String> {
170    vec![format!(
171        "-DLLVM_ENABLE_ASSERTIONS='{}'",
172        if enabled { "On" } else { "Off" },
173    )]
174}
175
176///
177/// The build options to build with RTTI support.
178///
179pub fn shared_build_opts_rtti(enabled: bool) -> Vec<String> {
180    vec![format!(
181        "-DLLVM_ENABLE_RTTI='{}'",
182        if enabled { "On" } else { "Off" },
183    )]
184}
185
186///
187/// The build options to enable sanitizers.
188///
189pub fn shared_build_opts_sanitizers(sanitizer: Option<Sanitizer>) -> Vec<String> {
190    match sanitizer {
191        Some(sanitizer) => vec![format!("-DLLVM_USE_SANITIZER='{}'", sanitizer)],
192        None => vec![],
193    }
194}
195
196///
197/// The build options to enable Valgrind for LLVM regression tests.
198///
199pub fn shared_build_opts_valgrind(enabled: bool, valgrind_options: Vec<String>) -> Vec<String> {
200    if !enabled {
201        return vec![];
202    }
203
204    let vg_args = valgrind_options
205        .iter()
206        .map(|opt| format!("--vg-arg='{}'", opt))
207        .collect::<Vec<_>>()
208        .join(" ");
209
210    vec![format!("-DLLVM_LIT_ARGS='-sv --vg --vg-leak {}'", vg_args)]
211}
212
213///
214/// The LLVM tests build options shared by all platforms.
215///
216pub fn shared_build_opts_tests(enabled: bool) -> Vec<String> {
217    vec![
218        format!(
219            "-DLLVM_BUILD_UTILS='{}'",
220            if enabled { "On" } else { "Off" },
221        ),
222        format!(
223            "-DLLVM_BUILD_TESTS='{}'",
224            if enabled { "On" } else { "Off" },
225        ),
226        format!(
227            "-DLLVM_INCLUDE_UTILS='{}'",
228            if enabled { "On" } else { "Off" },
229        ),
230        format!(
231            "-DLLVM_INCLUDE_TESTS='{}'",
232            if enabled { "On" } else { "Off" },
233        ),
234    ]
235}
236
237///
238/// The code coverage build options shared by all platforms.
239///
240pub fn shared_build_opts_coverage(enabled: bool) -> Vec<String> {
241    vec![format!(
242        "-DLLVM_BUILD_INSTRUMENTED_COVERAGE='{}'",
243        if enabled { "On" } else { "Off" },
244    )]
245}
246
247///
248/// Use of compiler cache (ccache) to speed up the build process.
249///
250pub fn shared_build_opts_ccache(ccache_variant: Option<CcacheVariant>) -> Vec<String> {
251    match ccache_variant {
252        Some(ccache_variant) => vec![
253            format!(
254                "-DCMAKE_C_COMPILER_LAUNCHER='{}'",
255                ccache_variant.to_string()
256            ),
257            format!(
258                "-DCMAKE_CXX_COMPILER_LAUNCHER='{}'",
259                ccache_variant.to_string()
260            ),
261        ],
262        None => vec![],
263    }
264}
265
266///
267/// Ignore duplicate libraries warnings for MacOS with XCode>=15.
268///
269pub fn macos_build_opts_ignore_dupicate_libs_warnings() -> Vec<String> {
270    let xcode_version =
271        crate::utils::get_xcode_version().unwrap_or(crate::utils::XCODE_MIN_VERSION);
272    if xcode_version >= crate::utils::XCODE_VERSION_15 {
273        vec![
274            "-DCMAKE_EXE_LINKER_FLAGS='-Wl,-no_warn_duplicate_libraries'".to_owned(),
275            "-DCMAKE_SHARED_LINKER_FLAGS='-Wl,-no_warn_duplicate_libraries'".to_owned(),
276        ]
277    } else {
278        vec![]
279    }
280}