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.16.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.16-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: cppmake-127.0.16.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.16.tar.gz
Algorithm Hash digest
SHA256 c9afdf452bd64d2b51d9a29b119841d9645f1b732d1b79bf0a93dc59c0add0d1
MD5 b5e342094749c623ca05efcdc7f3083b
BLAKE2b-256 bac8ce95dd93d26ed0bda5835955ce86f88fad5979ca71e7ffad21153ee057f3

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cppmake-127.0.16-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.16-py3-none-any.whl
Algorithm Hash digest
SHA256 97d368feaaf8f990390dd16af15e17b8f2129d9c0dc1c15419d1bf15681fa0c4
MD5 5866f1b8b2a31c09c3f5980af62ad966
BLAKE2b-256 f8c69296a602152bed4a9b912f6477d021e20f81e96f0cf9174b162d73344920

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