A Python-based build system that generates Ninja files
Project description
Pcons
A modern Python-based build system. Builds anything that requires a repeatable workflow using a dependency graph. Works with Ninja (or Makefile) to do the builds.
Overview
Pcons is inspired by SCons and CMake, taking a few of the best ideas from each:
- From SCons: Environments, Tools, dependency tracking, Python as the configuration language
- From CMake: Generator architecture (configure once, build fast), usage requirements that propagate through dependencies
Key design principles:
- Configuration, not execution: Pcons generates Ninja files; Ninja executes the build
- Python is the language: No custom DSL—build scripts are real Python with full IDE support
- Language-agnostic: Build C++, Rust, LaTeX, protobuf, or anything else
- Explicit over implicit: Dependencies are discoverable and traceable
- Extensible: Add-on modules for domain-specific tasks (plugin bundles, SDK configuration, etc.)
Why another software build tool?
I was one of the original developers of SCons, and helped maintain it for many years. I love that python is the config language; that makes build descriptions incredibly flexible and powerful. Recently I've been using CMake for more projects, and despite the deeply painful configuration language, I've come to appreciate its power: conan integration, the separation between describing the build and running it, and dependency propagation, among other things. I feel that SCons hasn't kept up with modern python; like any very widely used mature project, it has a lot of accumulated wisdom but also a bit ossified ways of doing things.
I've been thinking for years now about rearchitecting SCons onto a modern python stack with Path and decorators and all the other wonderful stuff python has been doing, and fixing some of the pain points at the same time (substitution/quoting, extensibility, tracing, separation between description and building, and more), but I've never had the time to dig into it. But recently as I've been using a lot more of Claude Code as a programming assistant, and it has gotten significantly better, it seemed like the right time to try this as a collaborative project. So, meet pcons!
Status
🚧 Under active development - ready for experimentation and feedback.
Core functionality is working: C/C++/Fortran compilation, static and shared libraries, programs, install targets, and mixed-language builds. See ARCHITECTURE.md for design details.
This Project is AI-Assisted
I've used Claude Code extensively to create this project, mostly Claude Opus 4.6. It has been a huge help in realizing a vision I've had for a long time. If you reflexively or morally reject all AI-generated or AI-assisted code, pcons is not for you. That said, I've reviewed every decision and nearly every line, and this code reflects my architecture, goals and priorities. I take full responsibility for it, and as a professional software engineer I stand behind it.
One of my sub-goals has been to make sure the documentation and source organization is clear; not just for humans but for browsing by AI agents. I want to make it easy for a human or an AI agent to create a best-practices pcons-build.py for your project quickly and easily. Using AI to auto-generate doc and make sure APIs are clean and consistent helps with that goal.
Quick Example
# pcons-build.py
from pcons.core.project import Project
from pcons.toolchains import find_c_toolchain
project = Project("myapp", build_dir="build")
# Find and configure a C/C++ toolchain
env = project.Environment(toolchain=find_c_toolchain())
env.cc.flags.extend(["-Wall"])
# Build a static library
lib = project.StaticLibrary("core", env)
lib.sources.append(project.node("src/core.c"))
lib.public.include_dirs.append(Path("include"))
# Build a program using it
app = project.Program("myapp", env)
app.sources.append(project.node("src/main.c"))
app.link(lib)
# Generate the ninja.build script
project.generate()
uvx pcons # generate ninja.build and run it, producing build/myapp (or build/myapp.exe)
Installation
No installation needed, if you have uv; just use uvx pcons to configure and build. uvx pcons --help for more info.
If you want to install it, though:
# Install as a CLI tool (recommended)
uv tool install pcons
pcons ...
# Or add to a project's dependencies
uv add pcons
# Or with pip
pip install pcons
Documentation
- User Guide is at ReadTheDocs
- ARCHITECTURE.md - Design document and implementation status
- CONTRIBUTING.md - How to contribute
Fetching Dependencies
pcons also ships with pcons-fetch, a helper for downloading and building
third-party dependencies from source using a simple deps.toml file.
Example:
[packages.zlib]
url = "https://zlib.net/zlib-1.3.1.tar.gz"
version = "1.3.1"
build = "cmake"
sha256 = "9a93b2b7df..."
pcons-fetch fetch deps.toml
sha256 is optional but recommended for archive downloads, especially in CI.
When present, pcons-fetch verifies the downloaded archive before extraction
and aborts on mismatch. This check applies to archive URLs, not Git clones.
Archive extraction is also path-safe: pcons-fetch rejects archive members
that try to escape the destination directory via absolute paths, ..
components, or tar/zip link tricks.
Development
# Run tests
uv run pytest
# Run linter
make lint
# Format code
make fmt
# Or use uv directly
uv run ruff check pcons/
uv run mypy pcons/
License
MIT License - see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pcons-0.10.0.tar.gz.
File metadata
- Download URL: pcons-0.10.0.tar.gz
- Upload date:
- Size: 1.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78214d18d5b2d78c374d9da14d4dc8612b7c1658394604d1f0221485cb2beb47
|
|
| MD5 |
aa41bd6e1ebb14322be520d2845b8d15
|
|
| BLAKE2b-256 |
dae079270896a4568cb52026926cec47297b10970f376b99d2bb9c80fc38370c
|
File details
Details for the file pcons-0.10.0-py3-none-any.whl.
File metadata
- Download URL: pcons-0.10.0-py3-none-any.whl
- Upload date:
- Size: 285.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23c020041f87a9df94a500279ce9f5940b4c99a8942c9817e0a0a6bd323e1397
|
|
| MD5 |
deab3ff77e95a8ed581b1d1cbc662e60
|
|
| BLAKE2b-256 |
ed6faef327883aa869c170a5af75a0d0c882c37af1784f42755e79c96208400e
|