Skip to content

Commit

Permalink
Merge pull request #12 from esp-rs/feature/default-host-arg
Browse files Browse the repository at this point in the history
Add `default-host` argument
  • Loading branch information
SergioGasquez authored Oct 17, 2022
2 parents f61933c + 2da07d9 commit 2bbb89f
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 78 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ log = "0.4.17"
env_logger = "0.9.0"
embuild = { version = "0.30.4", features = ["espidf", "git"] }
strum = { version = "0.24", features = ["derive"] }
strum_macros = "0.24.3"

[target.aarch64-unknown-linux-gnu.dependencies]
openssl = { version = "0.10", features = ["vendored"] }
Expand Down
42 changes: 42 additions & 0 deletions src/host_triple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::emoji;
use anyhow::{Context, Result};
use guess_host_triple::guess_host_triple;
use std::str::FromStr;
use strum::Display;
use strum_macros::EnumString;

#[derive(Display, Debug, Clone, EnumString)]
pub enum HostTriple {
/// 64-bit Linux
#[strum(serialize = "x86_64-unknown-linux-gnu")]
X86_64UnknownLinuxGnu = 0,
/// ARM64 Linux
#[strum(serialize = "aarch64-unknown-linux-gnu")]
Aarch64UnknownLinuxGnu,
/// 64-bit MSVC
#[strum(serialize = "x86_64-pc-windows-msvc")]
X86_64PcWindowsMsvc,
/// 64-bit MinGW
#[strum(serialize = "x86_64-pc-windows-gnu")]
X86_64PcWindowsGnu,
/// 64-bit macOS
#[strum(serialize = "x86_64-apple-darwin")]
X86_64AppleDarwin,
/// ARM64 macOS
#[strum(serialize = "aarch64-apple-darwin")]
Aarch64AppleDarwin,
}

/// Parse the host triple if specified, otherwise guess it.
pub fn get_host_triple(host_triple_arg: Option<String>) -> Result<HostTriple> {
if let Some(host_triple_arg) = host_triple_arg {
HostTriple::from_str(&host_triple_arg).context(format!(
"{} Host triple '{}' is not supported.",
emoji::ERROR,
host_triple_arg,
))
} else {
HostTriple::from_str(guess_host_triple().unwrap())
.context(format!("{} Unable to guess host triple.", emoji::ERROR,))
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod emoji;
pub mod host_triple;
pub mod targets;
pub mod toolchain;
pub mod logging {
Expand Down
23 changes: 18 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use clap::Parser;
use embuild::espidf::{parse_esp_idf_git_ref, EspIdfRemote};
use espup::{
emoji,
host_triple::get_host_triple,
logging::initialize_logger,
targets::{parse_targets, Target},
toolchain::{
Expand Down Expand Up @@ -56,6 +57,9 @@ pub enum SubCommand {

#[derive(Debug, Parser)]
pub struct InstallOpts {
/// Target triple of the host.
#[arg(short = 'd', long, required = false)]
pub default_host: Option<String>,
/// ESP-IDF version to install. If empty, no esp-idf is installed. Version format:
///
/// - `commit:<hash>`: Uses the commit `<hash>` of the `esp-idf` repository.
Expand Down Expand Up @@ -95,6 +99,9 @@ pub struct InstallOpts {

#[derive(Debug, Parser)]
pub struct UpdateOpts {
/// Target triple of the host.
#[arg(short = 'd', long, required = false)]
pub default_host: Option<String>,
/// Verbosity level of the logs.
#[arg(short = 'l', long, default_value = "info", value_parser = ["debug", "info", "warn", "error"])]
pub log_level: String,
Expand Down Expand Up @@ -132,20 +139,22 @@ fn install(args: InstallOpts) -> Result<()> {

info!("{} Installing esp-rs", emoji::DISC);
let targets: HashSet<Target> = parse_targets(&args.targets).unwrap();
let host_triple = get_host_triple(args.default_host)?;
let mut extra_crates: HashSet<RustCrate> =
args.extra_crates.split(',').map(RustCrate::new).collect();
let mut exports: Vec<String> = Vec::new();
let export_file = args.export_file.clone();
let rust_toolchain = RustToolchain::new(args.toolchain_version.clone());
let rust_toolchain = RustToolchain::new(&args.toolchain_version, &host_triple);

// Complete LLVM is failing for Windows, aarch64 MacOs, and aarch64 Linux, so we are using always minified.
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
let llvm = LlvmToolchain::new(args.profile_minimal);
let llvm = LlvmToolchain::new(args.profile_minimal, &host_triple);
#[cfg(any(not(target_arch = "x86_64"), not(target_os = "linux")))]
let llvm = LlvmToolchain::new(true);
let llvm = LlvmToolchain::new(true, &host_triple);

debug!(
"{} Arguments:
- Host triple: {}
- Targets: {:?}
- ESP-IDF version: {:?}
- Export file: {:?}
Expand All @@ -156,6 +165,7 @@ fn install(args: InstallOpts) -> Result<()> {
- Profile Minimal: {:?}
- Toolchain version: {:?}",
emoji::INFO,
host_triple,
targets,
&args.espidf_version,
export_file,
Expand Down Expand Up @@ -185,7 +195,7 @@ fn install(args: InstallOpts) -> Result<()> {
exports.extend(repo.install()?);
extra_crates.insert(RustCrate::new("ldproxy"));
} else {
exports.extend(install_gcc_targets(targets)?);
exports.extend(install_gcc_targets(targets, &host_triple)?);
}

debug!(
Expand Down Expand Up @@ -252,18 +262,21 @@ fn uninstall(args: UninstallOpts) -> Result<()> {
fn update(args: UpdateOpts) -> Result<()> {
initialize_logger(&args.log_level);
info!("{} Updating Xtensa Rust toolchain", emoji::DISC);
let host_triple = get_host_triple(args.default_host)?;

debug!(
"{} Arguments:
- Host triple: {}
- Toolchain version: {}",
emoji::INFO,
host_triple,
&args.toolchain_version,
);

info!("{} Deleting previous Xtensa Rust toolchain", emoji::WRENCH);
remove_dir_all(get_rustup_home().join("toolchains").join("esp"))?;

let rust_toolchain = RustToolchain::new(args.toolchain_version);
let rust_toolchain = RustToolchain::new(&args.toolchain_version, &host_triple);
rust_toolchain.install_xtensa_rust()?;

info!("{} Update suscesfully completed!", emoji::CHECK);
Expand Down
29 changes: 12 additions & 17 deletions src/targets.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//! ESP32 chip variants support.

use crate::emoji;
use anyhow::Context;
use log::debug;
use std::{collections::HashSet, str::FromStr};
use strum::Display;
use strum_macros::EnumString;

#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug, Display)]

#[derive(Clone, Copy, EnumString, PartialEq, Hash, Eq, Debug, Display)]
pub enum Target {
/// Xtensa LX7 based dual core
#[strum(serialize = "esp32")]
Expand All @@ -22,20 +23,6 @@ pub enum Target {
ESP32C3,
}

impl FromStr for Target {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"esp32" => Ok(Target::ESP32),
"esp32s2" => Ok(Target::ESP32S2),
"esp32s3" => Ok(Target::ESP32S3),
"esp32c3" => Ok(Target::ESP32C3),
_ => Err(()),
}
}
}

/// Returns a vector of Chips from a comma or space separated string.
pub fn parse_targets(targets_str: &str) -> Result<HashSet<Target>, String> {
debug!("{} Parsing targets: {}", emoji::DEBUG, targets_str);
Expand All @@ -54,7 +41,15 @@ pub fn parse_targets(targets_str: &str) -> Result<HashSet<Target>, String> {
};

for target in targets_str {
targets.insert(FromStr::from_str(target).unwrap());
targets.insert(
Target::from_str(target)
.context(format!(
"{} Target '{}' is not supported",
emoji::ERROR,
target
))
.unwrap(),
);
}
debug!("{} Parsed targets: {:?}", emoji::DEBUG, targets);
Ok(targets)
Expand Down
52 changes: 27 additions & 25 deletions src/toolchain/gcc_toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::{
emoji,
host_triple::HostTriple,
targets::Target,
toolchain::{download_file, espidf::get_tool_path},
};
Expand All @@ -16,14 +17,16 @@ const DEFAULT_GCC_VERSION: &str = "8_4_0";

#[derive(Debug)]
pub struct GccToolchain {
/// The repository containing GCC sources.
pub repository_url: String,
/// Host triple.
pub host_triple: HostTriple,
/// Repository release version to use.
pub release: String,
/// GCC Version.
pub version: String,
/// The repository containing GCC sources.
pub repository_url: String,
/// GCC Toolchain target.
pub toolchain_name: String,
/// GCC Version.
pub version: String,
}

impl GccToolchain {
Expand All @@ -41,15 +44,14 @@ impl GccToolchain {
let target_dir = format!("{}/{}-{}", self.toolchain_name, self.release, self.version);

let gcc_path = get_tool_path(&target_dir);
let host_triple = guess_host_triple::guess_host_triple().unwrap();
let extension = get_artifact_extension(host_triple);
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(host_triple).unwrap(),
get_arch(&self.host_triple).unwrap(),
extension
);
let gcc_dist_url = format!("{}/{}/{}", self.repository_url, self.release, gcc_file);
Expand All @@ -63,35 +65,32 @@ impl GccToolchain {
}

/// Create a new instance with default values and proper toolchain name.
pub fn new(target: Target) -> Self {
pub fn new(target: Target, host_triple: &HostTriple) -> Self {
Self {
repository_url: DEFAULT_GCC_REPOSITORY.to_string(),
host_triple: host_triple.clone(),
release: DEFAULT_GCC_RELEASE.to_string(),
version: DEFAULT_GCC_VERSION.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: &str) -> Result<&str, String> {
fn get_arch(host_triple: &HostTriple) -> Result<&str> {
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
)),
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 architecture.
fn get_artifact_extension(host_triple: &str) -> &str {
/// Gets the artifact extension based on the host triple.
fn get_artifact_extension(host_triple: &HostTriple) -> &str {
match host_triple {
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => "zip",
_ => "tar.gz",
HostTriple::X86_64PcWindowsMsvc | HostTriple::X86_64PcWindowsGnu => "zip",
_ => "tar.xz",
}
}

Expand Down Expand Up @@ -128,11 +127,14 @@ pub fn get_ulp_toolchain_name(target: Target, version: Option<&EspIdfVersion>) -
}

/// Installs GCC toolchain the selected targets.
pub fn install_gcc_targets(targets: HashSet<Target>) -> Result<Vec<String>> {
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);
let gcc = GccToolchain::new(target, host_triple);
gcc.install()?;

#[cfg(windows)]
Expand Down
Loading

0 comments on commit 2bbb89f

Please sign in to comment.