From 80ae98ab0e69d15b7c3715499fa389842f221af8 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Arcos Date: Thu, 18 May 2023 10:43:18 +0200 Subject: [PATCH] Update LLVM and GCC (#256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ✨ Add support for LLVM 16 * feat: ✨ Add support for GCC 12 * feat: ✨ Update LLVM release * style: 🎨 Avoid having RELEASE and VERSION consts * feat: 🎨 Update target methdos name * feat: 🐛 Fix LLVM versions --- src/main.rs | 28 +++++++++++++++--------- src/targets.rs | 6 +++--- src/toolchain/gcc.rs | 50 ++++++++++++++++--------------------------- src/toolchain/llvm.rs | 27 +++++++++++++++++++++-- src/toolchain/rust.rs | 2 +- 5 files changed, 65 insertions(+), 48 deletions(-) diff --git a/src/main.rs b/src/main.rs index 81ade276..cd8f9f8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -146,20 +146,28 @@ async fn install(args: InstallOpts) -> Result<()> { let export_file = get_export_file(args.export_file)?; let mut exports: Vec = Vec::new(); let host_triple = get_host_triple(args.default_host)?; + let xtensa_rust_version = if let Some(toolchain_version) = &args.toolchain_version { + toolchain_version.clone() + } else { + XtensaRust::get_latest_version().await? + }; let install_path = get_rustup_home().join("toolchains").join(args.name); - let llvm = Llvm::new(&install_path, &host_triple, args.extended_llvm)?; + let llvm: Llvm = Llvm::new( + &install_path, + &host_triple, + args.extended_llvm, + &xtensa_rust_version, + )?; let targets = args.targets; let xtensa_rust = if targets.contains(&Target::ESP32) || targets.contains(&Target::ESP32S2) || targets.contains(&Target::ESP32S3) { - let xtensa_rust: XtensaRust = if let Some(toolchain_version) = &args.toolchain_version { - XtensaRust::new(toolchain_version, &host_triple, &install_path) - } else { - let latest_version = XtensaRust::get_latest_version().await?; - XtensaRust::new(&latest_version, &host_triple, &install_path) - }; - Some(xtensa_rust) + Some(XtensaRust::new( + &xtensa_rust_version, + &host_triple, + &install_path, + )) } else { None }; @@ -197,14 +205,14 @@ async fn install(args: InstallOpts) -> Result<()> { to_install.push(Box::new(llvm)); - if targets.iter().any(|t| t.riscv()) { + if targets.iter().any(|t| t.is_riscv()) { let riscv_target = RiscVTarget::new(&args.nightly_version); to_install.push(Box::new(riscv_target)); } if !args.std { targets.iter().for_each(|target| { - if target.xtensa() { + if target.is_xtensa() { let gcc = Gcc::new(target, &host_triple, &install_path); to_install.push(Box::new(gcc)); } diff --git a/src/targets.rs b/src/targets.rs index d82a60b8..7bdf0c36 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -27,12 +27,12 @@ pub enum Target { impl Target { /// Returns true if the target is a RISC-V based chip. - pub fn riscv(&self) -> bool { - !self.xtensa() + pub fn is_riscv(&self) -> bool { + !self.is_xtensa() } /// Returns true if the target is a Xtensa based chip. - pub fn xtensa(&self) -> bool { + pub fn is_xtensa(&self) -> bool { matches!(self, Target::ESP32 | Target::ESP32S2 | Target::ESP32S3) } } diff --git a/src/toolchain/gcc.rs b/src/toolchain/gcc.rs index 2a4c6fcf..69fa907a 100644 --- a/src/toolchain/gcc.rs +++ b/src/toolchain/gcc.rs @@ -16,8 +16,7 @@ use std::{ }; const DEFAULT_GCC_REPOSITORY: &str = "https://github.com/espressif/crosstool-NG/releases/download"; -const DEFAULT_GCC_RELEASE: &str = "esp-2021r2-patch5"; -const DEFAULT_GCC_VERSION: &str = "8_4_0"; +const DEFAULT_GCC_RELEASE: &str = "12.2.0_20230208"; pub const ESP32_GCC: &str = "xtensa-esp32-elf"; pub const ESP32S2_GCC: &str = "xtensa-esp32s2-elf"; pub const ESP32S3_GCC: &str = "xtensa-esp32s3-elf"; @@ -29,14 +28,8 @@ pub struct Gcc { pub host_triple: HostTriple, /// GCC Toolchain name. pub name: String, - /// Repository release version to use. - pub release: String, - /// The repository containing GCC sources. - pub repository_url: String, /// GCC Toolchain path. pub path: PathBuf, - /// GCC Version. - pub version: String, } impl Gcc { @@ -48,38 +41,28 @@ impl Gcc { /// Create a new instance with default values and proper toolchain name. pub fn new(target: &Target, host_triple: &HostTriple, toolchain_path: &Path) -> Self { let name = get_gcc_name(target); - let version = DEFAULT_GCC_VERSION.to_string(); - let release = DEFAULT_GCC_RELEASE.to_string(); let path = toolchain_path .join(&name) - .join(format!("{release}-{version}")); + .join(format!("esp-{DEFAULT_GCC_RELEASE}")); Self { host_triple: host_triple.clone(), name, - release, - repository_url: DEFAULT_GCC_REPOSITORY.to_string(), path, - version, } } /// Create a new instance of RISC-V GCC with default values and proper toolchain name. pub fn new_riscv(host_triple: &HostTriple, toolchain_path: &Path) -> Self { - let version = DEFAULT_GCC_VERSION.to_string(); - let release = DEFAULT_GCC_RELEASE.to_string(); let name = RISCV_GCC.to_string(); let path = toolchain_path .join(&name) - .join(format!("{release}-{version}")); + .join(format!("esp-{DEFAULT_GCC_RELEASE}")); Self { host_triple: host_triple.clone(), name, - release, - repository_url: DEFAULT_GCC_REPOSITORY.to_string(), path, - version, } } } @@ -97,14 +80,16 @@ impl Installable for Gcc { ); } else { let gcc_file = format!( - "{}-gcc{}-{}-{}.{}", + "{}-{}-{}.{}", self.name, - self.version, - self.release, + DEFAULT_GCC_RELEASE, get_arch(&self.host_triple).unwrap(), extension ); - let gcc_dist_url = format!("{}/{}/{}", self.repository_url, self.release, gcc_file); + let gcc_dist_url = format!( + "{}/esp-{}/{}", + DEFAULT_GCC_REPOSITORY, DEFAULT_GCC_RELEASE, gcc_file + ); download_file( gcc_dist_url, &format!("{}.{}", &self.name, extension), @@ -141,11 +126,13 @@ impl Installable for Gcc { /// Gets the name of the GCC arch based on the host triple. fn get_arch(host_triple: &HostTriple) -> Result<&str> { match host_triple { - HostTriple::X86_64AppleDarwin => Ok("macos"), - HostTriple::Aarch64AppleDarwin => Ok("macos-arm64"), - HostTriple::X86_64UnknownLinuxGnu => Ok("linux-amd64"), - HostTriple::Aarch64UnknownLinuxGnu => Ok("linux-arm64"), - HostTriple::X86_64PcWindowsMsvc | HostTriple::X86_64PcWindowsGnu => Ok("win64"), + HostTriple::X86_64AppleDarwin => Ok("x86_64-apple-darwin"), + HostTriple::Aarch64AppleDarwin => Ok("aarch64-apple-darwin"), + HostTriple::X86_64UnknownLinuxGnu => Ok("x86_64-linux-gnu"), + HostTriple::Aarch64UnknownLinuxGnu => Ok("aarch64-linux-gnu"), + HostTriple::X86_64PcWindowsMsvc | HostTriple::X86_64PcWindowsGnu => { + Ok("x86_64-w64-mingw32") + } } } @@ -153,7 +140,7 @@ fn get_arch(host_triple: &HostTriple) -> Result<&str> { fn get_artifact_extension(host_triple: &HostTriple) -> &str { match host_triple { HostTriple::X86_64PcWindowsMsvc | HostTriple::X86_64PcWindowsGnu => "zip", - _ => "tar.gz", + _ => "tar.xz", } } @@ -180,10 +167,9 @@ pub fn uninstall_gcc_toolchains(toolchain_path: &Path) -> Result<(), Error> { #[cfg(windows)] if cfg!(windows) { let gcc_path = format!( - "{}\\{}-{}\\{}\\bin", + "{}\\esp-{}\\{}\\bin", gcc_path.display(), DEFAULT_GCC_RELEASE, - DEFAULT_GCC_VERSION, toolchain ); std::env::set_var( diff --git a/src/toolchain/llvm.rs b/src/toolchain/llvm.rs index df81d561..34155cc4 100644 --- a/src/toolchain/llvm.rs +++ b/src/toolchain/llvm.rs @@ -6,18 +6,21 @@ use crate::{ emoji, error::Error, host_triple::HostTriple, - toolchain::{download_file, Installable}, + toolchain::{download_file, rust::RE_EXTENDED_SEMANTIC_VERSION, Installable}, }; use async_trait::async_trait; use log::{info, warn}; use miette::Result; +use regex::Regex; use std::{ fs::remove_dir_all, path::{Path, PathBuf}, + u8, }; const DEFAULT_LLVM_REPOSITORY: &str = "https://github.com/espressif/llvm-project/releases/download"; const DEFAULT_LLVM_15_VERSION: &str = "esp-15.0.0-20221201"; +const DEFAULT_LLVM_16_VERSION: &str = "esp-16.0.0-20230516"; pub const CLANG_NAME: &str = "xtensa-esp32-elf-clang"; #[derive(Debug, Clone, Default)] @@ -71,8 +74,28 @@ impl Llvm { toolchain_path: &Path, host_triple: &HostTriple, extended: bool, + xtensa_rust_version: &str, ) -> Result { - let version = DEFAULT_LLVM_15_VERSION.to_string(); + let re_extended: Regex = Regex::new(RE_EXTENDED_SEMANTIC_VERSION).unwrap(); + let (major, minor, patch, subpatch) = match re_extended.captures(xtensa_rust_version) { + Some(version) => ( + version.get(1).unwrap().as_str().parse::().unwrap(), + version.get(2).unwrap().as_str().parse::().unwrap(), + version.get(3).unwrap().as_str().parse::().unwrap(), + version.get(4).unwrap().as_str().parse::().unwrap(), + ), + None => return Err(Error::InvalidVersion(xtensa_rust_version.to_string())), + }; + + // Use LLVM 15 for versions 1.69.0.0 and below + let version = if (major == 1 && minor == 69 && patch == 0 && subpatch == 0) + || (major == 1 && minor < 69) + { + DEFAULT_LLVM_15_VERSION.to_string() + } else { + DEFAULT_LLVM_16_VERSION.to_string() + }; + let mut file_name = format!( "llvm-{}-{}.tar.xz", version, diff --git a/src/toolchain/rust.rs b/src/toolchain/rust.rs index a5e33391..996a728e 100644 --- a/src/toolchain/rust.rs +++ b/src/toolchain/rust.rs @@ -34,7 +34,7 @@ const XTENSA_RUST_LATEST_API_URL: &str = const XTENSA_RUST_API_URL: &str = "https://api.github.com/repos/esp-rs/rust-build/releases"; /// Xtensa Rust Toolchain version regex. -const RE_EXTENDED_SEMANTIC_VERSION: &str = r"^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)?$"; +pub const RE_EXTENDED_SEMANTIC_VERSION: &str = r"^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)?$"; const RE_SEMANTIC_VERSION: &str = r"^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)?$";