pymcu-arm-toolchain
Vendored LLVM toolchain for the PyMCU ARM (Cortex-M) backend.
The ARM backend lowers PyMCU's architecture-agnostic IR to LLVM IR and then invokes five LLVM command-line tools to produce a flashable flat binary:
opt llc llvm-mc ld.lld llvm-objcopy
This package is the ARM counterpart of
pymcu-avr-toolchain: a
platform-specific wheel whose only job is to ship those tools so that
pip install pymcu-compiler[arm] is fully self-contained — no
brew install llvm or apt install lld step required on supported platforms.
License: MIT packaging + Apache-2.0 WITH LLVM-exception binaries
The Python packaging code in this repo is MIT.
The bundled LLVM binaries are distributed under the Apache License 2.0 with LLVM Exceptions — the official license of the LLVM Project. This is a permissive license with no copyleft. Specifically:
- LLVM is not GPL. There is no copyleft infection on this package, on PyMCU, or on firmware compiled with these tools.
- The LLVM Exception clause explicitly exempts compiled output: binary
firmware produced by PyMCU through
opt/llccarries no license obligation from LLVM. - Contrast with AVR:
pymcu-avr-toolchainbundlesavr-gcc(derived from GCC), which is GPL-3.0. That package must therefore be GPL- licensed. The isolation mechanism is the same — a separate optional package — but the license differs because the upstream compilers differ.
See LICENSE for the complete text and a plain-language explanation.
Installation
pip install pymcu-arm-toolchain
libLLVM.{dylib,so} is 200–300 MB of code even in a release build — too
large for PyPI's 100 MB per-file ceiling. The distribution is therefore split:
| Channel | What it contains |
|---|---|
PyPI (pip install pymcu-arm-toolchain) |
Lightweight stub (~20 KB) |
| GitHub Releases | Binary wheels with LLVM bundled (~300 MB each) |
The LLVM tools are downloaded automatically. The first call to
get_tool() (or any PyMCU ARM build) downloads the official LLVM
release for your platform from GitHub and extracts the five required tools
into the shared cache at ~/.pymcu/tools/. Subsequent calls are instant.
import pymcu_arm_toolchain
opt = pymcu_arm_toolchain.get_tool("opt") # downloads on first call
For CI or air-gapped environments, override the download URL or install the binary wheel directly:
# Linux x86-64
pip install https://github.com/PyMCU/pymcu-arm-toolchain/releases/download/v22.1.7/pymcu_arm_toolchain-22.1.7-py3-none-manylinux_2_17_x86_64.whl
# Linux arm64
pip install https://github.com/PyMCU/pymcu-arm-toolchain/releases/download/v22.1.7/pymcu_arm_toolchain-22.1.7-py3-none-manylinux_2_17_aarch64.whl
# macOS Apple Silicon
pip install https://github.com/PyMCU/pymcu-arm-toolchain/releases/download/v22.1.7/pymcu_arm_toolchain-22.1.7-py3-none-macosx_14_0_arm64.whl
# Windows x86-64
pip install https://github.com/PyMCU/pymcu-arm-toolchain/releases/download/v22.1.7/pymcu_arm_toolchain-22.1.7-py3-none-win_amd64.whl
System LLVM (alternative)
If you already have LLVM 18+ installed (brew install llvm lld /
apt install llvm lld), the Rp2040LlvmToolchain driver finds the tools via
the cache or PATH automatically — no package needed.
How the driver resolves tools
Rp2040LlvmToolchain (in pymcu-arm) checks these sources in order:
| Priority | Source |
|---|---|
| 1 | pymcu_arm_toolchain.get_tool(name) — wheel bundle or auto-downloaded cache |
| 2 | Shared cache ~/.pymcu/tools/<platform>/llvm-arm/bin/ |
| 3 | Common keg dirs (/opt/homebrew/opt/llvm/bin, /usr/lib/llvm/bin, …) |
| 4 | PATH |
A missing wheel never blocks a developer who already has LLVM installed.
Inspecting installed tools
pymcu-arm-toolchain-info # entry-point
python -m pymcu_arm_toolchain status
Example output:
pymcu-arm-toolchain (LLVM 22.1.7, platform darwin-arm64)
[ok] opt ~/.pymcu/tools/darwin-arm64/llvm-arm/bin/opt
[ok] llc ~/.pymcu/tools/darwin-arm64/llvm-arm/bin/llc
[ok] llvm-mc ~/.pymcu/tools/darwin-arm64/llvm-arm/bin/llvm-mc
[ok] ld.lld ~/.pymcu/tools/darwin-arm64/llvm-arm/bin/ld.lld
[ok] llvm-objcopy ~/.pymcu/tools/darwin-arm64/llvm-arm/bin/llvm-objcopy
Seeding the cache manually
For platforms without a published wheel, or to use a locally installed LLVM:
# Download the pinned LLVM release automatically:
python -m pymcu_arm_toolchain fetch --cache
# Use a Homebrew LLVM (symlinked, dev convenience):
python -m pymcu_arm_toolchain fetch --cache \
--from-dir /opt/homebrew/opt/llvm --link
# Copy from a system install:
python -m pymcu_arm_toolchain fetch --cache \
--from-dir /usr/lib/llvm-19
For maintainers: publishing a new wheel
Release process
- Update
LLVM_VERSIONinsrc/pymcu_arm_toolchain/__init__.pyandversioninpyproject.toml. - Tag and push:
git tag v22.1.7 git push origin v22.1.7
- The
build-wheels.ymlworkflow fires automatically:- Downloads the official LLVM
.tar.xz, slims to the five tools + shared libs viascripts/stage-llvm.sh, builds apy3-none-<platform>wheel per platform. - Binary wheels → GitHub Releases (too large for PyPI's 100 MB limit).
- PyPI receives only the pure-Python sdist stub.
publish-pypiuses OIDC trusted publishing (no stored token required).
- Downloads the official LLVM
Required GitHub configuration
| Item | Where | Purpose |
|---|---|---|
release environment |
Repo → Settings → Environments | Gates OIDC publishing; add tag protection rule v* |
Building a wheel locally
bash scripts/stage-llvm.sh /opt/homebrew/opt/llvm /tmp/staged-llvm
ARMT_TOOLCHAIN_DIR=/tmp/staged-llvm \
WHEEL_PLATFORM_TAG=macosx_14_0_arm64 \
uv build --wheel
Environment variables
| Variable | Effect |
|---|---|
ARMT_TOOLCHAIN_DIR |
Path to a staged LLVM tree for hatch_build.py |
WHEEL_PLATFORM_TAG |
Override the wheel platform tag (e.g. win_amd64) |
PYMCU_TOOLS_DIR |
Override the ~/.pymcu/tools cache root |
PYMCU_ARM_LLVM_URL |
Override the LLVM archive download URL (air-gapped installs) |
PYMCU_ARM_LLVM_SHA256 |
Expected SHA-256 of the downloaded archive |
PYMCU_SKIP_HASH_CHECK |
Set to 1 to skip SHA-256 verification |
Version history
| Package version | Bundled LLVM | Notes |
|---|---|---|
| 22.1.7 | LLVM 22.1.7 | Initial release |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file pymcu_arm_toolchain-22.1.7.post1.tar.gz.
File metadata
- Download URL: pymcu_arm_toolchain-22.1.7.post1.tar.gz
- Upload date:
- Size: 14.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21e38cba33184e7c4dfc02e0090723d04ef9d5fd1c60c606672eab5ce0605528
|
|
| MD5 |
42f7fd5bdef8e4467ead364b2485625a
|
|
| BLAKE2b-256 |
5b718b6b58c805f34647d41ee46d342aa8f384bdf640efd937b9ddd1adf180c7
|