π¨ 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
- Cross-Compilation
- IDE Integration
- Scripts & Hooks
- Testing
- Advanced Topics
- Examples
- Troubleshooting
- Goals & Roadmap
- Contributing
- License
- Simple TOML Configuration: Easy project setup without complex CMake syntax
- Multi-platform: Supports Windows, macOS, Linux
- Dependency Management: Integrated support for
vcpkg
, Git, and custom dependencies - 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: Integrated with CTest
- Custom Scripts & Hooks: Run project-specific tasks at various stages
- Automatic Tool Setup: Installs missing tools automatically
- Enhanced Diagnostics: Clear, informative compiler errors
- Build Variants: Easily switch between different build configurations
- Package Management: Create distributable packages for your software
Use the provided bootstrap scripts to build and install CForge.
bash scripts/bootstrap.sh
.\scripts\bootstrap.ps1
scripts\bootstrap.bat
- 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 run
After 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 build
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β cforge - C/C++ Build System beta-v2.0.0 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Using build configuration: Debug
β Building project: hi2 [Debug]
β Configuring with CMake...
β Running CMake Configure...
β Command: cmake -S C:\hi2 -B C:\hi2\build -DCMAKE_BUILD_TYPE=Debug -DDEBUG=1 -DENABLE_LOGGING=1 -DENABLE_TESTS=ON -G "Ninja Multi-Config"
β CMake Configure completed successfully
β Building with CMake...
β Built project: hi2 [Debug]
β Command completed successfully
$ cforge run
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β cforge - C/C++ Build System beta-v2.0.0 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Running in single project context
β Project: hi2
β Configuration: Debug
β Configuring project...
β Building project...
β Project built successfully
β Running executable: C:\hi2\build\bin\Debug\hi2.exe
β Program Output
Hello from hi2!
β Program exited with code 0
β Command completed successfully
Command | Description | Example |
---|---|---|
init |
Create a new project or workspace (supports --template , --workspace , --projects ) |
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 (supports config, category & test filters) | cforge test -c Release Math Add |
install |
Install project binaries | cforge install --prefix /usr/local |
deps |
Manage dependencies | cforge deps --update |
script |
Execute custom scripts | cforge script format |
startup |
Manage workspace startup project | cforge startup my_app |
ide |
Generate IDE project files | cforge ide vscode |
package |
Package project binaries | cforge package --type zip |
list |
List variants, configs, or targets | cforge list variants |
All commands accept the following global options:
-v/--verbose
: Set verbosity level
Many commands support these options:
--config
: Build/run with specific configuration (e.g.,Debug
,Release
)
CForge includes a built-in test runner (no external CTest calls needed). By default your tests live in the directory specified by test.directory
in cforge.toml
(defaults to tests
). To build and run tests:
# Run all tests in Debug (default)
cforge test
# Run only the 'Math' category in Debug
cforge test Math
# Run specific tests in Release
cforge test -c Release Math Add Divide
# Explicitly separate CForge flags from filters
cforge test -c Release -- Math Add Divide
Options:
-c, --config <config>
: Build configuration (Debug, Release, etc.)-v, --verbose
: Show verbose build & test output
Positional arguments (after flags, or after --
):
<category>
: Optional test category to run<test_name> ...
: Optional list of test names under the category
The cforge.toml
file is the heart of your project configuration:
[project]
name = "cforge"
version = "2.0.0"
description = "A C/C++ build tool with dependency management"
cpp_standard = "17"
binary_type = "executable" # executable, shared_library, static_library, header_only
authors = ["Chase Sunstrom <casunstrom@gmail.com>"]
homepage = "https://github.com/ChaseSunstrom/cforge"
repository = "https://github.com/ChaseSunstrom/cforge.git"
license = "MIT"
[build]
build_type = "Debug"
directory = "build"
source_dirs = ["src"]
include_dirs = ["include"]
[build.config.debug]
defines = ["DEBUG=1", "FMT_HEADER_ONLY=ON"]
flags = ["DEBUG_INFO", "NO_OPT"]
[build.config.release]
defines = ["NDEBUG=1"]
flags = ["OPTIMIZE"]
[test]
enabled = false
[package]
enabled = true
generators = []
vendor = "Chase Sunstrom"
contact = "Chase Sunstrom <casunstrom@gmail.com>"
[platforms.windows]
defines = ["WINDOWS", "WIN32"]
flags = ["UNICODE"]
[platforms.darwin]
defines = ["OSX"]
flags = []
[platforms.linux]
defines = ["LINUX"]
flags = []
CForge supports multiple dependency management systems:
[dependencies.vcpkg]
enabled = true
path = "~/.vcpkg" # Optional, defaults to ~/.vcpkg
packages = ["fmt", "boost", "nlohmann-json"]
Example C++ code using vcpkg dependencies:
#include <fmt/core.h>
#include <nlohmann/json.hpp>
int main() {
// Using fmt library from vcpkg
fmt::print("Hello, {}!\n", "world");
// Using nlohmann/json library from vcpkg
nlohmann::json j = {
{"name", "CForge"},
{"version", "1.2.0"}
};
fmt::print("JSON: {}\n", j.dump(2));
return 0;
}
[[dependencies.git]]
name = "nlohmann_json"
url = "https://github.com/nlohmann/json.git"
tag = "v3.11.3"
# Optional settings
shallow = true # Faster clone with reduced history
update = false # Whether to update the repo on builds
[[dependencies.git]]
name = "fmt"
url = "https://github.com/fmtlib/fmt.git"
tag = "9.1.0"
cmake_options = ["-DFMT_TEST=OFF", "-DFMT_DOC=OFF"] # Pass CMake options when building
[[dependencies.git]]
name = "imgui"
url = "https://github.com/ocornut/imgui.git"
branch = "master" # Use a specific branch instead of tag
shallow = true
[[dependencies.git]]
name = "custom_repo"
url = "https://example.com/repo.git"
commit = "abc123def456" # Use a specific commit hash
Git dependencies are automatically cloned into a deps directory. The libraries can be included in your project by adding their include paths to your target configuration:
[targets.default]
include_dirs = ["include", "deps/nlohmann_json/single_include", "deps/fmt/include"]
defines = ["FMT_HEADER_ONLY"] # Optionally add defines for your dependencies
You can also use the libraries in your code immediately:
#include <nlohmann/json.hpp>
#include <fmt/core.h>
int main() {
// Using nlohmann/json
nlohmann::json obj = {{"name", "cforge"}, {"version", "1.4.0"}};
// Using fmt
fmt::print("Project: {}\n", obj["name"].get<std::string>());
return 0;
}
[dependencies]
system = ["X11", "pthread", "dl"]
Workspaces allow you to manage multiple related CForge projects together. You can initialize a new workspace and specify which project directories it should include.
# Initialize a workspace named "my_workspace" managing two project folders
cforge init --workspace my_workspace --projects projects/core projects/gui
This generates a cforge-workspace.toml
file at the workspace root with contents like:
[workspace]
name = "my_workspace"
projects = ["projects/core", "projects/gui"]
default_startup_project = "projects/core"
To build all projects in the workspace:
cforge build
To build or run a specific project, pass its directory name:
cforge build projects/gui
cforge run projects/gui
CForge supports cross-compilation for various platforms:
[cross_compile]
enabled = true
target = "android-arm64"
sysroot = "$ANDROID_NDK/platforms/android-24/arch-arm64"
cmake_toolchain_file = "$ANDROID_NDK/build/cmake/android.toolchain.cmake"
flags = ["-DANDROID_ABI=arm64-v8a", "-DANDROID_PLATFORM=android-24"]
Cross-compilation targets:
android-arm64
: Android ARM64 platformandroid-arm
: Android ARM platformios
: iOS ARM64 platformraspberry-pi
: Raspberry Pi ARM platformwasm
: WebAssembly via Emscripten
Example:
cforge build --target android-arm64
Generate IDE-specific project files:
# VS Code
cforge ide vscode
# CLion
cforge ide clion
# Xcode (macOS only)
cforge ide xcode
# Visual Studio (Windows only)
cforge ide vs2022
cforge ide vs:x64 # With architecture specification
- CMake not found: Ensure it's installed and in PATH.
- Dependency failures: Run
cforge deps --update
. - Cross-compilation: Check environment variables (e.g.,
$ANDROID_NDK
). - Compiler errors: Use
cforge build --verbosity verbose
.
CForge provides enhanced error diagnostics:
Build error details:
ERROR[E0001]: undefined reference to 'math_lib::divide(int, int)'
--> src/main.cpp:12:5
12| math_lib::divide(10, 0);
^~~~~~~~~~~~~~~~
help: The function 'divide' is used but not defined. Check if the library is properly linked.
# List available configurations
cforge list configs
# List available build variants
cforge list variants
# List cross-compilation targets
cforge list targets
# List custom scripts
cforge list scripts
CForge is continuously evolving to simplify C/C++ project management while providing powerful features. Here's what we've accomplished and where we're headed next:
- Simple TOML Configuration: Easy project setup without complex CMake syntax
- Multi-platform Support: Windows, macOS, Linux compatibility
- Core Dependency Management: Integrated vcpkg and git dependencies
- Workspace Support: Basic multi-project management
- IDE Integration: VS Code, CLion support
- Testing: Test integration
- Build Variants: Multiple configuration support
- Package Generation: Create distributable packages
- Enhanced Workspace Dependencies: Improving library detection and linking
- Precompiled Header Optimization: Better build performance
- Diagnostic Improvements: Clearer error messages and suggestions
- Documentation Expansion: More examples and quick-start guides
-
Enhanced IDE Support
- Better Visual Studio project generation
- QtCreator integration
- Eclipse CDT support
- Xcode project improvements
-
Plugin System
- Custom build steps via plugins
- Language server integration
- Code generation tools
-
Documentation Features
- Automatic API documentation generation
- Doxygen integration
-
Advanced Testing
- Code coverage reports
- Benchmark framework integration
- Sanitizer integrations
-
CI/CD Pipeline Integration
- GitHub Actions templates
- GitLab CI templates
- Azure DevOps integration
-
Mobile Development
- Improved Android/iOS workflows
- Mobile-specific templates
-
Cloud Development
- Remote build capabilities
- Container-based builds
- Package registry integration
-
Package Manager Enhancements
- Complete Conan 2.0 support
- Lock file management
- Recipe generation
We welcome contributions to help achieve these goals! If you're interested in working on a specific feature or have suggestions, please open an issue or submit a pull request.
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.