mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-04-23 00:18:01 +00:00
2fb8beee62
This PR changes the CI build scripts to also build LLVM for windows. **It doesn't build `revive` itself for windows**. This will come in a follow up. But once we have a LLVM binary release the turn around time will be much quicker for experimenting with the revive windows build. I manually uploaded the release those changes produce [here](https://github.com/paritytech/revive-alex-workflowtest/releases/tag/llvm-18.1.8-revive.22f3ceb). This enables this PR's CI to find the proper release. This is necessary because I am also making changes to the folder structure and artifact naming that the other CI jobs are depending on. Releases generated from this branch can be inspected here: https://github.com/paritytech/revive-alex-workflowtest/releases/tag/v0.1.0-dev.12 Summary of changes: - Change `llvm-builder` to use MSVC toolchain on windows - Fix `llvm-builder` to work with `.exe` files - Unify the llvm release jobs into a single one. This removed a lot of copy pasted code and also speeds up the build by giving each their own runner. - Use the LLVM target triple to name the binary releases instead of an ad-hoc naming convention - Remove the nested folder hierarchy inside the llvm release. Its just now a single folder `llvm-<target>` that contains the toolchain. - Give jobs and workflows consistent names - Replace all runners bei their `*-latest` counterpart - Only use `parity-large` to build llvm now. All other jobs use github runners
341 lines
11 KiB
Rust
341 lines
11 KiB
Rust
//! The revive LLVM builder library.
|
|
|
|
pub mod build_type;
|
|
pub mod builtins;
|
|
pub mod ccache_variant;
|
|
pub mod llvm_path;
|
|
pub mod llvm_project;
|
|
pub mod lock;
|
|
pub mod platforms;
|
|
pub mod sanitizer;
|
|
pub mod target_env;
|
|
pub mod target_triple;
|
|
pub mod utils;
|
|
|
|
pub use self::build_type::BuildType;
|
|
pub use self::llvm_path::LLVMPath;
|
|
pub use self::lock::Lock;
|
|
pub use self::platforms::Platform;
|
|
|
|
use std::collections::HashSet;
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
pub use target_env::TargetEnv;
|
|
pub use target_triple::TargetTriple;
|
|
|
|
/// Executes the LLVM repository cloning.
|
|
pub fn clone(lock: Lock, deep: bool, target_env: TargetEnv) -> anyhow::Result<()> {
|
|
utils::check_presence("git")?;
|
|
|
|
if target_env == TargetEnv::Emscripten {
|
|
utils::install_emsdk()?;
|
|
}
|
|
|
|
let destination_path = PathBuf::from(LLVMPath::DIRECTORY_LLVM_SOURCE);
|
|
if destination_path.exists() {
|
|
log::warn!(
|
|
"LLVM repository directory {} already exists, falling back to checkout",
|
|
destination_path.display()
|
|
);
|
|
return checkout(lock, false);
|
|
}
|
|
|
|
let mut clone_args = vec!["clone", "--branch", lock.branch.as_str()];
|
|
if !deep {
|
|
clone_args.push("--depth");
|
|
clone_args.push("1");
|
|
}
|
|
|
|
utils::command(
|
|
Command::new("git")
|
|
.args(clone_args)
|
|
.arg(lock.url.as_str())
|
|
.arg(destination_path.to_string_lossy().as_ref()),
|
|
"LLVM repository cloning",
|
|
)?;
|
|
|
|
if let Some(r#ref) = lock.r#ref {
|
|
utils::command(
|
|
Command::new("git")
|
|
.args(["checkout", r#ref.as_str()])
|
|
.current_dir(destination_path.to_string_lossy().as_ref()),
|
|
"LLVM repository commit checking out",
|
|
)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Executes the checkout of the specified branch.
|
|
pub fn checkout(lock: Lock, force: bool) -> anyhow::Result<()> {
|
|
let destination_path = PathBuf::from(LLVMPath::DIRECTORY_LLVM_SOURCE);
|
|
|
|
utils::command(
|
|
Command::new("git")
|
|
.current_dir(destination_path.as_path())
|
|
.args(["fetch", "--all", "--tags"]),
|
|
"LLVM repository data fetching",
|
|
)?;
|
|
|
|
if force {
|
|
utils::command(
|
|
Command::new("git")
|
|
.current_dir(destination_path.as_path())
|
|
.args(["clean", "-d", "-x", "--force"]),
|
|
"LLVM repository cleaning",
|
|
)?;
|
|
}
|
|
|
|
utils::command(
|
|
Command::new("git")
|
|
.current_dir(destination_path.as_path())
|
|
.args(["checkout", "--force", lock.branch.as_str()]),
|
|
"LLVM repository data pulling",
|
|
)?;
|
|
|
|
if let Some(r#ref) = lock.r#ref {
|
|
let mut checkout_command = Command::new("git");
|
|
checkout_command.current_dir(destination_path.as_path());
|
|
checkout_command.arg("checkout");
|
|
if force {
|
|
checkout_command.arg("--force");
|
|
}
|
|
checkout_command.arg(r#ref);
|
|
utils::command(&mut checkout_command, "LLVM repository checking out")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Executes the building of the LLVM framework for the platform determined by the cfg macro.
|
|
/// Since cfg is evaluated at compile time, overriding the platform with a command-line
|
|
/// argument is not possible. So for cross-platform testing, comment out all but the
|
|
/// line to be tested, and perhaps also checks in the platform-specific build method.
|
|
#[allow(clippy::too_many_arguments)]
|
|
pub fn build(
|
|
build_type: BuildType,
|
|
target_env: TargetEnv,
|
|
targets: HashSet<Platform>,
|
|
llvm_projects: HashSet<llvm_project::LLVMProject>,
|
|
enable_rtti: bool,
|
|
default_target: Option<TargetTriple>,
|
|
enable_tests: bool,
|
|
enable_coverage: bool,
|
|
extra_args: &[String],
|
|
ccache_variant: Option<ccache_variant::CcacheVariant>,
|
|
enable_assertions: bool,
|
|
sanitizer: Option<sanitizer::Sanitizer>,
|
|
enable_valgrind: bool,
|
|
) -> anyhow::Result<()> {
|
|
log::trace!("build type: {:?}", build_type);
|
|
log::trace!("target env: {:?}", target_env);
|
|
log::trace!("targets: {:?}", targets);
|
|
log::trace!("llvm projects: {:?}", llvm_projects);
|
|
log::trace!("enable rtti: {:?}", enable_rtti);
|
|
log::trace!("default target: {:?}", default_target);
|
|
log::trace!("eneable tests: {:?}", enable_tests);
|
|
log::trace!("enable_coverage: {:?}", enable_coverage);
|
|
log::trace!("extra args: {:?}", extra_args);
|
|
log::trace!("sanitzer: {:?}", sanitizer);
|
|
log::trace!("enable valgrind: {:?}", enable_valgrind);
|
|
|
|
if !PathBuf::from(LLVMPath::DIRECTORY_LLVM_SOURCE).exists() {
|
|
log::error!(
|
|
"LLVM project source directory {} does not exist (run `revive-llvm --target-env {} clone`)",
|
|
LLVMPath::DIRECTORY_LLVM_SOURCE,
|
|
target_env
|
|
)
|
|
}
|
|
|
|
std::fs::create_dir_all(llvm_path::DIRECTORY_LLVM_TARGET.get().unwrap())?;
|
|
|
|
if cfg!(target_arch = "x86_64") {
|
|
if cfg!(target_os = "linux") {
|
|
if target_env == TargetEnv::MUSL {
|
|
platforms::x86_64_linux_musl::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
enable_valgrind,
|
|
)?;
|
|
} else if target_env == TargetEnv::GNU {
|
|
platforms::x86_64_linux_gnu::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
enable_valgrind,
|
|
)?;
|
|
} else if target_env == TargetEnv::Emscripten {
|
|
platforms::wasm32_emscripten::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
enable_valgrind,
|
|
)?;
|
|
} else {
|
|
anyhow::bail!("Unsupported target environment for x86_64 and Linux");
|
|
}
|
|
} else if cfg!(target_os = "macos") {
|
|
platforms::x86_64_macos::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
)?;
|
|
} else if cfg!(target_os = "windows") {
|
|
platforms::x86_64_windows_msvc::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
)?;
|
|
} else {
|
|
anyhow::bail!("Unsupported target OS for x86_64");
|
|
}
|
|
} else if cfg!(target_arch = "aarch64") {
|
|
if cfg!(target_os = "linux") {
|
|
if target_env == TargetEnv::MUSL {
|
|
platforms::aarch64_linux_musl::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
enable_valgrind,
|
|
)?;
|
|
} else if target_env == TargetEnv::GNU {
|
|
platforms::aarch64_linux_gnu::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
enable_valgrind,
|
|
)?;
|
|
} else {
|
|
anyhow::bail!("Unsupported target environment for aarch64 and Linux");
|
|
}
|
|
} else if cfg!(target_os = "macos") {
|
|
if target_env == TargetEnv::Emscripten {
|
|
platforms::wasm32_emscripten::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
enable_valgrind,
|
|
)?;
|
|
} else {
|
|
platforms::aarch64_macos::build(
|
|
build_type,
|
|
targets,
|
|
llvm_projects,
|
|
enable_rtti,
|
|
default_target,
|
|
enable_tests,
|
|
enable_coverage,
|
|
extra_args,
|
|
ccache_variant,
|
|
enable_assertions,
|
|
sanitizer,
|
|
)?;
|
|
}
|
|
} else {
|
|
anyhow::bail!("Unsupported target OS for aarch64");
|
|
}
|
|
} else {
|
|
anyhow::bail!("Unsupported target architecture");
|
|
}
|
|
|
|
crate::builtins::build(
|
|
build_type,
|
|
target_env,
|
|
default_target,
|
|
extra_args,
|
|
ccache_variant,
|
|
sanitizer,
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Executes the build artifacts cleaning.
|
|
pub fn clean() -> anyhow::Result<()> {
|
|
let remove_if_exists = |path: &Path| {
|
|
if !path.exists() {
|
|
return Ok(());
|
|
}
|
|
log::info!("deleting {}", path.display());
|
|
std::fs::remove_dir_all(path)
|
|
};
|
|
|
|
remove_if_exists(
|
|
llvm_path::DIRECTORY_LLVM_TARGET
|
|
.get()
|
|
.expect("target_env is always set because of the default value")
|
|
.parent()
|
|
.expect("target_env parent directory is target-llvm"),
|
|
)?;
|
|
remove_if_exists(&PathBuf::from(LLVMPath::DIRECTORY_EMSDK_SOURCE))?;
|
|
remove_if_exists(&PathBuf::from(LLVMPath::DIRECTORY_LLVM_SOURCE))?;
|
|
remove_if_exists(&PathBuf::from(LLVMPath::DIRECTORY_LLVM_HOST_SOURCE))?;
|
|
|
|
Ok(())
|
|
}
|