Skip to main content

A modern C++ builder based on C++20 Modules.

Project description

Cppmake: A C++20 Modules Build System

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.

Show

vedio

Install

Use pip to install cppmake:

pip install cppmake

Or install from source:

git clone https://github.com/anonymouspc/cppmake
cd cppmake
python install.py

Getting Started

In a cppmake project:

  • module aaa.bbb should be placed at module/aaa/bbb.cpp
  • module aaa:ccc should be placed at module/aaa/ccc.cpp
  • source main should be placed at source/main.cpp
  • std module 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

cppmake

The output will be generated in the binary/ directory.

Advanced

Cppmake provides various configurable options, such as:

cppmake --compiler=clang++ --std=c++23
cppmake --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!)

Configure

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.cpp imports module my_module and module boost.asio, then Cppmake will precompile module my_module, cmake build boost, and precompile module boost.asio before finally compiling source/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 through cppmake --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.

Integrating third-party packages

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.)

Thank you!

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

cppmake-127.0.17.tar.gz (24.5 kB view details)

Uploaded Source

Built Distribution

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

cppmake-127.0.17-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

Details for the file cppmake-127.0.17.tar.gz.

File metadata

  • Download URL: cppmake-127.0.17.tar.gz
  • Upload date:
  • Size: 24.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for cppmake-127.0.17.tar.gz
Algorithm Hash digest
SHA256 8ed3fa717d292993833088de1e0a3501f530e5ba378df25bd8a541d520f94c99
MD5 229bca5f278c06180562b2629529f45c
BLAKE2b-256 549f8aeb753cf7dc346c5d5b47684d25f207c3a975fee1789222db229edda4d9

See more details on using hashes here.

File details

Details for the file cppmake-127.0.17-py3-none-any.whl.

File metadata

  • Download URL: cppmake-127.0.17-py3-none-any.whl
  • Upload date:
  • Size: 39.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for cppmake-127.0.17-py3-none-any.whl
Algorithm Hash digest
SHA256 319837c043b1fb5c0a6a5f5e5815141133a02c4e2fe5216adc861380e18f38ec
MD5 de8fa57ed87c99401d5ae00110f5dbfe
BLAKE2b-256 3d22f410d11d999835e315d3f25c1ddf905250a579595266d70a381e241893be

See more details on using hashes here.

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