refactor: ♻️ Delete toolchain.rs

This commit is contained in:
Sergio Gasquez 2022-09-20 09:41:31 +00:00
parent 6fb6dae738
commit 8f1f26ba00
5 changed files with 197 additions and 217 deletions

View File

@ -2,11 +2,11 @@
use crate::chip::Chip;
use crate::emoji;
use crate::gcc_toolchain::GccToolchain;
use crate::gcc_toolchain::{get_toolchain_name, get_ulp_toolchain_name};
use crate::utils::get_tools_path;
use anyhow::{Context, Result};
use embuild::{espidf, git};
use log::debug;
use log::{debug, info};
use std::path::PathBuf;
use strum::{Display, EnumIter, EnumString, IntoStaticStr};
@ -52,17 +52,7 @@ pub struct EspIdf {
}
impl EspIdf {
pub fn get_install_path(version: &str) -> String {
let parsed_version: String = version
.chars()
.map(|x| match x {
'/' => '-',
_ => x,
})
.collect();
format!("{}/frameworks/esp-idf-{}", get_tools_path(), parsed_version)
}
/// Create a new instance with the propper arguments.
pub fn new(version: &str, minified: bool, targets: Vec<Chip>) -> EspIdf {
let install_path = PathBuf::from(get_tools_path());
debug!(
@ -79,6 +69,7 @@ impl EspIdf {
}
}
/// Installs esp-idf.
pub fn install(self) -> Result<()> {
let cmake_generator = DEFAULT_CMAKE_GENERATOR;
@ -86,8 +77,9 @@ impl EspIdf {
let make_tools = move |repo: &git::Repository,
version: &Result<espidf::EspIdfVersion>|
-> Result<Vec<espidf::Tools>> {
eprintln!(
"Using esp-idf {} at '{}'",
info!(
"{} Using esp-idf {} at '{}'",
emoji::INFO,
espidf::EspIdfVersion::format(version),
repo.worktree().display()
);
@ -95,11 +87,10 @@ impl EspIdf {
let mut tools = vec![];
let mut subtools = Vec::new();
for target in self.targets.clone() {
let gcc_toolchain_name = GccToolchain::get_toolchain_name(target);
let gcc_toolchain_name = get_toolchain_name(target);
subtools.push(gcc_toolchain_name);
let ulp_toolchain_name =
GccToolchain::get_ulp_toolchain_name(target, version.as_ref().ok());
let ulp_toolchain_name = get_ulp_toolchain_name(target, version.as_ref().ok());
if !cfg!(target_os = "linux") || !cfg!(target_arch = "aarch64") {
if let Some(ulp_toolchain_name) = ulp_toolchain_name {
subtools.push(ulp_toolchain_name);

View File

@ -23,76 +23,22 @@ pub struct GccToolchain {
}
impl GccToolchain {
/// Gets the name of the GCC arch based on the host triple.
fn get_arch(host_triple: &str) -> Result<&str, String> {
match host_triple {
"aarch64-apple-darwin" | "x86_64-apple-darwin" => Ok("macos"),
"aarch64-unknown-linux-gnu" => Ok("linux-arm64"),
"x86_64-unknown-linux-gnu" => Ok("linux-amd64"),
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => Ok("win64"),
_ => Err(format!(
"No GCC arch found for the host triple: {}",
host_triple
)),
}
}
/// Gets the artifact extension based on the host architecture.
fn get_artifact_extension(host_triple: &str) -> &str {
match host_triple {
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "zip",
_ => "tar.gz",
}
}
/// Gets the binary path.
pub fn get_bin_path(&self) -> String {
format!("{}/bin", get_tool_path(&self.toolchain_name))
}
/// Gets the toolchain name based on the Chip
pub fn get_toolchain_name(chip: Chip) -> String {
match chip {
Chip::ESP32 => "xtensa-esp32-elf".to_string(),
Chip::ESP32S2 => "xtensa-esp32s2-elf".to_string(),
Chip::ESP32S3 => "xtensa-esp32s3-elf".to_string(),
Chip::ESP32C3 => "riscv32-esp-elf".to_string(),
}
}
/// Gets the toolchain name based on the Chip
pub fn get_ulp_toolchain_name(chip: Chip, version: Option<&EspIdfVersion>) -> Option<String> {
match chip {
Chip::ESP32 => Some("esp32ulp-elf".to_string()),
Chip::ESP32S2 | Chip::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 the gcc toolchain.
pub fn install(&self) -> Result<()> {
let gcc_path = get_tool_path(&self.toolchain_name);
let host_triple = guess_host_triple::guess_host_triple().unwrap();
let extension = Self::get_artifact_extension(host_triple);
let extension = get_artifact_extension(host_triple);
debug!("{} GCC path: {}", emoji::DEBUG, gcc_path);
let gcc_file = format!(
"{}-{}-{}.{}",
self.toolchain_name,
self.version,
Self::get_arch(host_triple).unwrap(),
get_arch(host_triple).unwrap(),
extension
);
let gcc_dist_url = format!("{}/{}/{}", self.repository_url, self.release, gcc_file);
@ -111,7 +57,72 @@ impl GccToolchain {
repository_url: DEFAULT_GCC_REPOSITORY.to_string(),
release: DEFAULT_GCC_RELEASE.to_string(),
version: DEFAULT_GCC_VERSION.to_string(),
toolchain_name: Self::get_toolchain_name(chip),
toolchain_name: get_toolchain_name(chip),
}
}
}
/// Gets the name of the GCC arch based on the host triple.
fn get_arch(host_triple: &str) -> Result<&str, String> {
match host_triple {
"aarch64-apple-darwin" | "x86_64-apple-darwin" => Ok("macos"),
"aarch64-unknown-linux-gnu" => Ok("linux-arm64"),
"x86_64-unknown-linux-gnu" => Ok("linux-amd64"),
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => Ok("win64"),
_ => Err(format!(
"No GCC arch found for the host triple: {}",
host_triple
)),
}
}
/// Gets the artifact extension based on the host architecture.
fn get_artifact_extension(host_triple: &str) -> &str {
match host_triple {
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "zip",
_ => "tar.gz",
}
}
/// Gets the toolchain name based on the Chip
pub fn get_toolchain_name(chip: Chip) -> String {
match chip {
Chip::ESP32 => "xtensa-esp32-elf".to_string(),
Chip::ESP32S2 => "xtensa-esp32s2-elf".to_string(),
Chip::ESP32S3 => "xtensa-esp32s3-elf".to_string(),
Chip::ESP32C3 => "riscv32-esp-elf".to_string(),
}
}
/// Gets the toolchain name based on the Chip
pub fn get_ulp_toolchain_name(chip: Chip, version: Option<&EspIdfVersion>) -> Option<String> {
match chip {
Chip::ESP32 => Some("esp32ulp-elf".to_string()),
Chip::ESP32S2 | Chip::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 chips.
pub fn install_gcc_targets(targets: Vec<Chip>) -> Result<Vec<String>> {
let mut exports: Vec<String> = Vec::new();
for target in targets {
let gcc = GccToolchain::new(target);
gcc.install()?;
exports.push(format!("export PATH={}:$PATH", gcc.get_bin_path()));
}
Ok(exports)
}

View File

@ -1,8 +1,8 @@
use crate::chip::*;
use crate::espidf::EspIdf;
use crate::gcc_toolchain::install_gcc_targets;
use crate::llvm_toolchain::LlvmToolchain;
use crate::rust_toolchain::RustToolchain;
use crate::toolchain::*;
use crate::rust_toolchain::{check_rust_installation, RustToolchain};
use crate::utils::*;
use anyhow::Result;
use clap::Parser;
@ -142,11 +142,7 @@ fn install(args: InstallOpts) -> Result<()> {
let espidf = EspIdf::new(&espidf_version, args.minified_espidf, targets);
espidf.install()?;
exports.push(format!("export IDF_TOOLS_PATH=\"{}\"", get_tools_path()));
// TODO: Fix the export path
exports.push(format!(
"source {}/export.sh",
EspIdf::get_install_path(&espidf_version)
));
// exports.push(format!("source {}/export.sh", install_path.display()));
rust_toolchain.install_extra_crate("ldproxy")?;
} else {
info!("{} Installing gcc for build targets", emoji::WRENCH);

View File

@ -4,10 +4,11 @@ use super::InstallOpts;
use crate::chip::Chip;
use crate::emoji;
use crate::utils::{download_file, get_dist_path};
use anyhow::Result;
use anyhow::{bail, Result};
use embuild::cmd;
use log::{info, warn};
use std::path::PathBuf;
use std::process::Stdio;
const DEFAULT_XTENSA_RUST_REPOSITORY: &str =
"https://github.com/esp-rs/rust-build/releases/download";
@ -38,32 +39,6 @@ pub struct RustToolchain {
}
impl RustToolchain {
/// Gets the artifact extension based on the host architecture.
fn get_artifact_extension(host_triple: &str) -> &str {
match host_triple {
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "zip",
_ => "tar.xz",
}
}
/// Gets the default cargo home path.
fn get_default_cargo_home() -> PathBuf {
dirs::home_dir().unwrap().join(".cargo")
}
/// Gets the default rustup home path.
fn get_default_rustup_home() -> PathBuf {
dirs::home_dir().unwrap().join(".rustup")
}
/// Gets the installer file.
pub fn get_installer(host_triple: &str) -> &str {
match host_triple {
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "",
_ => "./install.sh",
}
}
/// Installs an extra crate.
pub fn install_extra_crate(&self, crate_name: &str) -> Result<()> {
info!("{} Installing {} crate", emoji::WRENCH, crate_name);
@ -111,7 +86,7 @@ impl RustToolchain {
// Some platfroms like Windows are available in single bundle rust + src, because install
// script in dist is not available for the plaform. It's sufficient to extract the toolchain
if Self::get_installer(host_triple).to_string().is_empty() {
if get_installer(host_triple).to_string().is_empty() {
download_file(
self.dist_url.clone(),
"rust.zip",
@ -154,7 +129,7 @@ impl RustToolchain {
// TODO: Some fields are not needed in Windows
/// Create a new instance.
pub fn new(args: &InstallOpts, arch: &str, targets: &[Chip]) -> Self {
let artifact_extension = Self::get_artifact_extension(arch);
let artifact_extension = get_artifact_extension(arch);
let version = args.toolchain_version.clone();
let dist = format!("rust-{}-{}", args.toolchain_version, arch);
let dist_file = format!("{}.{}", dist, artifact_extension);
@ -171,11 +146,11 @@ impl RustToolchain {
let cargo_home = args
.cargo_home
.clone()
.unwrap_or_else(Self::get_default_cargo_home);
.unwrap_or_else(get_default_cargo_home);
let rustup_home = args
.rustup_home
.clone()
.unwrap_or_else(Self::get_default_rustup_home);
.unwrap_or_else(get_default_rustup_home);
let toolchain_destination = args
.toolchain_destination
.clone()
@ -195,3 +170,114 @@ impl RustToolchain {
}
}
}
/// Gets the artifact extension based on the host architecture.
fn get_artifact_extension(host_triple: &str) -> &str {
match host_triple {
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "zip",
_ => "tar.xz",
}
}
/// Gets the default cargo home path.
fn get_default_cargo_home() -> PathBuf {
dirs::home_dir().unwrap().join(".cargo")
}
/// Gets the default rustup home path.
fn get_default_rustup_home() -> PathBuf {
dirs::home_dir().unwrap().join(".rustup")
}
/// Gets the installer file.
fn get_installer(host_triple: &str) -> &str {
match host_triple {
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "",
_ => "./install.sh",
}
}
pub fn check_rust_installation(nightly_version: &str) -> Result<()> {
match std::process::Command::new("rustup")
.arg("toolchain")
.arg("list")
.stdout(Stdio::piped())
.output()
{
Ok(child_output) => {
let result = String::from_utf8_lossy(&child_output.stdout);
if !result.contains("nightly") {
warn!("{} Rust nightly toolchain not found", emoji::WARN);
install_rust_nightly(nightly_version)?;
}
}
Err(e) => {
if let std::io::ErrorKind::NotFound = e.kind() {
warn!("{} rustup was not found.", emoji::WARN);
install_rustup(nightly_version)?;
} else {
bail!("{} Error: {}", emoji::ERROR, e);
}
}
}
Ok(())
}
fn install_rustup(nightly_version: &str) -> Result<()> {
#[cfg(windows)]
let rustup_init_path = download_file(
"https://win.rustup.rs/x86_64".to_string(),
"rustup-init.exe",
&get_dist_path("rustup"),
false,
)?;
#[cfg(unix)]
let rustup_init_path = download_file(
"https://sh.rustup.rs".to_string(),
"rustup-init.sh",
&get_dist_path("rustup"),
false,
)?;
info!(
"{} Installing rustup with {} toolchain",
emoji::WRENCH,
nightly_version
);
#[cfg(windows)]
cmd!(
rustup_init_path,
"--default-toolchain",
nightly_version,
"--profile",
"minimal",
"-y"
)
.run()?;
#[cfg(not(windows))]
cmd!(
"/bin/bash",
rustup_init_path,
"--default-toolchain",
nightly_version,
"--profile",
"minimal",
"-y"
)
.run()?;
Ok(())
}
fn install_rust_nightly(version: &str) -> Result<()> {
info!("{} Installing {} toolchain", emoji::WRENCH, version);
cmd!(
"rustup",
"toolchain",
"install",
version,
"--profile",
"minimal"
)
.run()?;
Ok(())
}

View File

@ -1,104 +0,0 @@
use crate::chip::Chip;
use crate::emoji;
use crate::gcc_toolchain::GccToolchain;
use crate::utils::*;
use anyhow::{bail, Result};
use embuild::cmd;
use log::{info, warn};
use std::process::Stdio;
pub fn check_rust_installation(nightly_version: &str) -> Result<()> {
match std::process::Command::new("rustup")
.arg("toolchain")
.arg("list")
.stdout(Stdio::piped())
.output()
{
Ok(child_output) => {
let result = String::from_utf8_lossy(&child_output.stdout);
if !result.contains("nightly") {
warn!("{} Rust nightly toolchain not found", emoji::WARN);
install_rust_nightly(nightly_version)?;
}
}
Err(e) => {
if let std::io::ErrorKind::NotFound = e.kind() {
warn!("{} rustup was not found.", emoji::WARN);
install_rustup(nightly_version)?;
} else {
bail!("{} Error: {}", emoji::ERROR, e);
}
}
}
Ok(())
}
pub fn install_rustup(nightly_version: &str) -> Result<()> {
#[cfg(windows)]
let rustup_init_path = download_file(
"https://win.rustup.rs/x86_64".to_string(),
"rustup-init.exe",
&get_dist_path("rustup"),
false,
)?;
#[cfg(unix)]
let rustup_init_path = download_file(
"https://sh.rustup.rs".to_string(),
"rustup-init.sh",
&get_dist_path("rustup"),
false,
)?;
info!(
"{} Installing rustup with {} toolchain",
emoji::WRENCH,
nightly_version
);
#[cfg(windows)]
// TO BE TESTED
cmd!(
rustup_init_path,
"--default-toolchain",
nightly_version,
"--profile",
"minimal",
"-y"
)
.run()?;
#[cfg(not(windows))]
cmd!(
"/bin/bash",
rustup_init_path,
"--default-toolchain",
nightly_version,
"--profile",
"minimal",
"-y"
)
.run()?;
Ok(())
}
pub fn install_rust_nightly(version: &str) -> Result<()> {
info!("{} Installing {} toolchain", emoji::WRENCH, version);
cmd!(
"rustup",
"toolchain",
"install",
version,
"--profile",
"minimal"
)
.run()?;
Ok(())
}
pub fn install_gcc_targets(targets: Vec<Chip>) -> Result<Vec<String>> {
let mut exports: Vec<String> = Vec::new();
for target in targets {
let gcc = GccToolchain::new(target);
gcc.install()?;
exports.push(format!("export PATH={}:$PATH", gcc.get_bin_path()));
}
Ok(exports)
}