Skip to content

Commit

Permalink
Update LLVM and GCC (#256)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
SergioGasquez authored May 18, 2023
1 parent 79fa60b commit 80ae98a
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 48 deletions.
28 changes: 18 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,28 @@ async fn install(args: InstallOpts) -> Result<()> {
let export_file = get_export_file(args.export_file)?;
let mut exports: Vec<String> = 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
};
Expand Down Expand Up @@ -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));
}
Expand Down
6 changes: 3 additions & 3 deletions src/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
50 changes: 18 additions & 32 deletions src/toolchain/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 {
Expand All @@ -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,
}
}
}
Expand All @@ -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),
Expand Down Expand Up @@ -141,19 +126,21 @@ 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")
}
}
}

/// Gets the artifact extension based on the host triple.
fn get_artifact_extension(host_triple: &HostTriple) -> &str {
match host_triple {
HostTriple::X86_64PcWindowsMsvc | HostTriple::X86_64PcWindowsGnu => "zip",
_ => "tar.gz",
_ => "tar.xz",
}
}

Expand All @@ -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(
Expand Down
27 changes: 25 additions & 2 deletions src/toolchain/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -71,8 +74,28 @@ impl Llvm {
toolchain_path: &Path,
host_triple: &HostTriple,
extended: bool,
xtensa_rust_version: &str,
) -> Result<Self, Error> {
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::<u8>().unwrap(),
version.get(2).unwrap().as_str().parse::<u8>().unwrap(),
version.get(3).unwrap().as_str().parse::<u8>().unwrap(),
version.get(4).unwrap().as_str().parse::<u8>().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,
Expand Down
2 changes: 1 addition & 1 deletion src/toolchain/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)\.(?P<subpatch>0|[1-9]\d*)?$";
pub const RE_EXTENDED_SEMANTIC_VERSION: &str = r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)\.(?P<subpatch>0|[1-9]\d*)?$";
const RE_SEMANTIC_VERSION: &str =
r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)?$";

Expand Down

0 comments on commit 80ae98a

Please sign in to comment.