Skip to main content

LLVM-C Python bindings with nanobind.

Project description

llvm-nanobind

Python bindings for the LLVM-C API using nanobind.

This project provides a Pythonic interface to LLVM's compiler infrastructure, enabling you to build compilers, analyzers, and code transformation tools in Python.

Current status: Experimental but usable. The bindings target LLVM 21.1.6 and are published as llvm-nanobind on PyPI (import name: llvm). Wheels bundle LLVM and are built/tested in CI for Linux x86_64/aarch64, macOS arm64, and Windows x86_64. The API is still evolving; expect breaking changes until a stable release.

Version numbers track LLVM: 21.1.6.1 means LLVM 21.1.6 plus binding/package revision 1.

Note: This project is 90%+ vibe coded. It is mostly an experiment to see what LLMs can do when you set things up properly.

Installation

Released wheels bundle LLVM for supported platforms, so normal installation is:

pip install llvm-nanobind
python -c "import llvm; print(llvm)"

For source/development builds, see Development.

See llvm-nanobind-example for a simple example project.

Quick Start

import llvm

# Create a simple function that returns 42.
with llvm.create_context() as ctx:
    i32 = ctx.types.i32
    fn_type = ctx.types.function(i32, [])

    with ctx.create_module("example") as mod:
        fn = mod.add_function("get_answer", fn_type)
        entry = fn.append_basic_block("entry")

        with entry.create_builder() as builder:
            builder.ret(i32.constant(42))

        assert mod.verify(), mod.verification_error
        print(mod)

This exact snippet is available as examples/quick_start.py.

Examples

Runnable examples live in examples/ and are covered by tests/test_examples.py.

uv run python examples/quick_start.py
uv run python examples/transform_replace_add.py

More examples worth browsing:

Current capabilities

  • Pythonic wrappers for contexts, modules, types, values, functions, basic blocks, builders, metadata, debug info, object files, targets, target machines, and pass builder options
  • IR construction, traversal, and transformation helpers: constants, globals, PHI/control flow/memory/cast/cmp instructions, operands, predecessors, RAUW, split blocks, move/clone/erase instructions
  • IR and bitcode parsing/writing, lazy bitcode modules, module cloning/linking, module flags, diagnostics, attributes, COMDATs, calling conventions, linkage/visibility/storage controls
  • Target initialization/lookup, data layouts, object/assembly emission through target machines, and PassBuilder pipeline execution
  • Lifetime/validity guards that turn many use-after-free, disposed-object, null-reference, and wrong-kind mistakes into Python exceptions instead of hard crashes
  • Auto-generated typed .pyi stubs for IDEs/type checkers
  • Golden-master tests, Python regression scripts, examples, and vendored llvm-c-test lit tests, including CI coverage against installed wheels

Documentation

Type stubs are auto-generated and provide IDE intellisense. After building, find them at:

.venv/lib/python3.*/site-packages/llvm/__init__.pyi

For development documentation, see devdocs/README.md.

Known limitations

  • The API is not stable yet; method names and ownership rules may still change.
  • Scope follows the LLVM-C API, not the full LLVM C++ API. A high-level JIT/ExecutionEngine API is not currently exposed.
  • Docs are currently the README, examples, devdocs/, and the generated .pyi stub; there is no hosted API reference yet.
  • Prebuilt wheels currently target CPython 3.12+ stable ABI on Linux x86_64/aarch64, macOS arm64, and Windows x86_64. Other platforms require a source build.

Development

Setup

Source/development builds need LLVM 21.1.6 available to CMake. The LLVM archives used for packaging are published at LLVMParty/llvm-builds v21.1.6.

From a checkout, download the matching LLVM archive and then run uv sync:

# Choose the archive matching your platform:
#   llvm-21.1.6-linux-x86_64.zip
#   llvm-21.1.6-linux-aarch64.zip
#   llvm-21.1.6-macos-arm64.zip
#   llvm-21.1.6-windows-x86_64.zip
python tools/ci/install_llvm.py \
  --version 21.1.6 \
  --archive llvm-21.1.6-linux-x86_64.zip \
  --dest .llvm \
  --prefix-file .llvm-prefix

uv sync --verbose

If you are using your own LLVM install instead, set LLVM_ROOT to its install prefix:

export LLVM_ROOT=/path/to/llvm
uv sync --verbose

If .llvm-prefix already points at another LLVM install, delete it first; CMake may reuse it from a previous configure.

For offline builds:

uv sync --offline --no-build-isolation --verbose

For Windows C++/LSP setup, see the Windows development section below.

Testing

# Main golden-master suite:
# - runs C++ test executables from build/
# - runs paired Python scripts
# - compares Python output against stored C++ behavior
uv run run_tests.py

# Python-only regression scripts in tests/regressions/
uv run run_tests.py --regressions

# Vendored llvm-c-test lit suite against the C test binary
# Rebuilds the vendored C binary before running lit.
uv run run_llvm_c_tests.py
uv run run_llvm_c_tests.py -v

# Vendored llvm-c-test lit suite against the Python implementation
uv run run_llvm_c_tests.py --use-python

# Run the Python llvm-c-test port directly during development
uv run python -m llvm_c_test --targets-list

# Type checking (not a test suite, but commonly run in CI/dev)
uvx ty check

If you want the closest thing to “run everything in this repo”, use:

uv run run_tests.py
uv run run_tests.py --regressions
uv run run_llvm_c_tests.py
uv run run_llvm_c_tests.py --use-python

Python tests here are intended to be executable as standalone scripts (e.g. uv run tests/test_module.py or uv run tests/regressions/test_const_bytes.py). They are generally pytest-compatible too, but direct script execution is the historical/default style used by run_tests.py and for one-off debugging.

pytest is still useful for targeting specific regression files or subsets, but it is not our complete top-level test entrypoint by itself.

Coverage

# Run with coverage
uv run coverage run run_llvm_c_tests.py --use-python
uv run coverage combine
uv run coverage report --include="llvm_c_test/*"

Windows source builds and C++ IntelliSense

The wheel is the easiest path on Windows. If you need a source/development build, install Visual Studio or Visual Studio Build Tools with the C++ workload, then fetch LLVM and run uv sync:

py -3.12 tools\ci\install_llvm.py `
  --version 21.1.6 `
  --archive llvm-21.1.6-windows-x86_64.zip `
  --dest .llvm `
  --prefix-file .llvm-prefix

uv sync --verbose

That command downloads from LLVMParty/llvm-builds v21.1.6, installs into .llvm, and writes .llvm-prefix for CMake.

If you are using your own LLVM install instead:

$env:LLVM_ROOT = "C:\path\to\llvm"
uv sync --verbose

For C++ local development with an LSP, create a local CMakeUserPresets.json at the repository root. CMake gets LLVM from .llvm-prefix created above, or from LLVM_ROOT on first configure. The compiler paths below assume the usual LLVM installer location; adjust them if your clang-cl.exe is elsewhere:

{
    "version": 3,
    "configurePresets": [
        {
            "name": "clang-cl",
            "displayName": "Ninja with clang-cl",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build",
            "cacheVariables": {
                "CMAKE_C_COMPILER": "C:/Program Files/LLVM/bin/clang-cl.exe",
                "CMAKE_CXX_COMPILER": "C:/Program Files/LLVM/bin/clang-cl.exe",
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
                "CMAKE_BUILD_TYPE": "RelWithDebInfo"
            }
        }
    ],
    "buildPresets": [
        {
            "name": "clang-cl",
            "configurePreset": "clang-cl"
        }
    ]
}

Then configure/build with:

cmake --preset clang-cl
cmake --build --preset clang-cl

If you move or replace the LLVM install, delete or regenerate .llvm-prefix from any previous configure.

License

This project is licensed under the MIT License. See LICENSE for details.

LLVM is licensed under the Apache License v2.0 with LLVM Exceptions.

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

llvm_nanobind-21.1.6.1.tar.gz (633.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

llvm_nanobind-21.1.6.1-cp312-abi3-win_amd64.whl (44.0 MB view details)

Uploaded CPython 3.12+Windows x86-64

llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_x86_64.whl (61.8 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ x86-64

llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_aarch64.whl (58.5 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ ARM64

llvm_nanobind-21.1.6.1-cp312-abi3-macosx_13_0_arm64.whl (43.9 MB view details)

Uploaded CPython 3.12+macOS 13.0+ ARM64

File details

Details for the file llvm_nanobind-21.1.6.1.tar.gz.

File metadata

  • Download URL: llvm_nanobind-21.1.6.1.tar.gz
  • Upload date:
  • Size: 633.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llvm_nanobind-21.1.6.1.tar.gz
Algorithm Hash digest
SHA256 b46ba66cabf6f47b4fb988ee77ebf0fb9a52a94df7396400e27dad09c26d05e6
MD5 b0f6e6ef4adeb4d8741aee72b924db96
BLAKE2b-256 66b52255a7b42ddd154ea3247841f0d6610b634a376ad2e20cc49b91c8d83c22

See more details on using hashes here.

Provenance

The following attestation bundles were made for llvm_nanobind-21.1.6.1.tar.gz:

Publisher: ci.yml on LLVMParty/llvm-nanobind

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llvm_nanobind-21.1.6.1-cp312-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for llvm_nanobind-21.1.6.1-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 3c18170be22f41b0552c0032ecd863b926e1132ba2f89af8c34a118df2abdc78
MD5 3d42151a30e44fc6e48f6c6d6e8a8202
BLAKE2b-256 362f26d6839abd9a112132abc0dfb790b2c76e9d169959ff1580b9ee8c355264

See more details on using hashes here.

Provenance

The following attestation bundles were made for llvm_nanobind-21.1.6.1-cp312-abi3-win_amd64.whl:

Publisher: ci.yml on LLVMParty/llvm-nanobind

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fc45990f16dda0dadbae13e013c069232780ad0131736ccaaaf1f8eb9f66d83e
MD5 a097c796850f1f1731b7cf2b7441ff7d
BLAKE2b-256 9d55deb6aa6c2f7b2387541385443b443823cab66b367beb131a7a9567f3c0b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_x86_64.whl:

Publisher: ci.yml on LLVMParty/llvm-nanobind

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5782bd8172cdfd0c0ba8b175137ee860a9fa9208ee9b652b6cfd2def5f6aacf7
MD5 c69e3c12c53730829a718f2d31c45ca5
BLAKE2b-256 562c660005a35afea084d76e9bbfaf4c3326de457dbfa7f630fa2a2667839d04

See more details on using hashes here.

Provenance

The following attestation bundles were made for llvm_nanobind-21.1.6.1-cp312-abi3-manylinux_2_28_aarch64.whl:

Publisher: ci.yml on LLVMParty/llvm-nanobind

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llvm_nanobind-21.1.6.1-cp312-abi3-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for llvm_nanobind-21.1.6.1-cp312-abi3-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 e4263b5570e6877bb2d417c9f7dd10c10107a9f3b9f8847ec31da76a970307da
MD5 e8b0361885b97cc7b38b8759d9c4d3e3
BLAKE2b-256 9db0e776e058669e8037b30b7327c7c243be626b67c3e12365be50b5a18846c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for llvm_nanobind-21.1.6.1-cp312-abi3-macosx_13_0_arm64.whl:

Publisher: ci.yml on LLVMParty/llvm-nanobind

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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