Cppmake is a modern, fast, and accurate C++ build system focusing on C++20 Modules.
Cppmake aims to
- Make everything modular.
- Easily modularize third-party libraries.
- Be fast, parallel, and fully cached.
Cppmake is written in pure Python with no additional pip dependencies.
Use pip to install cppmake:
pip install cppmakeOr install from source:
git clone https://github.com/anonymouspc/cppmake
cd cppmake
python install.pyIn a cppmake project:
- module
aaa.bbbshould be placed atmodule/aaa/bbb.cpp - module
aaa:cccshould be placed atmodule/aaa/ccc.cpp - source
mainshould be placed atsource/main.cpp stdmodule will be auto-installed.
For example:
├── module
│ ├── aaa.cpp
│ ├── aaa
│ │ ├── bbb.cpp // aaa.bbb
│ │ └── ccc.cpp // aaa:ccc
│ └── ddd.cpp
├── source
│ └── main.cpp
└── cppmake.py
Then, run
cppmakeThe output will be generated in the binary/ directory.
Cppmake provides various configurable options, such as:
cppmake --compiler=clang++ --std=c++23cppmake --compiler=/opt/gcc/bin/g++ --linker=lld --std=c++26 --type=release --target=make --parallel=$(nproc)System/compiler support:
| clang | emcc | gcc | msvc | |
|---|---|---|---|---|
| Linux | ✓ | ✓ | ✓ | N/A |
| Macos | ✓ | ✓ | ✓ | N/A |
| Windows | ✗ | ✗ | ✗ | ✗ |
- ✓: Supported and tested.
- ✗: Not implemented yet; planned for future releases.
- (The author does not own a Windows PC. Contributions for Windows support are welcome!)
Cppmake uses a cppmake.py file (pure Python) to describe the C++ project. The configuration is entirely standard Python syntax.
For example:
from cppmakelib import *
def make():
Source("main").compile()This cppmake.py defines a single source source/main.cpp, which will be
built into a binary.
- (Imported modules and packages will be built automatically before compiling the source. For example, if
source/main.cppimports module my_module and moduleboost.asio, then Cppmake will precompile modulemy_module, cmake buildboost, and precompile moduleboost.asiobefore finally compilingsource/main.cpp.) - (By default, the imported modules and packages form a directed acyclic graph and will be executed with maximum possible parallelism, depending on your cpu thread count. You can control the level of parallelism using
cppmake --parallel=N, or force serial compilation throughcppmake --parallel=1.)
Another example:
from cppmakelib import *
if type(compiler) == Gcc:
compiler.compile_flags += ["-fno-inline"] # global
compiler.define_macros |= {"NDEBUG": '1'} # global
package.define_macros = {"MY_MACRO": "42"} # package-local
def build(): # select a source file to compile
if type(system) == Linux:
Source("linux").compile()
def test(): # compile and test all units
for file in iterate_dir("source/test", recursive=True):
Source(file=file).compile()
Executable(file=file).run()This cppmake.py defines 2 targets (switchable via
cppmake --target=build|test) and several configuration rules. You can
easily extend it with any other Python code.
Third-party packages should be located in package/, for example
├── module
│ ├── aaa.cpp
│ ├── aaa
│ │ ├── bbb.cpp // aaa.bbb
│ │ └── ccc.cpp // aaa:ccc
│ └── ddd.cpp
├── source
│ └── main.cpp
├── package
│ ├── boost
│ │ ├── git
│ │ │ └── [git clone]
│ │ ├── module
│ │ │ ├── boost.cpp // boost
│ │ │ └── boost
│ │ │ ├── asio.cpp // boost.asio
│ │ │ ├── beast.cpp // boost.beast
│ │ │ └── numeric.cpp // boost.numeric
│ │ │ ├── interval.cpp // boost.numeric.interval
│ │ │ └── ublas.cpp // boost.numeric.ublas
│ │ └── cppmake.py
│ └── eigen
│ ├── git
│ │ └── [git clone]
│ ├── module
│ │ └── eigen.cpp // eigen
│ └── cppmake.py
└── cppmake.py
In package/boost/cppmake.py we can define a build() function to describe how this package should be built. For example:
# package/boost/cppmake.py
from cppmakelib import *
def build():
cmake.build(
package=package,
args=[
"-DBUILD_SHARED_LIBS=OFF"
]
)Then:
// package/boost/module/boost/asio.cpp
module;
#include <boost/asio.hpp>
export module boost.asio;
export namespace boost::asio
{
using boost::asio::io_context;
//...
}will modularize boost.asio into a module.
Builder support:
| cmake | include* | makefile | meson | msbuild |
|---|---|---|---|---|
| ✓ | ✓ | ✓ | (soon) | ✗ |
- ✓: Supported and tested.
- ✗: Not implemented yet; planned for future releases.
- (include: means header-only libraries.)
