Ninja

raw JSON →
1.13.0 verified Tue May 12 auth: no python install: stale

Ninja is a small build system focused on speed, typically used with higher-level build systems like CMake to manage large projects. The Python package `ninja` provides the `ninja` executable and the `ninja_syntax.py` module for generating `.ninja` build files programmatically. It is currently at version 1.13.0 and actively maintained by scikit-build.

pip install ninja
error ninja: error: loading 'build.ninja': No such file or directory
cause This error occurs when the `ninja` executable is run in a directory where the `build.ninja` file, which defines the build rules, does not exist or cannot be found in the specified path.
fix
Ensure you are running ninja from the correct build directory where build.ninja was generated (e.g., a build/ or out/Default subdirectory created by CMake or another meta-build system). If the file is missing, you need to run the meta-build system (e.g., cmake .. -G Ninja) to generate it first.
error ninja: command not found
cause This error indicates that the `ninja` executable is not in your system's PATH environment variable, or it is not installed. When used with CMake, the error might appear as 'CMake Error: CMake was unable to find a build program corresponding to "Ninja"'.
fix
Install Ninja (e.g., pip install ninja for the Python package or sudo apt install ninja-build on Debian/Ubuntu, brew install ninja on macOS) and ensure its installation directory is correctly added to your system's PATH. For CMake, ensure Ninja is installed and discoverable by CMake, or specify its path using CMAKE_MAKE_PROGRAM.
error ModuleNotFoundError: No module named 'ninja'
cause This error occurs when a Python script tries to import the `ninja` module (typically `ninja_syntax.py` for generating build files) but the Python interpreter cannot find it. This usually means the Python `ninja` package is not installed in the active Python environment, or there's a conflict with other Python installations.
fix
Install the Python ninja package using pip: pip install ninja. Ensure you are installing it for the correct Python interpreter that your script is using, especially if you have multiple Python versions or virtual environments.
error ninja: build stopped: subcommand failed.
cause This is a generic error from Ninja indicating that one of the underlying commands (e.g., a compiler, linker, or custom script) that Ninja executed as part of the build process returned a non-zero exit code, signifying a failure. The actual, more specific error message from the failed subcommand is usually printed in the console output *before* this 'subcommand failed' line.
fix
Scroll up in your terminal or build log to find the detailed error message from the subcommand that failed. This message will provide the actual cause of the build failure (e.g., compilation error, linker error, missing file, incorrect arguments) which needs to be addressed.
breaking Versions of the `ninja` Python package after 1.13 no longer support Python 3.7. Similarly, versions after 1.11.1.1 dropped support for Python 2-3.6.
fix Upgrade your Python environment to 3.8 or newer if using recent `ninja` versions.
breaking The `pipes` module, which `ninja` relies on, was deprecated and removed in Python 3.13. This causes build failures when `ninja` is used with Python 3.13 or newer.
fix Downgrade your Python environment to 3.12 or earlier when using the `ninja` Python package. Alternatively, use a virtual environment with an older Python version.
gotcha Ninja is designed as a low-level build system. Its `.ninja` input files are intended to be generated by a higher-level build system (like CMake or Meson), not written or maintained by hand for complex projects. Attempting to manage complex build logic directly within `.ninja` files is an anti-pattern.
fix For complex projects, use a build system generator (e.g., CMake, Meson) to produce the `.ninja` files. Use `ninja_syntax` for simpler, programmatic generation if direct Python control is desired.
gotcha Building the `ninja` Python package from source using `--no-binary=ninja` can fail if CMake is not already installed on the system, as `ninja`'s build process sometimes requires CMake.
fix Ensure CMake is installed and in your PATH before attempting to install `ninja` with `--no-binary` flags, or prefer installing pre-built binary wheels.
gotcha Incorrectly generated dependency files (`dep-files`) by certain compilers can lead to `ninja` always triggering full re-builds even when no changes have occurred.
fix Verify the `dep-file` output format of your compiler. If necessary, wrap your compiler with a script to correct the `dep-file` format, or configure `ninja` to use alternative dependency scanning if available.
gotcha The `ninja_syntax` module is a separate Python package and is not bundled with the `ninja` package. Attempting to `import ninja_syntax` without installing it will result in a `ModuleNotFoundError`.
fix Install the `ninja-syntax` package separately using `pip install ninja-syntax`.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - - 17.8M
3.10 alpine (musl) - - - -
3.10 slim (glibc) wheel 1.5s - 18M
3.10 slim (glibc) - - - -
3.11 alpine (musl) wheel - - 19.7M
3.11 alpine (musl) - - - -
3.11 slim (glibc) wheel 1.5s - 20M
3.11 slim (glibc) - - - -
3.12 alpine (musl) wheel - - 11.6M
3.12 alpine (musl) - - - -
3.12 slim (glibc) wheel 1.4s - 12M
3.12 slim (glibc) - - - -
3.13 alpine (musl) wheel - - 11.3M
3.13 alpine (musl) - - - -
3.13 slim (glibc) wheel 1.5s - 12M
3.13 slim (glibc) - - - -
3.9 alpine (musl) wheel - - 17.3M
3.9 alpine (musl) - - - -
3.9 slim (glibc) wheel 1.8s - 18M
3.9 slim (glibc) - - - -

This quickstart demonstrates how to use `ninja_syntax` to programmatically generate a `build.ninja` file for a simple C project, and then execute the `ninja` command to build it. Ensure you have a C compiler (like `gcc`) installed and that `ninja` (the executable) is in your system's PATH.

import subprocess
from ninja_syntax import Writer
import os

# Create a simple build.ninja file
with open('build.ninja', 'w') as f:
    writer = Writer(f)
    writer.variable('cflags', '-Wall -Wextra')
    writer.rule('cc', 'gcc $cflags -c $in -o $out')
    writer.rule('link', 'gcc $in -o $out')
    writer.build('hello.o', 'cc', 'hello.c')
    writer.build('hello', 'link', 'hello.o')
    writer.default('hello')

# Create a dummy source file
with open('hello.c', 'w') as f:
    f.write("""
#include <stdio.h>

int main() {
    printf("Hello, Ninja!\n");
    return 0;
}
""")

print("Generated build.ninja and hello.c. Running ninja...")

try:
    # Run ninja
    result = subprocess.run(['ninja'], capture_output=True, text=True, check=True)
    print("Ninja build successful!")
    print("\nStdout:\n", result.stdout)
    if result.stderr:
        print("\nStderr:\n", result.stderr)

    # Optionally, run the built executable
    print("\nRunning built executable...")
    exec_result = subprocess.run(['./hello'], capture_output=True, text=True, check=True)
    print("Executable output:\n", exec_result.stdout)

except subprocess.CalledProcessError as e:
    print(f"Ninja build failed with error: {e}")
    print("\nStdout:\n", e.stdout)
    print("\nStderr:\n", e.stderr)
except FileNotFoundError:
    print("Error: 'ninja' command not found. Please ensure Ninja is installed and in your PATH.")

# Clean up generated files (optional)
# os.remove('build.ninja')
# os.remove('hello.c')
# if os.path.exists('hello.o'):
#     os.remove('hello.o')
# if os.path.exists('hello'):
#     os.remove('hello')