arm-toolchain 0.1.0

Manage and use the embedded ARM toolchain
Documentation
# ARM Toolchain Manager

ARM Toolchain Manager is a tool for installing and managing the LLVM-based ARM embedded toolchain.

## Features

- `arm-toolchain` command: Utility for the downloading, installing, and managing of ARM toolchains
- `atrun` command: Run commands from the active toolchain without adding it to your `PATH`.
- Library mode: Query installed toolchains programmatically via the Rust crate.
- Cargo xtask integration: Add the tool as a subcommand of your Cargo project's xtask command.

## Usage

You can download and activate the latest toolchain with this command:

```shell
arm-toolchain use latest
```

Or pick a custom version:

```shell
arm-toolchain use v21.1.0
```

Once you've activated a toolchain, run commands from it with `atrun`:

```terminal
$ atrun clang -print-targets

  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_32 - AArch64 (little endian ILP32)
    aarch64_be - AArch64 (big endian)
    arm        - ARM
    arm64      - ARM64 (little endian)
    arm64_32   - ARM64 (little endian ILP32)
    armeb      - ARM (big endian)
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
```

Using `atrun` has the same effect of invoking `arm-toolchain run`, but it's shorter to type.

### Locate toolchains

Use the `locate` subcommand to get the path to the active toolchain, or a specified one.

```shell
arm-toolchain locate
export PATH="$(arm-toolchain locate bin):$PATH"

arm-toolchain locate -T v21.1.0
export PATH="$(arm-toolchain locate bin -T v21.1.0):$PATH"
```

If you are collaborating with others, you might want to make a symlink to the toolchain so that you can refer to its path without hardcoding anything too unpredictable. Here's how you'd do that:

```shell
echo "/toolchain" >> .gitignore
ln -s "$(arm-toolchain locate)" toolchain
```

After this initial setup, you can use consistent paths in other places.

```shell
./toolchain/bin/clang -print-targets
export C_INCLUDE_PATH="toolchain/lib/clang-runtimes/arm-none-eabi/include"
```

### List toolchains

You can view all the installed toolchains with the `list` subcommand.

```terminal
$ arm-toolchain list
Active: v21.1.1

Installed:
- v21.1.1
- v21.1.0
```

### Remove toolchains

You can remove toolchains when you're done using them.

```shell
arm-toolchain remove v21.1.0
arm-toolchain remove all
```

You can also purge the download cache to save space. `arm-toolchain` will delete things from the cache after it finishes downloading them, but if it gets interrupted you might end up with some excess files in there.

```shell
arm-toolchain purge-cache
```

### Integration with cargo xtask

If your Rust project uses the [xtask pattern](https://github.com/matklad/cargo-xtask), you can make `arm-toolchain` a subcommand by adding it to your existing parser.

```toml
[dependencies]
arm_toolchain = { version = "*", features = ["cli"] }
```

```rs
use arm_toolchain::cli::ArmToolchainCmd;

#[derive(Debug, clap::Parser)]
enum Args {
    // ...
    Toolchain(ArmToolchainCmd),
}

#[tokio::main]
async fn main() -> miette::Result<()> {
    let args = Args::parse();

    match args {
        // ...
        Args::Toolchain(cmd) => {
            cmd.run().await?;
        }
    }
}
```

Now you can use the tool without having to install the standalone command.

```shell
cargo xtask toolchain use latest
```

### Library mode

All of this tool's functionality is exposed programmatically for your custom scripting needs. To access it, your project will need to be using the Tokio runtime.

```rs
let client = ToolchainClient::using_data_dir().await?;

let installed = client.installed_versions().await?;

println!("Installed toolchains:");
for version in installed {
    let toolchain = client.toolchain(&version);
    println!("- {version} at {}", toolchain.path.display());
}
```