From e078dacb47ad74727fdcf19133a9b6181488430f Mon Sep 17 00:00:00 2001 From: David Alexander Bjerremose Date: Fri, 6 Jun 2025 15:32:53 +0200 Subject: [PATCH] feat: add Crosstools version parameter and update to latest Crosstools (#508) * feat: add option to specify crosstools version * feat: update to newest crosstool version * fix: re-add actual Rust toolchain * chore: format * docs: added CHANGELOG entries * chore: move to windows section only * docs: CHANGELOG review comments * chore: fix clippy across platforms * Update src/toolchain/gcc.rs Co-authored-by: Sergio Gasquez Arcos * chore: format --------- Co-authored-by: Sergio Gasquez Arcos --- CHANGELOG.md | 2 ++ src/cli.rs | 6 ++++++ src/main.rs | 2 +- src/toolchain/gcc.rs | 35 ++++++++++++++++++++++++++--------- src/toolchain/mod.rs | 16 +++++++++++++--- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4687302..27bdd8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Added option to specify Crosstool-NG version, using `-c` or `--crosstools-toolchain-version` ### Fixed ### Changed +- Updated default GCC / Crosstools version to latest, [`esp-14.2.0_20241119`](https://github.com/espressif/crosstool-NG/releases/tag/esp-14.2.0_20241119) (#508) ### Removed diff --git a/src/cli.rs b/src/cli.rs index aa1f8dd..12fd978 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -57,6 +57,9 @@ pub struct InstallOpts { /// Xtensa Rust toolchain version. #[arg(short = 'v', long)] pub toolchain_version: Option, + /// Crosstool-NG toolchain version, e.g. (14.2.0_20241119) + #[arg(short = 'c', long)] + pub crosstool_toolchain_version: Option, } #[derive(Debug, Parser)] @@ -67,4 +70,7 @@ pub struct UninstallOpts { /// Xtensa Rust toolchain name. #[arg(short = 'a', long, default_value = "esp")] pub name: String, + /// GCC toolchain version. + #[arg(short = 'c', long)] + pub crosstool_toolchain_version: Option, } diff --git a/src/main.rs b/src/main.rs index 8c913fe..922e3d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,7 +70,7 @@ async fn uninstall(args: UninstallOpts) -> Result<()> { if toolchain_dir.exists() { Llvm::uninstall(&toolchain_dir).await?; - uninstall_gcc_toolchains(&toolchain_dir).await?; + uninstall_gcc_toolchains(&toolchain_dir, args.crosstool_toolchain_version).await?; XtensaRust::uninstall(&toolchain_dir).await?; diff --git a/src/toolchain/gcc.rs b/src/toolchain/gcc.rs index 4fdcd8d..7e82194 100644 --- a/src/toolchain/gcc.rs +++ b/src/toolchain/gcc.rs @@ -16,7 +16,7 @@ use std::{env, fs::File}; use tokio::fs::remove_dir_all; const DEFAULT_GCC_REPOSITORY: &str = "https://github.com/espressif/crosstool-NG/releases/download"; -const DEFAULT_GCC_RELEASE: &str = "14.2.0_20240906"; +const DEFAULT_GCC_RELEASE: &str = "14.2.0_20241119"; pub const RISCV_GCC: &str = "riscv32-esp-elf"; pub const XTENSA_GCC: &str = "xtensa-esp-elf"; @@ -28,6 +28,8 @@ pub struct Gcc { pub arch: String, /// GCC Toolchain path. pub path: PathBuf, + /// GCC release version. + pub release_version: String, } impl Gcc { @@ -41,11 +43,18 @@ impl Gcc { } /// Create a new instance with default values and proper toolchain name. - pub fn new(arch: &str, host_triple: &HostTriple, toolchain_path: &Path) -> Self { + pub fn new( + arch: &str, + host_triple: &HostTriple, + toolchain_path: &Path, + release_version: Option, + ) -> Self { + let release_version = release_version.unwrap_or_else(|| DEFAULT_GCC_RELEASE.to_string()); + #[cfg(unix)] let path = toolchain_path .join(arch) - .join(format!("esp-{DEFAULT_GCC_RELEASE}")); + .join(format!("esp-{}", release_version)); #[cfg(windows)] let path: PathBuf = toolchain_path.into(); @@ -53,6 +62,7 @@ impl Gcc { host_triple: host_triple.clone(), arch: arch.to_string(), path, + release_version, } } } @@ -70,7 +80,7 @@ impl Installable for Gcc { let is_installed = self .path .join(&self.arch) - .join(DEFAULT_GCC_RELEASE) + .join(&self.release_version) .exists(); if is_installed { @@ -82,13 +92,13 @@ impl Installable for Gcc { let gcc_file = format!( "{}-{}-{}.{}", self.arch, - DEFAULT_GCC_RELEASE, + self.release_version, get_arch(&self.host_triple).unwrap(), extension ); let gcc_dist_url = format!( "{}/esp-{}/{}", - DEFAULT_GCC_REPOSITORY, DEFAULT_GCC_RELEASE, gcc_file + DEFAULT_GCC_REPOSITORY, self.release_version, gcc_file ); download_file( gcc_dist_url, @@ -103,7 +113,7 @@ impl Installable for Gcc { #[cfg(windows)] if cfg!(windows) { - File::create(self.path.join(&self.arch).join(DEFAULT_GCC_RELEASE))?; + File::create(self.path.join(&self.arch).join(&self.release_version))?; exports.push(format!( "$Env:PATH = \"{};\" + $Env:PATH", @@ -152,9 +162,16 @@ fn get_artifact_extension(host_triple: &HostTriple) -> &str { } /// Checks if the toolchain is pressent, if present uninstalls it. -pub async fn uninstall_gcc_toolchains(toolchain_path: &Path) -> Result<(), Error> { +pub async fn uninstall_gcc_toolchains( + toolchain_path: &Path, + release_version: Option, +) -> Result<(), Error> { info!("Uninstalling GCC"); + #[cfg_attr(not(windows), allow(unused_variables))] + // release_version is only used in the windows block, but is also being passed, and so clippy will complain if not marked unused across platforms + let release_version = release_version.unwrap_or_else(|| DEFAULT_GCC_RELEASE.to_string()); + let gcc_toolchains = vec![XTENSA_GCC, RISCV_GCC]; for toolchain in gcc_toolchains { @@ -166,7 +183,7 @@ pub async fn uninstall_gcc_toolchains(toolchain_path: &Path) -> Result<(), Error let gcc_version_path = format!( "{}\\esp-{}\\{}\\bin", gcc_path.display(), - DEFAULT_GCC_RELEASE, + release_version, toolchain ); updated_path = updated_path.replace(&format!("{gcc_version_path};"), ""); diff --git a/src/toolchain/mod.rs b/src/toolchain/mod.rs index 7805e71..c9f1c3c 100644 --- a/src/toolchain/mod.rs +++ b/src/toolchain/mod.rs @@ -283,7 +283,7 @@ pub async fn install(args: InstallOpts, install_mode: InstallMode) -> Result<()> &args.skip_version_parse, targets, &toolchain_dir, - args.toolchain_version, + args.crosstool_toolchain_version, ); check_rust_installation().await?; @@ -311,13 +311,23 @@ pub async fn install(args: InstallOpts, install_mode: InstallMode) -> Result<()> .iter() .any(|t| t == &Target::ESP32 || t == &Target::ESP32S2 || t == &Target::ESP32S3) { - let xtensa_gcc = Gcc::new(XTENSA_GCC, &host_triple, &toolchain_dir); + let xtensa_gcc = Gcc::new( + XTENSA_GCC, + &host_triple, + &toolchain_dir, + args.crosstool_toolchain_version.clone(), + ); to_install.push(Box::new(xtensa_gcc)); } // By default only install the Espressif RISC-V toolchain if the user explicitly wants to if args.esp_riscv_gcc && targets.iter().any(|t| t != &Target::ESP32) { - let riscv_gcc = Gcc::new(RISCV_GCC, &host_triple, &toolchain_dir); + let riscv_gcc = Gcc::new( + RISCV_GCC, + &host_triple, + &toolchain_dir, + args.crosstool_toolchain_version.clone(), + ); to_install.push(Box::new(riscv_gcc)); } }