Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add llvm-version arg #23

Merged
merged 20 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ ARG CONTAINER_GROUP=esp

# Ubuntu/Debian
RUN apt-get update \
&& apt-get install -y git python3 python3-pip gcc build-essential curl pkg-config libudev-dev \
&& apt-get install -y git python3 python3-pip gcc build-essential curl pkg-config libudev-dev libtinfo5\
&& apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
RUN adduser --disabled-password --gecos "" ${CONTAINER_USER}

# Fedora
# RUN dnf -y update \
# && dnf -y install git python3 python3-pip gcc systemd-devel \
# && dnf -y install git python3 python3-pip gcc systemd-devel ncurses-compat-libs \
# && dnf clean all
# RUN adduser ${CONTAINER_USER}

USER ${CONTAINER_USER}
WORKDIR /home/${CONTAINER_USER}

# openSUSE Tumbleweed/Leap
# RUN zypper install -y git gcc libudev-devel ninja python3 python3-pip make \
# RUN zypper install -y git gcc libudev-devel ninja python3 python3-pip make libncurses5 \
# && zypper clean

# Install Rust
Expand Down
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,35 @@
`espup` is a tool for installing and maintaining the required toolchains for
developing applications in Rust for Espressif SoC's.

> **Note**
>
> This application is still under development and should be considered experimental

## Requirements
Before running or installing `espup`, make sure that [`rustup`](https://www.rust-lang.org/tools/install)
and the following dependencies are installed.
Before running or installing `espup`, make sure that [`rustup`](https://www.rust-lang.org/tools/install) and the following dependencies are installed.
### Windows

- [Python](https://www.python.org/downloads/). Version should be between `3.6` and `3.10`.
- [git](https://git-scm.com/download/win)
- Toolchain. Select one of the following:
- [Windows x86_64 GNU](https://github.com/esp-rs/rust-build#windows-x86_64-gnu)
- [Windows x86_64 MSVC](https://github.com/esp-rs/rust-build#windows-x86_64-msvc)

- [git](https://git-scm.com/download/win).
- [Python](https://www.python.org/downloads/): Only required when installing ESP-IDF.

### Linux
- Ubuntu/Debian
```sh
sudo apt-get install -y git python3 python3-pip gcc build-essential curl pkg-config libudev-dev
sudo apt-get install -y git python3 python3-pip gcc build-essential curl pkg-config libudev-dev libtinfo5
```
- `libudev-dev` is only required when installing `cargo-espflash`.
- `python3` and `python3-pip` are only required when installing ESP-IDF.
- `libtinfo5` is required by LLVM 15.
- Fedora
```sh
sudo dnf -y install git python3 python3-pip gcc systemd-devel
sudo dnf -y install git python3 python3-pip gcc systemd-devel ncurses-compat-libs
```
- `systemd-devel` is only required when installing `cargo-espflash`.
- `python3` and `python3-pip` are only required when installing ESP-IDF.
- `ncurses-compat-libs` is required by LLVM 15.
- openSUSE Thumbleweed/Leap
```
sudo zypper install -y git gcc libudev-devel ninja python3 python3-pip make
sudo zypper install -y git gcc libudev-devel ninja python3 python3-pip make libncurses5
```
- `libudev-devel` is only required when installing `cargo-espflash`.
- `python3` and `python3-pip` are only required when installing ESP-IDF.
- `libncurses5` is required by LLVM 15.


## Installation
Expand Down Expand Up @@ -76,12 +76,12 @@ See [Usage](#usage) section for more details.
> before building an application.
### Uninstall
```sh
espup uninstall
espup uninstall
```

### Update
```sh
espup update
espup update
```

## Usage
Expand Down
9 changes: 4 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ pub struct InstallOpts {
// Make it vector and have splliter =" "
#[arg(short = 'c', long, default_value = "cargo-espflash")]
pub extra_crates: String,
/// LLVM version.
#[arg(short = 'x', long, default_value = "15", value_parser = ["15"])]
pub llvm_version: 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 @@ -154,11 +157,7 @@ fn install(args: InstallOpts) -> Result<()> {
} else {
None
};
// 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, &host_triple);
#[cfg(any(not(target_arch = "x86_64"), not(target_os = "linux")))]
let llvm = LlvmToolchain::new(true, &host_triple);
let llvm = LlvmToolchain::new(args.llvm_version, args.profile_minimal, &host_triple);

debug!(
"{} Arguments:
Expand Down
101 changes: 25 additions & 76 deletions src/toolchain/llvm_toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ use crate::{
host_triple::HostTriple,
toolchain::{download_file, espidf::get_tool_path},
};
use anyhow::{bail, Ok, Result};
use anyhow::{Ok, Result};
use log::{info, warn};
use std::path::{Path, PathBuf};

const DEFAULT_LLVM_COMPLETE_REPOSITORY: &str =
"https://github.com/espressif/llvm-project/releases/download";
const DEFAULT_LLVM_MINIFIED_REPOSITORY: &str =
"https://github.com/esp-rs/rust-build/releases/download/llvm-project-14.0-minified";
const DEFAULT_LLVM_VERSION: &str = "esp-14.0.0-20220415";
const DEFAULT_LLVM_REPOSITORY: &str = "https://github.com/espressif/llvm-project/releases/download";
const DEFAULT_LLVM_15_VERSION: &str = "esp-15.0.0-20221014";

#[derive(Debug, Clone, Default)]
pub struct LlvmToolchain {
Expand All @@ -23,41 +20,30 @@ pub struct LlvmToolchain {
pub host_triple: HostTriple,
/// LLVM Toolchain path.
pub path: PathBuf,
/// The repository containing LVVM sources.
/// The repository containing LLVM sources.
pub repository_url: String,
/// Repository release version to use.
/// LLVM Version ["15"].
pub version: String,
}

impl LlvmToolchain {
/// Gets the name of the LLVM 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::Aarch64AppleDarwin => Ok("macos-arm64"),
HostTriple::X86_64AppleDarwin => Ok("macos"),
HostTriple::X86_64UnknownLinuxGnu => Ok("linux-amd64"),
HostTriple::Aarch64UnknownLinuxGnu => Ok("linux-arm64"),
HostTriple::X86_64PcWindowsMsvc | HostTriple::X86_64PcWindowsGnu => Ok("win64"),
_ => bail!(
"{} No LLVM arch found for the host triple: '{}'",
emoji::ERROR,
host_triple
),
}
}

/// 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 binary path.
fn get_lib_path(&self) -> String {
#[cfg(windows)]
let llvm_path = format!("{}/xtensa-esp32-elf-clang/bin", self.path.to_str().unwrap());
let llvm_path = format!("{}/esp-clang/bin", self.path.to_str().unwrap());
#[cfg(unix)]
let llvm_path = format!("{}/xtensa-esp32-elf-clang/lib", self.path.to_str().unwrap());
let llvm_path = format!("{}/esp-clang/lib", self.path.to_str().unwrap());
llvm_path
}

Expand All @@ -75,10 +61,7 @@ impl LlvmToolchain {
info!("{} Installing Xtensa elf Clang", emoji::WRENCH);
download_file(
self.repository_url.clone(),
&format!(
"idf_tool_xtensa_elf_clang.{}",
Self::get_artifact_extension(&self.host_triple)
),
"idf_tool_xtensa_elf_clang.tar.xz",
self.path.to_str().unwrap(),
true,
)?;
Expand All @@ -98,39 +81,25 @@ impl LlvmToolchain {
}

/// Create a new instance with default values and proper toolchain version.
pub fn new(minified: bool, host_triple: &HostTriple) -> Self {
let file_name: String;
let version = DEFAULT_LLVM_VERSION.to_string();
let repository_url: String;
pub fn new(version: String, minified: bool, host_triple: &HostTriple) -> Self {
let mut file_name = format!(
"llvm-{}-{}.tar.xz",
DEFAULT_LLVM_15_VERSION,
Self::get_arch(host_triple).unwrap()
);
if minified {
file_name = format!(
"xtensa-esp32-elf-llvm{}-{}-{}.{}",
get_release_with_underscores(&version),
&version,
host_triple,
Self::get_artifact_extension(host_triple)
);
repository_url = format!("{}/{}", DEFAULT_LLVM_MINIFIED_REPOSITORY, file_name,);
} else {
file_name = format!(
"xtensa-esp32-elf-llvm{}-{}-{}.{}",
get_release_with_underscores(&version),
&version,
Self::get_arch(host_triple).unwrap(),
Self::get_artifact_extension(host_triple)
);
repository_url = format!(
"{}/{}/{}",
DEFAULT_LLVM_COMPLETE_REPOSITORY, &version, file_name
);
file_name = format!("libs_{}", file_name);
}
let path = format!(
let repository_url = format!(
"{}/{}/{}",
DEFAULT_LLVM_REPOSITORY, DEFAULT_LLVM_15_VERSION, file_name,
);
let path = PathBuf::from(format!(
"{}/{}-{}",
get_tool_path("xtensa-esp32-elf-clang"),
version,
DEFAULT_LLVM_15_VERSION,
host_triple
)
.into();
));
Self {
file_name,
host_triple: host_triple.clone(),
Expand All @@ -140,23 +109,3 @@ impl LlvmToolchain {
}
}
}

/// Gets the parsed version name.
fn get_release_with_underscores(version: &str) -> String {
let version: Vec<&str> = version.split('-').collect();
let llvm_dot_release = version[1];
llvm_dot_release.replace('.', "_")
}

#[cfg(test)]
mod tests {
use crate::toolchain::llvm_toolchain::get_release_with_underscores;

#[test]
fn test_get_release_with_underscores() {
assert_eq!(
get_release_with_underscores("esp-14.0.0-20220415"),
"14_0_0".to_string()
);
}
}