1
0
Fork 0
Dead-simple C/++ build tool!
Find a file
2025-12-06 11:54:22 -06:00
examples enable echo for C projects, simplify output 2025-12-06 11:54:22 -06:00
include enable echo for C projects, simplify output 2025-12-06 11:54:22 -06:00
src enable echo for C projects, simplify output 2025-12-06 11:54:22 -06:00
tests tests without suite, use global suite 2025-11-09 22:32:37 -06:00
.gitignore keep working on fixing tests compilation flow 2025-11-13 18:58:52 -06:00
AI.md v0.2.11, fix test source access 2025-11-13 07:47:29 -06:00
bootstrap.ps1 split source and header files to better match expected pattern for mako projects 2025-11-08 09:00:55 -06:00
bootstrap.sh fix original errors 2025-11-15 09:08:14 -06:00
build.toml truly embed echo 2025-11-09 21:49:48 -06:00
EXAMPLES.md v0.2.10, license and copyright, updated guides and docs 2025-11-12 21:52:47 -06:00
GUIDE.md write up a guide, update style rules, do some refactor on builder 2025-11-10 11:05:47 -06:00
LICENSE.md v0.2.10, license and copyright, updated guides and docs 2025-11-12 21:52:47 -06:00
README.md readme updates 2025-11-12 21:57:10 -06:00
SPEC.md v0.2.10, license and copyright, updated guides and docs 2025-11-12 21:52:47 -06:00
STYLE.md big code refactor 2025-11-10 13:07:34 -06:00

Mako

A dead-simple build tool for C/C++ that just works.

No more wrestling with gnarly build configs. Drop in a minimal build.toml, run mako build, and you're shredding. Auto-discovers your source files, headers, and system libraries so you can focus on writing code instead of debugging Makefiles.

Heads up! Mako (v0.2.10) is production-ready for most C/C++ projects. It's been battle-tested on simple to medium codebases, self-hosts (builds itself!), and rocks solid incremental builds with content-hash caching. Still shaking out the kinks on macOS/Windows, but Linux is absolutely shredding. Stoked to have you try it out!


TL;DR

mako initmako run🏄 You're surfing


Why Mako?

I like Makefiles, and there are rad projects like xmake, bazel, ninja... but they're all way too complex for my taste. I wanted something declarative that auto-discovers everything, like PHP's autoloader but for C++.

The vibe:

  • Zero-config defaults (literally just name and language)
  • Auto-discovers everything (sources, headers, includes, system libs, tests, examples)
  • Crazy-fast incremental builds with content-hash caching (survives git operations!)
  • npm-style scripts for custom build workflows
  • Built-in dependency graphs (ASCII + interactive HTML)
  • Embedded test framework (zero external deps)
  • Auto-generates compile_commands.json for sick IDE integration
  • Works across platforms without platform-specific BS

No dependency graphs to maintain. No build scripts to debug. Just build.

Quick Start

Option 1: Interactive setup

mako init        # Set up a new project (asks for name, language, etc.)
mako build       # Build it
mako run         # Run it

Option 2: Quick start with defaults

mako new my-project   # Creates new directory with everything ready
cd my-project
mako build
mako run

Option 3: Manual setup

# build.toml
name = "myapp"
language = "c++17"
mako build

That's it. Mako will:

  • Find all .cpp files in src/
  • Auto-detect include/ and add it to include paths
  • Discover headers from your #include directives
  • Auto-link system libraries (pthread, math, etc.)
  • Compile in parallel across all your cores
  • Cache everything with content-hash validation (survives git checkout!)
  • Generate compile_commands.json for IDE magic
  • Generate .gitignore and initialize git automatically

Output: build/bin/myapp

Installation

From Source (Bootstrap)

Mako builds itself. First-time setup:

Linux/macOS:

git clone <repository-url>
cd mako
./bootstrap.sh

Windows (PowerShell):

git clone <repository-url>
cd mako
powershell -ExecutionPolicy Bypass -File bootstrap.ps1

After bootstrap, rebuild with itself:

./build/mako build    # Now at: build/bin/mako

Commands

Project setup:

mako init              # Initialize project in current directory (interactive)
mako i                 # Short form
mako new <name>        # Create new project directory (uses defaults)
mako n <name>          # Short form

Building:

mako build             # Build (incremental)
mako b                 # Short form
mako b -c              # Clean build (rebuild everything)
mako b -q              # Quiet mode
mako b -v              # Verbose (show compiler commands)

Running:

mako run               # Build and run main executable
mako r                 # Short form
mako run --test foo    # Build and run tests/foo.cpp
mako run -t foo        # Short form
mako run --example bar # Build and run examples/bar.cpp
mako run -e bar        # Short form

Development:

mako clean             # Remove build artifacts
mako clean --dry-run   # Preview what would be deleted
mako watch             # Watch files and auto-rebuild on changes
mako w                 # Short form
mako list [category]   # List project components (sources, headers, libs, etc.)
mako graph [format]    # Visualize dependencies (ascii or html)
mako script <name>     # Run custom scripts from build.toml

Project Initialization Features

mako init - Interactive setup in current directory:

  • Prompts for project name, language, and build mode
  • Creates build.toml, .gitignore, src/, and main.cpp
  • Smart-merges .gitignore if it already exists
  • Skips creating files/directories that already exist
  • Automatically runs git init if git is available

mako new <name> - Quick project creation:

  • Creates new directory with the project name
  • Uses sensible defaults (c++17, executable mode)
  • Generates complete project structure
  • Perfect for starting new projects quickly

Both commands generate a comprehensive .gitignore that includes build artifacts, editor files, and OS-specific files.

Auto-Discovery Magic

Mako handles the boring stuff automatically:

🔍 Auto-Detected Directories

Common directories are automatically added to include paths:

  • include/, inc/, headers/ (standard header locations)
  • src/ (headers alongside source)
  • lib/, libs/ (library headers)

This means clean includes:

#include "core/app.hpp"      // ← No ugly ../../ paths!
#include "utils/logger.hpp"  // ← Just works

📦 Auto-Discovered Libraries

Mako detects system libraries from your includes:

#include <pthread.h>  // → Auto-links -lpthread
#include <cmath>      // → Auto-links -lm (Unix/Linux)

Build output shows what it found:

Auto-discovered 2 system libraries: m, pthread

Supports: pthread, math, dl, rt, uring, OpenSSL, zlib, and more...

📁 Source Discovery

Recursively finds all source files in src/:

  • C++: .cpp, .cc, .cxx
  • C: .c
  • Headers: .h, .hpp (for dependency tracking)

Incremental Builds

Tracks source files, headers, object files, and config changes. Only rebuilds what changed. Typical incremental build: < 100ms.

🧪 Auto-Discovered Tests & Examples

Drop .cpp files in tests/ or examples/ and they're automatically available:

# Project structure:
# tests/test_parser.cpp
# tests/test_lexer.cpp
# examples/hello.cpp

mako run --test test_parser    # Builds and runs tests/test_parser.cpp
mako run --example hello       # Builds and runs examples/hello.cpp

The magic:

  • Tests and examples automatically link against your main project sources
  • No need to configure each one in build.toml
  • Main's main() function is excluded from linking (no conflicts)
  • Build outputs go to build/tests/bin/ and build/examples/bin/

Zero config required. Just drop files in tests/ or examples/ and run them.

Basic Config

Minimal (required):

name = "myapp"
language = "c++17"    # c++20, c++17, c11, c99, etc.

Common settings:

source_dir = "src"              # Default: "src"
build_dir = "build"             # Default: "build"
threads = 8                     # Default: all cores
optimization = "release"        # 0, 1, 2, 3, debug, release, size, fast
warnings = "all"                # all, basic, none, error

External libraries:

pkg_config = ["openssl", "zlib"]           # System libs via pkg-config
link_libs = ["pthread", "m"]               # Direct link (optional - auto-detected!)
lib_dirs = ["vendor", "third_party"]       # Vendored libraries

Note: include/ is auto-detected! Only add include_dirs for non-standard directories:

include_dirs = ["third_party/custom"]      # Additional only

See EXAMPLES.md for detailed configs and advanced usage.

Multiple Executables

Auto-discovered (easiest): Files in tests/ and examples/ are automatically built and linked:

# Just drop files in tests/ or examples/
tests/test_parser.cpp
examples/demo.cpp

mako run --test test_parser    # Automatically builds and runs
mako run --example demo        # Automatically builds and runs

Manual config (for custom executables): For executables outside tests/ and examples/, or with special needs:

name = "mylib"
language = "c++17"

[executables.benchmark]
source_dir = "benchmarks"
entry_point = "bench.cpp"
ldflags = ["-lpthread"]

Build all with one command:

mako build
# Outputs:
#   build/bin/mylib
#   build/tests/bin/test_parser      (auto-discovered)
#   build/examples/bin/demo          (auto-discovered)
#   build/benchmarks/bin/benchmark   (manual config)

Automatic linking: All additional executables automatically link against your main project sources (excluding main.cpp to avoid conflicts).

More details: EXAMPLES.md

Library Mode

For header-only or library projects (no main executable):

mode = "library"    # Skips building main executable

[executables.demo]
source_dir = "examples"
entry_point = "demo.cpp"

Compiles library sources, skips main executable, links them into your examples.

Details: EXAMPLES.md

Platform-Specific Config

Override settings per platform:

[linux]
compiler = "gcc"
link_libs = ["pthread", "dl"]

[darwin]
compiler = "clang"

[windows]
link_libs = ["ws2_32"]

Supported: linux, darwin, bsd, windows

IDE Integration

Mako automatically generates compile_commands.json on every build for seamless IDE/editor integration.

What you get:

  • Autocomplete that actually works
  • Go-to-definition across your codebase
  • Real-time error checking
  • Find references and refactoring tools

How to use:

Just build your project:

mako build

This creates compile_commands.json at your project root. Most editors detect it automatically.

Editor setup examples:

VS Code (with clangd extension):

// .vscode/settings.json
{
  "clangd.arguments": ["--background-index"]
}

Neovim (with nvim-lspconfig):

require('lspconfig').clangd.setup{}

CLion/IntelliJ: Automatically detects compile_commands.json - no config needed!

The database includes ALL source files (even cached ones), so your IDE has complete project information from the first build. Incremental builds preserve and update entries automatically.

Development Workflow

Clean Command

Remove all build artifacts to start fresh:

mako clean

What gets removed:

  • Build directory (respects your build.toml config)
  • compile_commands.json

Use --dry-run to preview:

mako clean --dry-run
# Shows what would be deleted without removing anything

When to use:

  • Before a clean rebuild
  • To free up disk space
  • When troubleshooting cache issues
  • Before committing to version control

Watch Mode

Automatically rebuild on file changes. Perfect for development:

mako watch

What it does:

  • Performs initial build
  • Watches source directory recursively
  • Detects changes to .cpp, .c, .h, .hpp files
  • Automatically triggers incremental rebuilds
  • Continues even if build fails (shows errors and keeps watching)
  • Stops gracefully with Ctrl+C

Example output:

Watch Mode =============================

Watching: src

Running initial build...
✓ Initial build complete!

Watching for changes... (Press Ctrl+C to stop)
  src/main.cpp (modified)

Change detected, rebuilding...
✓ Build complete!

Smart features:

  • Debouncing: Waits 200ms after last change to avoid excessive rebuilds
  • Recursive: Automatically watches new subdirectories as they're created
  • Filtered: Only watches relevant C/C++ source and header files
  • Efficient: Uses platform-specific file watching APIs (inotify on Linux)

Platform support:

  • Linux (inotify)
  • ⚠️ macOS/BSD (planned - kqueue)
  • ⚠️ Windows (planned - ReadDirectoryChangesW)

Features That Rock

Content-hash caching - Rebuild only what actually changed (survives git operations!)

Incremental builds - Rebuild in milliseconds, not minutes

Parallel compilation - Uses all CPU cores by default

Auto-discovery - Source files, headers, include paths, system libraries, tests, examples

Automatic linking - Tests and examples auto-link to your project sources

List command - Inspect project components (sources, headers, libs, executables)

Dependency graphs - Visualize your codebase (ASCII terminal or interactive HTML)

Custom scripts - npm-style script system for build workflows

Run command - Build and execute with mako run --test or --example

Watch mode - Auto-rebuild on file changes with smart debouncing

Clean command - Remove build artifacts with dry-run preview

IDE integration - Auto-generates compile_commands.json for LSP servers (clangd, ccls)

Embedded test framework - Echo testing built-in (zero external dependencies)

Cross-platform - Linux (battle-tested), macOS/BSD/Windows (code complete, needs testing)

Zero dependencies - Self-contained, no external tools needed (even xxHash64 is embedded!)

Self-hosting - Mako builds itself successfully

Fast - Minimal TOML parser, optimized build pipeline

Platform Support

Platform Status Compilers
Linux Tested gcc, clang
macOS ⚠️ Needs testing clang, gcc
FreeBSD ⚠️ Needs testing clang, gcc
Windows ⚠️ Needs testing gcc (MinGW), msvc

Documentation

  • EXAMPLES.md - Detailed configs, advanced features, complete examples
  • build.toml - Annotated config with all options

Known Limitations

Mako is intentionally simple:

  • No package manager (yet - vendor your deps or use pkg-config)
  • No Windows/macOS/BSD testing yet (code complete, should work, needs validation)
  • ⚠️ Simplified TOML parser (supports what we need, not full spec)

These might be features, depending on your perspective. Mako is for projects that just need compilation without ceremony. Need complex build logic? Use CMake. Just want to compile code? Mako's got you.

Contributing

Mako needs testing! If you:

  • Try it on macOS, BSD, or Windows
  • Find bugs or rough edges
  • Have ideas for staying simple while adding value

Open an issue or PR! The goal is maximum simplicity with maximum utility.

FAQ

Q: Why another build system? A: Sometimes you just want to compile code without reading 200 pages of docs.

Q: Is it production ready? A: For Linux? Absolutely! Mako v0.2.10 is battle-tested, self-hosts, and rocks solid content-hash caching. For macOS/Windows? Code's there but needs testing. Use it for real projects on Linux, be the guinea pig for other platforms.

Q: Will it support [complex feature X]? A: Probably not. Simplicity is the goal. CMake exists for complex needs.

Q: Can I use it for [language X]? A: Only C/C++ for now. Might support others if it stays simple.

License

Sharkk Proprietary License