π¨ This software is currently in BETA. Features may be incomplete, contain bugs, or change without notice, and being frequently updated. Use at your own risk.
- Not recommended for production environments
- Data loss or corruption may occur
- APIs are subject to change without warning
- Limited support available
Please report any bugs or issues in the Issues section.
A TOML-based build system for C/C++ projects with seamless CMake and vcpkg integration.
CForge is a modern build system designed to simplify C/C++ project management. It provides a clean TOML-based configuration approach while leveraging the power of CMake and vcpkg under the hood.
- Features
- Installation
- Quick Start
- Command Reference
- Project Configuration
- Working with Dependencies
- Workspaces
- Developer Tools
- Cross-Compilation
- IDE Integration
- Scripts & Hooks
- Testing & Benchmarking
- Advanced Topics
- Examples
- Troubleshooting
- Goals & Roadmap
- Contributing
- License
- Simple TOML Configuration: Easy project setup without complex CMake syntax
- Multi-platform: Supports Windows, macOS, Linux
- Package Registry: Search and install packages from the cforge index (like Cargo)
- Dependency Management: Unified dependency config with registry, vcpkg, Git, and system deps
- Workspaces: Manage multiple projects together with dependency resolution
- Cross-compilation: Support for Android, iOS, Raspberry Pi, WebAssembly
- IDE Integration: VS Code, CLion, Xcode, Visual Studio
- Testing & Benchmarking: Integrated test runner and benchmark support
- Custom Scripts & Hooks: Run project-specific tasks at various stages
- Automatic Tool Setup: Installs missing tools automatically
- Enhanced Diagnostics: Cargo-style colored error output with fix suggestions
- Build Timing: See exactly how long builds take
- Developer Tools: Code formatting, linting, file templates, watch mode
- Shell Completions: Tab completion for bash, zsh, PowerShell, fish
- Documentation Generation: Integrated Doxygen support
- Package Creation: Create distributable packages for your software
Use the provided install scripts to build and install CForge.
# One-liner installation:
curl -fsSL https://raw.githubusercontent.com/ChaseSunstrom/cforge/master/scripts/install.sh | bash
# Or with options:
curl -fsSL https://raw.githubusercontent.com/ChaseSunstrom/cforge/master/scripts/install.sh | bash -s -- --prefix=/usr/local
# One-liner installation (run in PowerShell):
irm https://raw.githubusercontent.com/ChaseSunstrom/cforge/master/scripts/install.ps1 | iex- CMake (β₯3.15)
- C/C++ Compiler (GCC, Clang, MSVC)
- Optional: Ninja, Make, or Visual Studio Build Tools
# Create a new project in the current directory
cforge init
# Create a specific project type
cforge init --template static-lib # Create a static library project
cforge init --template header-only # Create a header-only library
# Build the project
cforge build
# Run the executable (for executable projects)
cforge runAfter initializing a project with cforge init, you'll have a structure like this:
myproject/
βββ cforge.toml # Project configuration
βββ src/
β βββ main.cpp # Main source file
βββ include/ # Header files
βββ scripts/ # Custom scripts
βββ build/ # Build artifacts (generated)
src/main.cpp (generated automatically):
#include <iostream>
int main(int argc, char* argv[]) {
std::cout << "Hello, cforge!" << std::endl;
return 0;
}CForge provides beautiful, Cargo-style colored output with build timing:
$ cforge build
cforge - C/C++ Build System beta-v2.2.0
Building myproject [Debug]
Setting up Git dependencies
Fetching 2 Git dependencies
Finished all Git dependencies are set up
Configuring project with CMake
Configuring CMake
Finished CMake configuration
Compiling myproject
Finished Debug target(s) in 3.67s
Finished Command completed successfully
$ cforge run
cforge - C/C++ Build System beta-v2.2.0
Building myproject [Debug]
Finished Debug target(s) in 0.42s
Running myproject
Hello, cforge!
Finished Program exited with code 0
| Command | Description | Example |
|---|---|---|
init |
Create a new project or workspace | cforge init --template lib |
build |
Build the project | cforge build --config Release |
clean |
Clean build artifacts | cforge clean |
run |
Run built executable | cforge run -- arg1 arg2 |
test |
Build and run unit tests | cforge test -c Release Math |
bench |
Run benchmarks | cforge bench --filter BM_Sort |
| Command | Description | Example |
|---|---|---|
search |
Search for packages in registry | cforge search json |
info |
Show package details | cforge info spdlog --versions |
add |
Add a dependency | cforge add fmt@11.1.4 |
remove |
Remove a dependency | cforge remove fmt |
deps |
Manage Git dependencies | cforge deps fetch |
vcpkg |
Manage vcpkg dependencies | cforge vcpkg install fmt |
tree |
Visualize dependency tree | cforge tree |
lock |
Manage dependency lock file | cforge lock --verify |
| Command | Description | Example |
|---|---|---|
fmt |
Format code with clang-format | cforge fmt --check |
lint |
Run clang-tidy static analysis | cforge lint --fix |
watch |
Auto-rebuild on file changes | cforge watch --run |
new |
Create files from templates | cforge new class MyClass |
doc |
Generate documentation | cforge doc --open |
| Command | Description | Example |
|---|---|---|
install |
Install project binaries | cforge install --prefix /usr/local |
package |
Create distributable packages | cforge package --type zip |
ide |
Generate IDE project files | cforge ide vscode |
list |
List projects, dependencies, etc. | cforge list build-order |
completions |
Generate shell completions | cforge completions bash |
| Command | Description | Example |
|---|---|---|
version |
Show version information | cforge version |
help |
Show help for a command | cforge help build |
update |
Update cforge or packages | cforge update --self |
All commands accept the following global options:
-v/--verbose: Enable verbose output-q/--quiet: Suppress non-essential output
Many commands support these options:
-c/--config: Build/run with specific configuration (e.g.,Debug,Release)
CForge includes powerful developer tools to improve your workflow.
Format your code using clang-format:
# Format all source files
cforge fmt
# Check formatting without modifying files
cforge fmt --check
# Show diff of what would change
cforge fmt --diff
# Use a specific style
cforge fmt --style=googleOutput:
cforge - C/C++ Build System beta-v2.2.0
Formatting 15 source files with clang-format
Formatted src/main.cpp
Formatted src/utils.cpp
Finished Formatted 15 files
Run clang-tidy static analysis:
# Run all checks
cforge lint
# Apply automatic fixes
cforge lint --fix
# Run specific checks
cforge lint --checks='modernize-*,bugprone-*'Automatically rebuild when files change:
# Watch and rebuild
cforge watch
# Watch, rebuild, and run
cforge watch --run
# Watch with Release configuration
cforge watch -c ReleaseOutput:
cforge - C/C++ Build System beta-v2.2.0
Watching for changes...
Tracking 47 files
Press Ctrl+C to stop
Building myproject [Debug]
Finished Debug target(s) in 1.23s
Changes detected:
Modified main.cpp
Building myproject [Debug]
Finished Debug target(s) in 0.89s
Create files from templates:
# Create a class with header and source
cforge new class MyClass
# Create with namespace
cforge new class MyClass -n myproject
# Create a header-only file
cforge new header utils
# Create a struct
cforge new struct Config
# Create an interface (abstract class)
cforge new interface IService
# Create a test file
cforge new test MyClass
# Create main.cpp
cforge new mainOutput:
cforge - C/C++ Build System beta-v2.2.0
Created include/my_class.hpp
Created src/my_class.cpp
Visualize your project dependencies:
cforge treeOutput (with colors):
cforge v2.2.0
|-- fmt @ 11.1.4 (git)
`-- tomlplusplus @ v3.4.0 (git)
Dependencies: 2 git
Dependencies are color-coded by type:
- Cyan: Git dependencies
- Magenta: vcpkg dependencies
- Yellow: System dependencies
- Green: Project dependencies (workspace)
Generate documentation with Doxygen:
# Generate documentation
cforge doc
# Create Doxyfile for customization
cforge doc --init
# Generate and open in browser
cforge doc --openEnable tab completion in your shell:
# Bash
cforge completions bash >> ~/.bashrc
# Zsh
cforge completions zsh >> ~/.zshrc
# PowerShell
cforge completions powershell >> $PROFILE
# Fish
cforge completions fish > ~/.config/fish/completions/cforge.fishThe cforge.toml file is the heart of your project configuration:
[project]
name = "myproject"
version = "1.0.0"
description = "My awesome C++ project"
cpp_standard = "17"
c_standard = "11"
binary_type = "executable" # executable, shared_library, static_library, header_only
authors = ["Your Name <you@example.com>"]
license = "MIT"
[build]
build_type = "Debug"
directory = "build"
source_dirs = ["src"]
include_dirs = ["include"]
[build.config.debug]
defines = ["DEBUG=1"]
flags = ["DEBUG_INFO", "NO_OPT"]
[build.config.release]
defines = ["NDEBUG=1"]
flags = ["OPTIMIZE"]
[test]
enabled = true
directory = "tests"
framework = "catch2" # or "gtest"
[benchmark]
directory = "bench"
target = "benchmarks"
[package]
enabled = true
generators = ["ZIP", "TGZ"]
vendor = "Your Name"The version from cforge.toml is automatically available as compile definitions:
#include <iostream>
int main() {
// Generic version macros (works for any project)
std::cout << "Version: " << PROJECT_VERSION << std::endl;
std::cout << "Major: " << PROJECT_VERSION_MAJOR << std::endl;
std::cout << "Minor: " << PROJECT_VERSION_MINOR << std::endl;
std::cout << "Patch: " << PROJECT_VERSION_PATCH << std::endl;
// Project-specific macros (e.g., for project named "myapp")
// std::cout << myapp_VERSION << std::endl;
return 0;
}Available macros:
| Macro | Description | Example |
|---|---|---|
PROJECT_VERSION |
Full version string | "1.2.3" |
PROJECT_VERSION_MAJOR |
Major version number | 1 |
PROJECT_VERSION_MINOR |
Minor version number | 2 |
PROJECT_VERSION_PATCH |
Patch version number | 3 |
<ProjectName>_VERSION |
Project-specific version | "1.2.3" |
Customize CMake behavior with includes, injections, and module paths:
[cmake]
version = "3.15" # Minimum CMake version
generator = "Ninja" # CMake generator
includes = ["cmake/custom.cmake"] # Custom CMake files to include
module_paths = ["cmake/modules"] # Custom module search paths
# Inject custom CMake code
inject_before_target = """
# Code inserted before add_executable/add_library
include(FetchContent)
"""
inject_after_target = """
# Code inserted after add_executable/add_library
target_precompile_headers(${PROJECT_NAME} PRIVATE <pch.hpp>)
"""
[cmake.compilers]
c = "/usr/bin/gcc-12"
cxx = "/usr/bin/g++-12"
[cmake.visual_studio]
platform = "x64"
toolset = "v143"Configure settings per platform (windows, linux, macos):
[platform.windows]
defines = ["WIN32", "_WINDOWS"]
flags = ["/W4"]
links = ["kernel32", "user32"]
[platform.linux]
defines = ["LINUX"]
flags = ["-Wall", "-Wextra"]
links = ["pthread", "dl"]
[platform.macos]
defines = ["MACOS"]
flags = ["-Wall"]
frameworks = ["Cocoa", "IOKit"] # macOS frameworksConfigure settings per compiler (msvc, gcc, clang, apple_clang, mingw):
[compiler.msvc]
flags = ["/W4", "/WX", "/permissive-"]
defines = ["_CRT_SECURE_NO_WARNINGS"]
[compiler.gcc]
flags = ["-Wall", "-Wextra", "-Wpedantic"]
[compiler.clang]
flags = ["-Wall", "-Wextra", "-Wpedantic"]
[compiler.mingw]
flags = ["-Wall", "-Wextra"]
defines = ["MINGW"]Combine platform and compiler for fine-grained control:
[platform.windows.compiler.msvc]
flags = ["/W4"]
defines = ["_CRT_SECURE_NO_WARNINGS"]
[platform.windows.compiler.mingw]
defines = ["MINGW_BUILD"]
links = ["mingw32"]
[platform.linux.compiler.gcc]
flags = ["-Wall", "-Wextra", "-fPIC"]CForge supports a unified dependency configuration with multiple sources. Dependencies are consolidated under the [dependencies] section with source options: index (default), git, vcpkg, system, and project.
CForge has a built-in package registry similar to Cargo. Search and add packages easily:
# Search for packages
cforge search json
# Get package info
cforge info spdlog --versions
# Add a package (defaults to registry)
cforge add fmt@11.1.4
# Add with specific features
cforge add spdlog@1.15.0 --features async,stdoutRegistry dependencies in cforge.toml:
[dependencies]
# Simple version constraint - uses CMake FetchContent by default
fmt = "11.1.4"
tomlplusplus = "3.4.0"
# With features and options
spdlog = { version = "1.15.0", features = ["async", "stdout"] }
# Header-only library
nlohmann-json = { version = "3.11.3", header_only = true }
# Wildcard versions (like Rust)
catch2 = "3.*" # Any 3.x version
benchmark = "1.9.*" # Any 1.9.x versionBy default, index dependencies use CMake's FetchContent to download packages during the CMake configure step. This is the recommended approach as it integrates seamlessly with CMake's dependency management.
To disable FetchContent and pre-clone packages instead:
[dependencies]
fetch_content = false # Pre-clone packages to vendor/ directory
directory = "vendor" # Where to clone packages (default: "deps")
fmt = "11.1.4"For packages not in the registry, use Git directly:
[dependencies]
# Git with tag
fmt = { git = "https://github.com/fmtlib/fmt.git", tag = "11.1.4" }
# Git with branch
imgui = { git = "https://github.com/ocornut/imgui.git", branch = "master", shallow = true }
# Git with specific commit
tomlplusplus = { git = "https://github.com/marzer/tomlplusplus.git", commit = "abc123" }Or use the CLI:
cforge add fmt --git https://github.com/fmtlib/fmt.git --tag 11.1.4Use vcpkg packages from the vcpkg ecosystem:
[dependencies.vcpkg]
enabled = true
path = "~/.vcpkg" # Optional: directory of vcpkg installation
triplet = "x64-windows" # Optional: specify vcpkg target triplet
[dependencies]
boost = { vcpkg = true }
openssl = { vcpkg = true, features = ["ssl", "crypto"] }Or use the CLI:
cforge add boost --vcpkg
cforge vcpkg install opensslSystem dependencies support three methods: find_package, pkg_config, and manual:
[dependencies]
# Auto-detect with CMake find_package
OpenGL = { system = true, method = "find_package", components = ["GL", "GLU"], target = "OpenGL::GL" }
# Auto-detect with pkg-config
x11 = { system = true, method = "pkg_config", package = "x11" }
# Manual specification
custom_lib = { system = true, method = "manual", include_dirs = ["/usr/local/include/custom"], libraries = ["custom"] }Add dependencies only for specific platforms:
[platform.windows.dependencies]
winapi = { vcpkg = true }
[platform.linux.dependencies]
x11 = { system = true, method = "pkg_config", package = "x11" }
[platform.macos.dependencies]
cocoa = { system = true, frameworks = ["Cocoa", "IOKit"] }Reference other projects in a workspace:
[dependencies]
core = { project = true, include_dirs = ["include"], link = true }
utils = { project = true, link_type = "PRIVATE" }# Update all packages from registry
cforge update --packages
# Update cforge itself
cforge update --selfEnsure reproducible builds with lock files:
# Generate/update lock file
cforge lock
# Verify dependencies match lock file
cforge lock --verify
# Force regeneration
cforge lock --forceWorkspaces allow you to manage multiple related CForge projects together.
# Initialize a workspace
cforge init --workspace my_workspace --projects core guiThis generates a cforge-workspace.toml:
[workspace]
name = "my_workspace"
projects = ["core", "gui"]
default_startup_project = "core"# Build all projects
cforge build
# Build specific project
cforge build -p gui
# List workspace projects
cforge list projects
# Show build order
cforge list build-order
# Visualize dependencies
cforge tree[dependencies.project.core]
include_dirs = ["include"]
link = true
link_type = "PRIVATE"# Run all tests
cforge test
# Run specific category
cforge test Math
# Run specific tests in Release
cforge test -c Release Math Add Divide
# Verbose output
cforge test -v# Run all benchmarks (builds in Release by default)
cforge bench
# Run specific benchmark
cforge bench --filter 'BM_Sort'
# Skip build
cforge bench --no-build
# Output formats
cforge bench --json > results.json
cforge bench --csv > results.csvConfigure benchmarks in cforge.toml:
[benchmark]
directory = "bench"
target = "my_benchmarks"CForge supports cross-compilation with a unified configuration:
[cross]
enabled = true
[cross.target]
system = "Linux" # CMAKE_SYSTEM_NAME
processor = "aarch64" # CMAKE_SYSTEM_PROCESSOR
toolchain = "path/to/toolchain.cmake" # Optional
[cross.compilers]
c = "/usr/bin/aarch64-linux-gnu-gcc"
cxx = "/usr/bin/aarch64-linux-gnu-g++"
[cross.paths]
sysroot = "/path/to/sysroot"
find_root = "/path/to/find/root"Define reusable cross-compilation profiles:
[cross.profile.android-arm64]
system = "Android"
processor = "aarch64"
toolchain = "${ANDROID_NDK}/build/cmake/android.toolchain.cmake"
variables = { ANDROID_ABI = "arm64-v8a", ANDROID_PLATFORM = "android-24" }
[cross.profile.raspberry-pi]
system = "Linux"
processor = "armv7l"
compilers = { c = "arm-linux-gnueabihf-gcc", cxx = "arm-linux-gnueabihf-g++" }
sysroot = "/path/to/rpi-sysroot"cforge build --profile android-arm64Supported platforms: Android, iOS, Raspberry Pi, WebAssembly, and more!.
Generate IDE-specific project files:
cforge ide vscode # VS Code
cforge ide clion # CLion
cforge ide xcode # Xcode (macOS)
cforge ide vs2022 # Visual Studio 2022Run custom scripts at build stages:
[scripts]
pre_build = ["scripts/setup_env.py", "scripts/gen_code.py"]
post_build = ["scripts/deploy.py"]CForge provides Cargo-style error output with helpful suggestions:
error: undefined reference to `math_lib::divide(int, int)'
--> src/main.cpp:12:5
|
12 | math_lib::divide(10, 0);
| ^~~~~~~~~~~~~~~~~~~~~~~
|
= help: The function 'divide' is declared but not defined
= hint: Check if the library containing this symbol is linked
error: no member named 'vetor' in namespace 'std'
--> src/utils.cpp:8:10
|
8 | std::vetor<int> nums;
| ^~~~~
|
= help: Did you mean 'vector'?
error: 'string' was not declared in this scope
--> src/parser.cpp:15:5
|
15 | string name;
| ^~~~~~
|
= help: Add '#include <string>' and use 'std::string'
error[summary]: Build failed with 3 errors and 2 warnings
CForge provides helpful suggestions for common linker errors:
error: LNK2019: unresolved external symbol "void __cdecl foo()"
= help: Common causes:
- Missing library in target_link_libraries
- Function declared but not defined
- Mismatched calling conventions
= hint: For 'WinMain': Link with kernel32.lib or check /SUBSYSTEM setting
# Verbose build output
cforge build -v
# Check formatting issues
cforge fmt --check
# Verify lock file
cforge lock --verify
# List configurations
cforge list configs- Simple TOML Configuration: Easy project setup without complex CMake syntax
- Multi-platform Support: Windows, macOS, Linux compatibility
- Package Registry: Search and add packages from the cforge index (
cforge search,cforge info,cforge add) - Unified Dependency Management: Consolidated
[dependencies]section with registry, vcpkg, Git, system, and project sources - Workspace Support: Multi-project management with dependency resolution
- IDE Integration: VS Code, CLion, Visual Studio, Xcode
- Testing: Integrated test runner with category/filter support
- Benchmarking: Google Benchmark integration
- Build Variants: Multiple configuration support
- Package Generation: ZIP, TGZ, DEB, NSIS packages
- Code Formatting: clang-format integration
- Static Analysis: clang-tidy integration
- Watch Mode: Auto-rebuild on file changes
- File Templates: Create classes, headers, tests from templates
- Documentation: Doxygen integration
- Shell Completions: bash, zsh, PowerShell, fish
- Dependency Visualization: Tree view of dependencies
- Enhanced Diagnostics: Cargo-style colored errors with suggestions
- Build Timing: Duration tracking for builds
- Lock Files: Reproducible builds with dependency locking
- Platform-Specific Configuration: Per-platform defines, flags, links, frameworks
- Compiler-Specific Configuration: Per-compiler settings (MSVC, GCC, Clang, MinGW)
- Enhanced System Dependencies: find_package, pkg_config, manual methods with platform filtering
- Subdirectory Dependencies: Use existing CMake projects as dependencies
- CMake Integration: Custom includes, module paths, code injection
- Cross-Compilation Profiles: Reusable cross-compilation configurations
- Plugin System: Custom build steps via plugins
- Code Coverage: Coverage report generation
- Sanitizer Integration: ASan, TSan, UBSan support
- CI/CD Templates: GitHub Actions, GitLab CI
- Remote Builds: Cloud/container-based builds
- Conan 2.0 Support: Additional package manager
Contributions welcome!
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-feature) - Commit your changes (
git commit -m 'Add new feature') - Push to your branch (
git push origin feature/new-feature) - Open a Pull Request
MIT License β see LICENSE.