cpp2b - a build system for cpp2
If you don't know what cpp2 is then I highly recommend you checkout the cppfront repository and the cpp2 documentation before continuing here.
- cpp2 only (no cpp1[1])
- simple build system that "just works"
- C++20 module support only (no legacy headers)
- support for latest compilers only
- configurable with cpp2 itself (no config files)
There is no installer for cpp2b
at this time. Instead you must compile and install it yourself. There are some convenient scripts to do that in the root of this repository, but they are not guaranteed to work since cpp2b
and cppfront
are changing frequently. None the less you'll find 'instructions' for Windows and Linux below.
- install the latest msvc
- clone this repo
- run
.\install.cmd
- install the latest clang
- clone this repo
- run
./install.sh
As of writing this you'll need to manually compile libcxx with module support by following these instructions. After which you must assign the CPP2B_LIBCXX_BUILD_ROOT
environment variable to the folder where you built libcxx.
For example this is what I use to build libcxx on my machine running Ubuntu.
cd ~/projects
git clone https://github.com/llvm/llvm-project.git
cd llvm-project
mkdir build
CC=clang CXX=clang++ cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
ninja -C build
# install cpp2b
CPP2B_LIBCXX_BUILD_ROOT=~/projects/llvm-project/build ./install.sh
A cpp2b
project simply contains a build.cpp2
at it's root. This file gets compiled and the build
function is ran while building your project. Inside your build.cpp2
file you can configure your project. This configuration is very limited at this time and will be expanded more in the future. Other *.cpp2
files are discovered and are parsed to see what kind of output file should be built. If your .cpp2
file has a main
function then it is assumed to be an executable and if it contains a module
statement it is considered a module. All output from cpp2b
is in the directory .cache/cpp2
and should be added to the ignore file of your source control of choice.
If you want to just get started quickly then run:
cpp2b init
And a simple project will be ready for you to build!
cpp2b
clones the latest cppfront
, but only if it hasn't been already fetched in your project. This means your project might break if there's a breaking change with cppfront
. If you want update to the latest cppfront
you must delete your .cache/cpp2
directory or run cpp2b clean
.
Any .cpp2
file with a main
function under a cpp2b
project root will be turned into an executable. By default the executables name will be the name of the *.cpp2
source file.
// example.cpp2
main: () = std::println("look im writing cpp2!");
// subdir/another.cpp2
main: () = std::println("another executable already!?");
After running cpp2b build
you should see 2 paths in the .cache/cpp2/bin
directory printed for you. Notice how there is .cache/cpp2/bin/example
and .cache/cpp2/bin/subdir/another
(on Windows you would have .exe
extension.)
If you want your executables (binaries) to have a different name you can configure that in your build.cpp2
.
import cpp2b.build;
build: (inout b: cpp2b::build) -> void = {
b.binary_name("example", "a.exe"); // rename to a.exe
b.binary_name("subdir/another", "b.exe"); // rename to b.exe
}
Now our example
executable will be named a.exe
and subdir/another
will be named b.exe
(even on Linux!)
As of writing this cpp2 doesn't support support exporting modules. See the cppfront github issue. For that reason cpp2b
temporarily supports .cppm
files as source files. Once cppfront
supports modules directly in some capacity this support will be removed.
Any .cppm
file with a module
statement is considered a module.
// somedep.cppm
export module itsme;
import std;
export void do_something() {
std::println("message from itsms module do_something()");
}
This module will be named itsme
because of the export module
statement. The filename has nothing to do with the module name (unlike an executable.) If we now add a binary .cpp2
file that imports itsme
it should be discovered.
// example.cpp2
import itsme;
main: () = {
std::println("look im writing cpp2!");
do_something();
}
After running cpp2b
and we run .cache/cpp2/bin/example
(.exe
on Windows) the output should be:
look im writing cpp2!
message from itsms module do_something()