A cargo-like build system.
Another relevant comic (all credit to xkcd):
- Big three compiler support (GCC, Clang, MSVC)
- Big three platform support (Linux, MacOS, Windows)
- Task runner using
muuk run <script>. Works pretty much likenpm run <script> - Clean command
- C++ Meta builder built on top of Ninja
- C++20 Experimental Module Support (MSVC only)
- Able to define Platform, Compiler & Profile Specific Flags
- All flags are automatically applied to dependencies
muuk requires the following programs to be installed and available on the PATH:
gitninja(you probably have this since I believe its bundled with most CMake distributions.)wgetclang-scan-deps(only needed if you plan on using modules)
Thats it!
A typical muuk.toml file looks like the one contained within this repo muuk.toml
Lets break it apart:
This section defines the package's metadata (name and version).
[package]
name = "muuk"
version = "1.0.0"
edition = "20"name→ The name of the project.version→ The project version.edition→ Doesn't do anything (yet)
The [library] section defines libraries that can be compiled separately and linked into other targets.
[library]
include = ["include"]
sources = ["src/source_file.cpp", "src/sauce_file.cpp - DSAUCE_FILE_ONLY_DEFINE -ISAUCE_FILE_ONLY_INCLUDE"]
sources = ["src/module_file.cppm"]
cflags = ["-Wall", "-Wextra"]
dependencies = { boost = { version = "1.75.0", muuk_path = "../boost" } }include→ A list of include directories.sources→ A list of source files for the library.module→ A list of module files for the librarycflags→ Compiler flags specific to this library.dependencies→ Defines dependencies required by this library.
Note on the single file flags, you can define file specific compilation flags by including them after the definition.
Dependency Format:
dependencies = { dep_name = { version = "X.Y.Z", git = "https://example.com/author/repo.git", muuk_path = "path/to/dep" } }This section defines build targets, which can be executables or other build artifacts.
[build.my_executable]
profiles = ["release", "debug"]
sources = ["src/main.cpp"]
dependencies = ["my_library"]sources→ Source files used to build the target.dependencies→ Libraries this build target depends on.
Note that this build artifact will include the compiler specific rules.
Profiles define build configurations, such as debug and release, but they can be whatever.
[profile.base]
cflags = ["-std:20"]
[profile.debug]
inherits = ["base"]
cflags = ["-g", "-O0"]
lflags = []
[profile.release]
inherits = "base"
cflags = ["-O2"]
lflags = []cflags→ Compiler flags for the profile.lflags→ Linker flags for the profile.
The [platform] section defines platform-specific flags. Acceptable platforms are windows, linux, apple.
[platform.windows]
cflags = ["-DWIN32"]
lflags = ["-lkernel32"]
[platform.linux]
cflags = ["-DLINUX"]
lflags = ["-pthread"]cflags→ Compiler flags for this platform.lflags→ Linker flags for this platform.
This section defines compiler-specific flags. Acceptable compilers are gcc, msvc or clang
[compiler.g++]
cflags = ["-std=c++20"]
lflags = ["-lstdc++"]cflags→ Compiler flags specific to this compiler.lflags→ Linker flags specific to this compiler.
This section defines build-related scripts, such as running an executable. This works like npm run <script>. Also muuk will add the name of your built executable so you can easily run it (not yet implemented though).
[scripts]
do = "something.exe"run→ Defines how to run the built executable.
Little Extra Stuff I have Planned So I don't Forget
[library.external]
type = "cmake",
path = "../some_cmake_lib",
args = ["-DBUILD_SHARED_LIBS=ON"]
outputs = ["build/cmake_some_cmake_lib/libmylib.a"]
Output will define the library to link against.


