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 <sergio.gasquez@gmail.com>

* chore: format

---------

Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>
This commit is contained in:
David Alexander Bjerremose 2025-06-06 15:32:53 +02:00 committed by GitHub
parent 9fe5d21025
commit e078dacb47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 13 deletions

View File

@ -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

View File

@ -57,6 +57,9 @@ pub struct InstallOpts {
/// Xtensa Rust toolchain version.
#[arg(short = 'v', long)]
pub toolchain_version: Option<String>,
/// Crosstool-NG toolchain version, e.g. (14.2.0_20241119)
#[arg(short = 'c', long)]
pub crosstool_toolchain_version: Option<String>,
}
#[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<String>,
}

View File

@ -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?;

View File

@ -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<String>,
) -> 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<String>,
) -> 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};"), "");

View File

@ -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));
}
}