Skip to main content

Vendored LLVM toolchain (opt/llc/llvm-mc/ld.lld/llvm-objcopy) for the PyMCU ARM backend

Project description

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/llc carries no license obligation from LLVM.
  • Contrast with AVR: pymcu-avr-toolchain bundles avr-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

  1. Update LLVM_VERSION in src/pymcu_arm_toolchain/__init__.py and version in pyproject.toml.
  2. Tag and push:
    git tag v22.1.7
    git push origin v22.1.7
    
  3. The build-wheels.yml workflow fires automatically:
    • Downloads the official LLVM .tar.xz, slims to the five tools + shared libs via scripts/stage-llvm.sh, builds a py3-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-pypi uses OIDC trusted publishing (no stored token required).

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymcu_arm_toolchain-22.1.7.tar.gz (14.8 kB view details)

Uploaded Source

File details

Details for the file pymcu_arm_toolchain-22.1.7.tar.gz.

File metadata

  • Download URL: pymcu_arm_toolchain-22.1.7.tar.gz
  • Upload date:
  • Size: 14.8 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

Hashes for pymcu_arm_toolchain-22.1.7.tar.gz
Algorithm Hash digest
SHA256 f9f2d34a8ffd8bc97fcaa4cd1d28a1e50dc62ba608c2ba02fbfba757b30df109
MD5 10938a42a92da56fbde335ea4bc59acb
BLAKE2b-256 eb8a55f9a3a69f7570ac4cbb07e18f77a6e9181de2f5414d7f4f1c19550572a1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page