refactor: ♻️ Add rust_toolchain.rs

This commit is contained in:
Sergio Gasquez 2022-09-19 10:15:22 +00:00
parent 9c3b973cf4
commit 6c32b5b8ef
6 changed files with 172 additions and 101 deletions

View File

@ -1,4 +1,4 @@
//! GCC Toolchain source and tools installation
//! GCC Toolchain source and installation tools
use crate::chip::Chip;
use crate::emoji;
@ -39,8 +39,7 @@ impl GccToolchain {
/// 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" => "zip",
"x86_64-pc-windows-gnu" => "zip",
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "zip",
_ => "tar.gz",
}
}
@ -83,7 +82,7 @@ impl GccToolchain {
Ok(())
}
/// Create a new instance with default values and proper toolchain_name.
/// Create a new instance with default values and proper toolchain name.
pub fn new(chip: Chip) -> Self {
Self {
repository_url: DEFAULT_GCC_REPOSITORY.to_string(),

View File

@ -1,4 +1,4 @@
//! LLVM Toolchain source and tools installation
//! LLVM Toolchain source and installation tools
use crate::emoji;
use crate::utils::{download_file, get_tool_path};
@ -6,8 +6,7 @@ use anyhow::Result;
use log::{info, warn};
use std::path::{Path, PathBuf};
const DEFAULT_LLVM_REPOSITORY: &str =
"https://github.com/espressif/llvm-project/releases/download/";
const DEFAULT_LLVM_REPOSITORY: &str = "https://github.com/espressif/llvm-project/releases/download";
pub struct LlvmToolchain {
/// The repository containing LVVM sources.
@ -104,10 +103,7 @@ impl LlvmToolchain {
Self::get_arch(host_triple).unwrap(),
Self::get_artifact_extension(host_triple)
);
let repository_url = format!(
"https://github.com/espressif/llvm-project/releases/download/{}/{}",
&release, file_name
);
let repository_url = format!("{}/{}/{}", DEFAULT_LLVM_REPOSITORY, &release, file_name);
let path = format!(
"{}/{}-{}",
get_tool_path("xtensa-esp32-elf-clang"),

View File

@ -1,11 +1,11 @@
use crate::chip::*;
use crate::llvm_toolchain::LlvmToolchain;
use crate::rust_toolchain::RustToolchain;
use crate::toolchain::*;
use crate::utils::*;
use anyhow::Result;
use clap::Parser;
use clap_verbosity_flag::{InfoLevel, Verbosity};
use embuild::cmd;
use log::{info, warn};
use std::fs::File;
use std::io::Write;
@ -15,8 +15,10 @@ mod chip;
mod emoji;
mod gcc_toolchain;
mod llvm_toolchain;
mod rust_toolchain;
mod toolchain;
mod utils;
#[derive(Parser)]
struct Opts {
#[clap(subcommand)]
@ -105,20 +107,7 @@ fn install(args: InstallOpts) -> Result<()> {
let targets: Vec<Chip> = parse_targets(&args.build_target).unwrap();
print_arguments(&args, arch, &targets);
let artifact_file_extension = get_artifact_llvm_extension(arch).to_string();
let rust_dist = format!("rust-{}-{}", args.toolchain_version, arch);
let rust_src_dist = format!("rust-src-{}", args.toolchain_version);
let rust_dist_file = format!("{}.{}", rust_dist, artifact_file_extension);
let rust_src_dist_file = format!("{}.{}", rust_src_dist, artifact_file_extension);
let rust_dist_url = format!(
"https://github.com/esp-rs/rust-build/releases/download/v{}/{}",
args.toolchain_version, rust_dist_file
);
let rust_src_dist_url = format!(
"https://github.com/esp-rs/rust-build/releases/download/v{}/{}",
args.toolchain_version, rust_src_dist_file
);
let rust_toolchain = RustToolchain::new(&args, arch, &targets);
let mut exports: Vec<String> = Vec::new();
@ -134,49 +123,15 @@ fn install(args: InstallOpts) -> Result<()> {
);
return Ok(());
} else {
// install_rust_xtensa_toolchain
// 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
info!("{} Installing Xtensa Rust toolchain", emoji::WRENCH);
if get_rust_installer(arch).to_string().is_empty() {
download_file(
rust_dist_url,
"rust.zip",
&args.toolchain_destination.display().to_string(),
true,
)?;
} else {
download_file(rust_dist_url, "rust.tar.xz", &get_dist_path("rust"), true)?;
info!("{} Installing rust esp toolchain", emoji::WRENCH);
let arguments = format!(
"{}/rust-nightly-{}/install.sh --destdir={} --prefix='' --without=rust-docs",
get_dist_path("rust"),
arch,
args.toolchain_destination.display()
);
cmd!("/bin/bash", "-c", arguments).run()?;
download_file(
rust_src_dist_url,
"rust-src.tar.xz",
&get_dist_path("rust-src"),
true,
)?;
info!("{} Installing rust-src for esp toolchain", emoji::WRENCH);
let arguments = format!(
"{}/rust-src-nightly/install.sh --destdir={} --prefix='' --without=rust-docs",
get_dist_path("rust-src"),
args.toolchain_destination.display()
);
cmd!("/bin/bash", "-c", arguments).run()?;
}
rust_toolchain.install_xtensa()?;
}
llvm.install()?;
exports.push(format!("export LIBCLANG_PATH=\"{}\"", &llvm.get_lib_path()));
if targets.contains(&Chip::ESP32C3) {
install_riscv_target(&args.nightly_version)?;
rust_toolchain.install_riscv_target()?;
}
if args.espidf_version.is_some() {

160
src/rust_toolchain.rs Normal file
View File

@ -0,0 +1,160 @@
//! Xtensa Rust Toolchain source and installation tools
use super::InstallOpts;
use crate::chip::Chip;
use crate::emoji;
use crate::utils::{download_file, get_dist_path};
use anyhow::Result;
use embuild::cmd;
use log::info;
use std::path::PathBuf;
const DEFAULT_XTENSA_RUST_REPOSITORY: &str =
"https://github.com/esp-rs/rust-build/releases/download";
pub struct RustToolchain {
/// Xtensa Rust toolchain file.
pub dist_file: String,
/// Xtensa Rust toolchain url.
pub dist_url: String,
/// Xtensa Src Rust toolchain file.
pub src_dist_file: String,
/// Xtensa Src Rust toolchain url.
pub src_dist_url: String,
/// ESP targets.
pub targets: Vec<Chip>,
/// Extra crates to install.
pub extra_crates: String,
/// Nightly version to install.
pub nightly_version: String,
/// Path to the cargo home directory.
pub cargo_home: PathBuf,
/// Path to the rustup home directory.
pub rustup_home: PathBuf,
/// Xtensa Rust toolchain destination path.
pub toolchain_destination: PathBuf,
/// Xtensa Rust Toolchain version.
pub version: String,
}
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 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 the RiscV target.
pub fn install_riscv_target(&self) -> Result<()> {
info!("{} Installing Riscv target", emoji::WRENCH);
cmd!(
"rustup",
"component",
"add",
"rust-src",
"--toolchain",
self.version.clone()
)
.run()?;
cmd!(
"rustup",
"target",
"add",
"--toolchain",
self.version.clone(),
"riscv32imac-unknown-none-elf"
)
.run()?;
Ok(())
}
/// Installs the Xtensa Rust toolchain.
pub fn install_xtensa(&self) -> Result<()> {
let host_triple = guess_host_triple::guess_host_triple().unwrap();
// 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() {
download_file(
self.dist_url.clone(),
"rust.zip",
&self.toolchain_destination.display().to_string(),
true,
)?;
} else {
download_file(
self.dist_url.clone(),
"rust.tar.xz",
&get_dist_path("rust"),
true,
)?;
info!("{} Installing rust esp toolchain", emoji::WRENCH);
let arguments = format!(
"{}/rust-nightly-{}/install.sh --destdir={} --prefix='' --without=rust-docs",
get_dist_path("rust"),
host_triple,
self.toolchain_destination.display()
);
cmd!("/bin/bash", "-c", arguments).run()?;
download_file(
self.src_dist_url.clone(),
"rust-src.tar.xz",
&get_dist_path("rust-src"),
true,
)?;
info!("{} Installing rust-src for esp toolchain", emoji::WRENCH);
let arguments = format!(
"{}/rust-src-nightly/install.sh --destdir={} --prefix='' --without=rust-docs",
get_dist_path("rust-src"),
self.toolchain_destination.display()
);
cmd!("/bin/bash", "-c", arguments).run()?;
}
Ok(())
}
// 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 version = args.toolchain_version.clone();
let dist = format!("rust-{}-{}", args.toolchain_version, arch);
let dist_file = format!("{}.{}", dist, artifact_extension);
let dist_url = format!(
"{}/v{}/{}",
DEFAULT_XTENSA_RUST_REPOSITORY, version, dist_file
);
let src_dist = format!("rust-src-{}", args.toolchain_version);
let src_dist_file = format!("{}.{}", src_dist, artifact_extension);
let src_dist_url = format!(
"{}/v{}/{}",
DEFAULT_XTENSA_RUST_REPOSITORY, version, src_dist_file
);
Self {
dist_file,
dist_url,
src_dist_file,
src_dist_url,
targets: targets.to_vec(),
extra_crates: args.extra_crates.clone(),
nightly_version: args.nightly_version.clone(),
cargo_home: args.cargo_home.clone(),
rustup_home: args.rustup_home.clone(),
toolchain_destination: args.toolchain_destination.clone(),
version,
}
}
}

View File

@ -34,29 +34,6 @@ pub fn check_rust_installation(nightly_version: &str) -> Result<()> {
Ok(())
}
pub fn install_riscv_target(version: &str) -> Result<()> {
info!("{} Installing Riscv target", emoji::WRENCH);
cmd!(
"rustup",
"component",
"add",
"rust-src",
"--toolchain",
version
)
.run()?;
cmd!(
"rustup",
"target",
"add",
"--toolchain",
version,
"riscv32imac-unknown-none-elf"
)
.run()?;
Ok(())
}
pub fn install_rustup(nightly_version: &str) -> Result<()> {
#[cfg(windows)]
let rustup_init_path = download_file(

View File

@ -44,22 +44,6 @@ pub fn parse_targets(build_target: &str) -> Result<Vec<Chip>, String> {
Ok(chips)
}
pub fn get_artifact_llvm_extension(arch: &str) -> &str {
match arch {
"x86_64-pc-windows-msvc" => "zip",
"x86_64-pc-windows-gnu" => "zip",
_ => "tar.xz",
}
}
pub fn get_rust_installer(arch: &str) -> &str {
match arch {
"x86_64-pc-windows-msvc" => "",
"x86_64-pc-windows-gnu" => "",
_ => "./install.sh",
}
}
pub fn get_home_dir() -> String {
home_dir().unwrap().display().to_string()
}