| --- |
| icon: octicons/sliders-16 |
| --- |
| |
| # Building with Bazel |
| |
| This page walks through building IREE from source using the |
| [Bazel build system](https://bazel.build/). |
| |
| !!! warning |
| |
| Bazel build support is primarily for internal project infrastructure. We |
| strongly recommend [using CMake](../../building-from-source/index.md) |
| instead. |
| |
| Our Bazel configuration is also _only_ tested on Linux. Windows and macOS |
| may be unstable. |
| |
| ## :octicons-download-16: Prerequisites |
| |
| === ":fontawesome-brands-linux: Linux" |
| |
| 1. **Recommended:** Install [bazelisk](https://github.com/bazelbuild/bazelisk) |
| to automatically use the correct Bazel version from |
| [`.bazelversion`](https://github.com/iree-org/iree/blob/main/.bazelversion): |
| |
| ```shell |
| # Via Go (if installed) |
| go install github.com/bazelbuild/bazelisk@latest |
| # go install names the binary 'bazelisk'. Add a symlink so |
| # 'bazel' works (~/go/bin should already be on your PATH). |
| ln -s ~/go/bin/bazelisk ~/go/bin/bazel |
| |
| # Or download binary directly as 'bazel' (recommended by bazelisk docs). |
| curl -Lo ~/.local/bin/bazel \ |
| https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 |
| chmod +x ~/.local/bin/bazel |
| ``` |
| |
| **Alternative:** Install Bazel 7.3.1 manually by following the |
| [official docs](https://bazel.build/install). |
| |
| 2. Install a compiler such as Clang (GCC is not fully supported). |
| |
| ```shell |
| sudo apt install clang |
| ``` |
| |
| Set environment variables for Bazel: |
| |
| ```shell |
| export CC=clang |
| export CXX=clang++ |
| ``` |
| |
| 3. Install Python build requirements: |
| |
| ```shell |
| python -m pip install -r runtime/bindings/python/iree/runtime/build_requirements.txt |
| ``` |
| |
| === ":fontawesome-brands-apple: macOS" |
| |
| 1. Install [Homebrew](https://brew.sh/): |
| |
| ```shell |
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" |
| ``` |
| |
| 2. **Recommended:** Install [bazelisk](https://github.com/bazelbuild/bazelisk) |
| to automatically use the correct Bazel version from |
| [`.bazelversion`](https://github.com/iree-org/iree/blob/main/.bazelversion): |
| |
| ```shell |
| brew install bazelisk |
| ``` |
| |
| **Alternative:** Install Bazel 7.3.1 manually by following the |
| [official docs](https://bazel.build/install/os-x) or via Homebrew: |
| |
| ```shell |
| brew install bazel |
| ``` |
| |
| 3. Install Python build requirements: |
| |
| ```shell |
| python -m pip install -r runtime/bindings/python/iree/runtime/build_requirements.txt |
| ``` |
| |
| === ":fontawesome-brands-windows: Windows" |
| |
| !!! tip |
| |
| You can simplify installation by using a package manager like |
| [Scoop](https://scoop.sh/) or [Chocolatey](https://chocolatey.org/). |
| |
| 1. **Recommended:** Install [bazelisk](https://github.com/bazelbuild/bazelisk) |
| to automatically use the correct Bazel version from |
| [`.bazelversion`](https://github.com/iree-org/iree/blob/main/.bazelversion): |
| |
| ```powershell |
| # Via Scoop |
| scoop install bazelisk |
| |
| # Via Chocolatey |
| choco install bazelisk |
| |
| # Or download binary from GitHub releases |
| ``` |
| |
| **Alternative:** Install Bazel 7.3.1 manually by following the |
| [official docs](https://bazel.build/install/windows). |
| |
| Also install [MSYS2](https://www.msys2.org/) by following Bazel's documentation. |
| |
| 2. Install Python3 ([docs here](https://www.python.org/downloads/windows/)) |
| and Python build requirements: |
| |
| ```shell |
| python -m pip install -r runtime/bindings/python/iree/runtime/build_requirements.txt |
| ``` |
| |
| 3. Install the full Visual Studio or "Build Tools For Visual Studio" from the |
| [downloads page](https://visualstudio.microsoft.com/downloads/) then |
| set the `BAZEL_VS` environment variable: |
| |
| ```powershell |
| > $env:BAZEL_VS = "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools" |
| ``` |
| |
| ## :octicons-rocket-16: Quickstart: clone and build |
| |
| **TL;DR** - Copy and paste this to get started: |
| |
| ```shell |
| # Clone and setup |
| git clone https://github.com/iree-org/iree.git |
| cd iree |
| git submodule update --init |
| python -m pip install -r runtime/bindings/python/iree/runtime/build_requirements.txt |
| |
| # Add tools to PATH (from repo root) |
| export PATH="$PWD/build_tools/bin:$PATH" |
| |
| # Configure once |
| iree-bazel-configure |
| |
| # Build and test |
| iree-bazel-build //tools:iree-compile |
| iree-bazel-test //... |
| ``` |
| |
| !!! tip "Building with CUDA?" |
| |
| Enable GPU drivers before configure: |
| |
| ```shell |
| IREE_HAL_DRIVER_CUDA=ON iree-bazel-configure |
| ``` |
| |
| Requires CUDA toolkit installed separately. |
| |
| !!! note "Driver configuration is sticky" |
| |
| Re-run `iree-bazel-configure` whenever you change `IREE_HAL_DRIVER_*` settings. |
| |
| !!! tip "Working with Claude Code?" |
| |
| All `iree-bazel-*` tools provide machine-readable documentation via `--agent_md`: |
| |
| ```shell |
| # Generate documentation for Claude |
| iree-bazel-configure --agent_md >> CLAUDE.local.md |
| ``` |
| |
| This appends concise tool documentation to your local Claude instructions, |
| teaching Claude how to use the `iree-bazel-*` tools in your project. |
| |
| ### Detailed steps |
| |
| 1. **Clone the repository:** |
| |
| ```shell |
| git clone https://github.com/iree-org/iree.git |
| cd iree |
| git submodule update --init |
| ``` |
| |
| !!! tip "Windows: Short paths" |
| |
| Clone to a short path like `C:\projects\` to avoid issues with Windows |
| maximum path lengths (260 characters). |
| |
| 2. **Install Python dependencies:** |
| |
| ```shell |
| python -m pip install -r runtime/bindings/python/iree/runtime/build_requirements.txt |
| ``` |
| |
| 3. **Add wrapper tools to PATH:** |
| |
| ```shell |
| export PATH="$PWD/build_tools/bin:$PATH" |
| ``` |
| |
| The `iree-bazel-*` wrapper tools simplify common workflows and provide sensible |
| defaults for local development. Run from the IREE repository root. |
| |
| 4. **Configure once per worktree:** |
| |
| ```shell |
| iree-bazel-configure |
| ``` |
| |
| This detects your platform/compiler and creates configuration files |
| (`configured.bazelrc` and `user.bazelrc`). Re-run this command to change |
| driver settings or after major environment changes. |
| |
| 5. **Build and test:** |
| |
| ```shell |
| # Build specific targets |
| iree-bazel-build //tools:iree-compile |
| |
| # Run all tests |
| iree-bazel-test //... |
| |
| # Run tests in a specific directory |
| iree-bazel-test //runtime/... |
| ``` |
| |
| Build artifacts are under the `bazel-bin/` directory, test logs under `bazel-testlogs/`. |
| |
| ## :octicons-gear-16: Local development configuration |
| |
| For faster local development iteration, use the `--config=localdev` flag: |
| |
| ```shell |
| bazel build --config=localdev //tools/... |
| bazel test --config=localdev //runtime/... |
| ``` |
| |
| !!! note |
| |
| The `iree-bazel-*` wrapper tools use `--config=localdev` by default, so you |
| don't need to specify it manually. |
| |
| This enables several optimizations: |
| |
| - **Skymeld** (merged analysis/execution phases for faster multi-target builds) |
| - **Ramdisk sandbox** on Linux (reduces I/O bottleneck with many CPU cores) |
| |
| The `localdev` config is defined in |
| [`build_tools/bazel/iree.bazelrc`](https://github.com/iree-org/iree/blob/main/build_tools/bazel/iree.bazelrc) |
| and works on all platforms. |
| |
| ## :octicons-pencil-16: Optional `user.bazelrc` |
| |
| !!! note |
| |
| `iree-bazel-configure` creates `user.bazelrc` automatically with platform-specific |
| defaults (including disk cache location). You can customize it further as shown below. |
| |
| You can put a `user.bazelrc` at the root of the repository for personal |
| customizations (ignored by git). For example: |
| |
| === ":fontawesome-brands-linux: Linux" |
| |
| ```shell |
| # Always use localdev optimizations |
| build --config=localdev |
| |
| # Use --config=debug to compile IREE and LLVM without optimizations |
| # and with assertions enabled. |
| build:debug --config=asserts --compilation_mode=opt '--per_file_copt=iree|llvm@-O0' --strip=never |
| |
| # Use --config=asserts to enable assertions. This has to be done globally: |
| # Code compiled with and without assertions can't be linked together (ODR violation). |
| build:asserts --compilation_mode=opt '--copt=-UNDEBUG' |
| ``` |
| |
| === ":fontawesome-brands-apple: macOS" |
| |
| ```shell |
| # Always use localdev optimizations |
| build --config=localdev |
| |
| # Use --config=debug to compile IREE and LLVM without optimizations |
| # and with assertions enabled. |
| build:debug --config=asserts --compilation_mode=opt '--per_file_copt=iree|llvm@-O0' --strip=never |
| |
| # Use --config=asserts to enable assertions. This has to be done globally: |
| # Code compiled with and without assertions can't be linked together (ODR violation). |
| build:asserts --compilation_mode=opt '--copt=-UNDEBUG' |
| ``` |
| |
| === ":fontawesome-brands-windows: Windows" |
| |
| ```shell |
| # Always use localdev optimizations |
| build --config=localdev |
| |
| # Debug config for Windows |
| build:debug --compilation_mode=dbg --copt=/O2 --per_file_copt=iree@/Od --strip=never |
| ``` |
| |
| ## :octicons-tools-16: Bazel Wrapper Tools |
| |
| IREE provides wrapper scripts in `build_tools/bin/` that simplify common Bazel workflows: |
| |
| **Setup:** |
| |
| ```shell |
| # Add to your PATH (in ~/.bashrc or similar) |
| export PATH="$PATH:/path/to/iree/build_tools/bin" |
| ``` |
| |
| **Available tools:** |
| |
| - `iree-bazel-configure` - Initial Bazel setup (run once per worktree) |
| - `iree-bazel-build [target]` - Build with optimized defaults |
| (supports `-w` watch mode) |
| - `iree-bazel-test [target]` - Run tests with configured drivers |
| (supports `-w` watch mode) |
| - `iree-bazel-run <target> [-- args]` - Build and execute from current directory |
| (supports `-w` watch mode) |
| - `iree-bazel-query <expr>` - Query the build graph |
| - `iree-bazel-cquery <expr>` - Configuration-aware query (resolved select()) |
| - `iree-bazel-try <file>` - Compile/run C++ snippets without BUILD files |
| - `iree-bazel-fuzz <target>` - Run fuzzer with corpus management |
| |
| **Examples:** |
| |
| ```shell |
| # Configure with CUDA support |
| IREE_HAL_DRIVER_CUDA=ON iree-bazel-configure |
| |
| # Build compiler tools |
| iree-bazel-build //tools:iree-compile |
| |
| # Run all tests (using configured drivers) |
| iree-bazel-test //... |
| |
| # Reconfigure to enable multiple drivers |
| IREE_HAL_DRIVER_CUDA=ON IREE_HAL_DRIVER_VULKAN=ON iree-bazel-configure |
| |
| # Reconfigure compiler plugins |
| IREE_COMPILER_PLUGINS="all,-input_torch" iree-bazel-configure |
| |
| # Run tool from current directory |
| iree-bazel-run //tools:iree-compile -- input.mlir -o output.vmfb |
| |
| # Quick C++ experiment |
| iree-bazel-try -e '#include "iree/base/api.h" |
| int main() { return iree_status_is_ok(iree_ok_status()) ? 0 : 1; }' |
| ``` |
| |
| **Watch mode:** |
| |
| Add `-w` or `--watch` to automatically rebuild/retest on file changes: |
| |
| ```shell |
| # Rebuild on changes |
| iree-bazel-build -w //tools:iree-compile |
| |
| # Rerun tests on changes (great for TDD) |
| iree-bazel-test -w //runtime/src/iree/base:status_test |
| |
| # Rebuild and restart binary on changes |
| iree-bazel-run -w //tools:iree-opt -- input.mlir |
| ``` |
| |
| Watch mode uses [ibazel](https://github.com/bazelbuild/bazel-watcher) which must |
| be installed separately: |
| |
| ```shell |
| go install github.com/bazelbuild/bazel-watcher/cmd/ibazel@latest |
| ``` |
| |
| !!! note "Bazel server lock behavior" |
| |
| Watch mode holds the Bazel server lock while the binary runs (necessary for |
| ibazel to control process lifecycle). Normal mode releases the lock after |
| building, allowing parallel builds in other shells. |
| |
| **Environment variables:** |
| |
| - `IREE_BAZEL_CACHE_DIR`: Bazel disk cache location |
| (default: `~/.cache/bazel-iree`) |
| - `IREE_HAL_DRIVER_*`: Enable/disable HAL drivers |
| (configure-time, matches CMake) |
| - `IREE_HAL_DRIVER_CUDA=ON`: Enable CUDA driver |
| - `IREE_HAL_DRIVER_VULKAN=ON`: Enable Vulkan driver |
| - Values: ON/YES/TRUE/Y/1 or OFF/NO/FALSE/N/0 |
| - `IREE_COMPILER_PLUGINS`: Select statically linked compiler plugins |
| (configure-time, default: `all` default buildable plugins) |
| - `IREE_COMPILER_PLUGINS=all`: Enable every default plugin whose |
| prerequisites are available |
| - `IREE_COMPILER_PLUGINS=all,-input_torch`: Enable all default buildable |
| plugins except `input_torch` |
| - `IREE_COMPILER_PLUGINS=hal_target_llvm_cpu,input_tosa`: Enable only the |
| listed plugins |
| - `IREE_TARGET_BACKEND_WEBGPU_SPIRV=ON`: Include WebGPU SPIR-V/Tint support |
| in `all` |
| - `VULKAN_SDK`: Vulkan SDK root for Bazel repository rules. If unset, |
| `iree-bazel-configure` probes `vulkaninfo` and common SDK install paths and |
| writes a detected SDK path to `configured.bazelrc`. |
| - `IREE_FUZZ_CACHE`: Fuzzer corpus cache |
| (default: `~/.cache/iree-fuzz-cache`) |
| - `IREE_FUZZ_CORPUS`: Fuzzer dictionaries |
| (default: `~/.cache/iree-fuzz-corpus`) |
| |
| **Tips:** |
| |
| - Add `-v` flag to see the exact Bazel command being executed |
| - Wrappers use `--config=localdev` by default for faster local iteration |
| - Run `<tool> --help` for detailed usage information |
| |
| ## :octicons-book-16: Advanced: Under the Hood |
| |
| ### Wrapper → Raw Bazel mapping |
| |
| The wrapper tools are thin shells around standard Bazel commands. Here's what |
| they do: |
| |
| | Wrapper | Equivalent Raw Command | |
| |---------|------------------------| |
| | `iree-bazel-build //foo` | `bazel build --config=localdev //foo` | |
| | `iree-bazel-build -w //foo` | `ibazel build --config=localdev //foo` | |
| | `iree-bazel-test //...` | `bazel test --config=localdev //...` | |
| | `iree-bazel-test -w //...` | `ibazel test --config=localdev //...` | |
| | `iree-bazel-run //foo` | Build + exec (releases lock) | |
| | `iree-bazel-run -w //foo` | `ibazel run --run_under="cd $PWD && " //foo` | |
| | `iree-bazel-configure` | `python3 configure_bazel.py` + create `user.bazelrc` | |
| |
| **Debugging wrappers:** Use `-v` or `--verbose` flag to print the exact Bazel |
| command being executed. |
| |
| **For CI/scripts:** Raw `bazel` commands work fine. Wrappers are optional |
| helpers for local development. |
| |
| ### Configuration files |
| |
| - `configured.bazelrc` - Written by `configure_bazel.py` (platform detection, |
| driver settings) |
| - `user.bazelrc` - Created by `iree-bazel-configure` (disk cache location, |
| custom configs) |
| - `build_tools/bazel/iree.bazelrc` - Main IREE configuration (localdev, GPU, |
| etc.) |
| |
| All three files are loaded automatically by Bazel in this order. |
| |
| ### GPU test targets |
| |
| GPU tests and samples need a target chip architecture (e.g., `gfx1100` for AMD |
| RDNA3). These are exposed as Bazel |
| [`string_flag`](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/common_settings_doc.md#string_flag) |
| build settings that can be overridden on the command line: |
| |
| | Flag | Default | CMake equivalent | |
| |------|---------|-----------------| |
| | `--//build_tools/bazel:rocm_test_target` | `gfx1100` | `IREE_ROCM_TEST_TARGET_CHIP` | |
| |
| ```shell |
| # Run AMDGPU CTS tests for a specific chip: |
| iree-bazel-test --//build_tools/bazel:rocm_test_target=gfx942 \ |
| //runtime/src/iree/hal/drivers/amdgpu/cts/... |
| |
| # Build test data for a different architecture: |
| iree-bazel-build --//build_tools/bazel:rocm_test_target=gfx1201 \ |
| //runtime/src/iree/hal/drivers/amdgpu/cts/... |
| ``` |
| |
| See the [AMDGPU driver README](https://github.com/iree-org/iree/tree/main/runtime/src/iree/hal/drivers/amdgpu/README.md) |
| for full quick-start instructions. |
| |
| #### How `flag_values` works in BUILD files |
| |
| BUILD files reference these flags via template variables in compiler flags and |
| format strings. The `flag_values` parameter maps placeholder names to build |
| setting labels: |
| |
| ```python |
| iree_hal_cts_testdata( |
| format_name = "amdgpu", |
| flags = ["--iree-rocm-target={ROCM_TARGET}"], |
| flag_values = {"ROCM_TARGET": "//build_tools/bazel:rocm_test_target"}, |
| format_string = '"amdgcn-amd-amdhsa--{ROCM_TARGET}"', |
| ... |
| ) |
| ``` |
| |
| At analysis time, Bazel reads the `string_flag` value and substitutes it into |
| all `{PLACEHOLDER}` occurrences in both `flags` and `format_string`. The |
| Bazel-to-CMake converter maps these to CMake variables automatically (e.g., |
| `{ROCM_TARGET}` becomes `${IREE_ROCM_TEST_TARGET_CHIP}`). |
| |
| ## What's next? |
| |
| ### Take a Look Around |
| |
| Build all of IREE's 'tools' directory: |
| |
| ```shell |
| bazel build //tools/... |
| ``` |
| |
| Check out what was built: |
| |
| ```shell |
| ls bazel-bin/tools/ |
| ./bazel-bin/tools/iree-compile --help |
| ``` |
| |
| Translate a |
| [MLIR file](https://github.com/iree-org/iree/blob/main/samples/models/simple_abs.mlir) |
| and execute a function in the compiled module: |
| |
| ```shell |
| # iree-run-mlir <compiler flags> [input.mlir] <runtime flags> |
| $ ./bazel-bin/tools/iree-run-mlir \ |
| --iree-hal-target-device=local \ |
| --iree-hal-local-target-device-backends=vmvx \ |
| --print-mlir \ |
| ./samples/models/simple_abs.mlir \ |
| --input=f32=-2 |
| ``` |