mirror of
https://github.com/esp-rs/espup.git
synced 2025-10-02 07:10:36 +00:00
147 lines
4.8 KiB
Rust
147 lines
4.8 KiB
Rust
//! GCC Toolchain source and installation tools
|
|
|
|
use crate::{
|
|
emoji,
|
|
host_triple::HostTriple,
|
|
targets::Target,
|
|
toolchain::{download_file, espidf::get_tool_path},
|
|
};
|
|
use anyhow::Result;
|
|
use embuild::espidf::EspIdfVersion;
|
|
use log::{debug, info};
|
|
use std::collections::HashSet;
|
|
|
|
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";
|
|
|
|
#[derive(Debug)]
|
|
pub struct GccToolchain {
|
|
/// Host triple.
|
|
pub host_triple: HostTriple,
|
|
/// Repository release version to use.
|
|
pub release: String,
|
|
/// The repository containing GCC sources.
|
|
pub repository_url: String,
|
|
/// GCC Toolchain target.
|
|
pub toolchain_name: String,
|
|
/// GCC Version.
|
|
pub version: String,
|
|
}
|
|
|
|
impl GccToolchain {
|
|
/// Gets the binary path.
|
|
pub fn get_bin_path(&self) -> String {
|
|
let toolchain_path = format!(
|
|
"{}/{}-{}/{}/bin",
|
|
&self.toolchain_name, self.release, self.version, &self.toolchain_name
|
|
);
|
|
get_tool_path(&toolchain_path)
|
|
}
|
|
|
|
/// Installs the gcc toolchain.
|
|
pub fn install(&self) -> Result<()> {
|
|
let target_dir = format!("{}/{}-{}", self.toolchain_name, self.release, self.version);
|
|
|
|
let gcc_path = get_tool_path(&target_dir);
|
|
let extension = get_artifact_extension(&self.host_triple);
|
|
debug!("{} GCC path: {}", emoji::DEBUG, gcc_path);
|
|
let gcc_file = format!(
|
|
"{}-gcc{}-{}-{}.{}",
|
|
self.toolchain_name,
|
|
self.version,
|
|
self.release,
|
|
get_arch(&self.host_triple).unwrap(),
|
|
extension
|
|
);
|
|
let gcc_dist_url = format!("{}/{}/{}", self.repository_url, self.release, gcc_file);
|
|
download_file(
|
|
gcc_dist_url,
|
|
&format!("{}.{}", &self.toolchain_name, extension),
|
|
&gcc_path,
|
|
true,
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Create a new instance with default values and proper toolchain name.
|
|
pub fn new(target: Target, host_triple: &HostTriple) -> Self {
|
|
Self {
|
|
host_triple: host_triple.clone(),
|
|
release: DEFAULT_GCC_RELEASE.to_string(),
|
|
repository_url: DEFAULT_GCC_REPOSITORY.to_string(),
|
|
toolchain_name: get_toolchain_name(target),
|
|
version: DEFAULT_GCC_VERSION.to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Gets the name of the GCC arch based on the host triple.
|
|
fn get_arch(host_triple: &HostTriple) -> Result<&str> {
|
|
match host_triple {
|
|
HostTriple::Aarch64AppleDarwin | HostTriple::X86_64AppleDarwin => Ok("macos"),
|
|
HostTriple::X86_64UnknownLinuxGnu => Ok("linux-amd64"),
|
|
HostTriple::Aarch64UnknownLinuxGnu => Ok("linux-arm64"),
|
|
HostTriple::X86_64PcWindowsMsvc | HostTriple::X86_64PcWindowsGnu => Ok("win64"),
|
|
}
|
|
}
|
|
|
|
/// 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.xz",
|
|
}
|
|
}
|
|
|
|
/// Gets the toolchain name based on the Target
|
|
pub fn get_toolchain_name(target: Target) -> String {
|
|
match target {
|
|
Target::ESP32 => "xtensa-esp32-elf".to_string(),
|
|
Target::ESP32S2 => "xtensa-esp32s2-elf".to_string(),
|
|
Target::ESP32S3 => "xtensa-esp32s3-elf".to_string(),
|
|
Target::ESP32C3 => "riscv32-esp-elf".to_string(),
|
|
}
|
|
}
|
|
|
|
/// Gets the toolchain name based on the Target
|
|
pub fn get_ulp_toolchain_name(target: Target, version: Option<&EspIdfVersion>) -> Option<String> {
|
|
match target {
|
|
Target::ESP32 => Some("esp32ulp-elf".to_string()),
|
|
Target::ESP32S2 | Target::ESP32S3 => Some(
|
|
if version
|
|
.map(|version| {
|
|
version.major > 4
|
|
|| version.major == 4 && version.minor > 4
|
|
|| version.major == 4 && version.minor == 4 && version.patch >= 2
|
|
})
|
|
.unwrap_or(true)
|
|
{
|
|
"esp32ulp-elf".to_string()
|
|
} else {
|
|
"esp32s2ulp-elf".to_string()
|
|
},
|
|
),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
/// Installs GCC toolchain the selected targets.
|
|
pub fn install_gcc_targets(
|
|
targets: HashSet<Target>,
|
|
host_triple: &HostTriple,
|
|
) -> Result<Vec<String>> {
|
|
info!("{} Installing gcc for build targets", emoji::WRENCH);
|
|
let mut exports: Vec<String> = Vec::new();
|
|
for target in targets {
|
|
let gcc = GccToolchain::new(target, host_triple);
|
|
gcc.install()?;
|
|
|
|
#[cfg(windows)]
|
|
exports.push(format!("$Env:PATH += \";{}\"", gcc.get_bin_path()));
|
|
#[cfg(unix)]
|
|
exports.push(format!("export PATH={}:$PATH", gcc.get_bin_path()));
|
|
}
|
|
Ok(exports)
|
|
}
|