c3pg (C++ Playground)
c3pg (C Plus Plus PlayGround) is a command-line tool designed to simplify the process of creating,
managing, and running C++ projects. Inspired by Rust's cargo, it aims to make setting up
C++ projects as easy and efficient as possible, even when working with external dependencies.
While C++ development often involves managing complex build systems like CMake and dependency
managers like Conan, c3pg abstracts these details, allowing you to focus on writing and testing
code. The complexity still exists, but it stays under the hood.
Features
- Quick Project Setup: Initialize a new C++ project with a single command, or use
c3pg scratchfor a throwaway scratchpad in/tmp/. - Convention over Configuration: Simple projects need only a project name -- no build targets to declare.
- Unified Configuration: Use
c3pg.tomlfor all project configuration, similar toCargo.tomlin Rust. - Dependency Management: Easily add and remove Conan dependencies with a Cargo-like
[dependencies]table. - Build and Run: Compile and execute your projects with minimal effort.
- Testing: Scaffold and run GTest-based tests with auto-detection.
- Multi-target Support: Declare
[[lib]]and[[bin]]targets explicitly when needed. - Code Quality: Format and lint C++ sources with
clang-formatandclang-tidy. - Sanitizers: Enable AddressSanitizer, ThreadSanitizer, or UndefinedBehaviorSanitizer with a single flag.
- Customizable C++ Standards: Specify the C++ standard for your projects (default: C++20).
- Git Integration: Optionally initialize a Git repository for version control.
Installation
c3pg requires the following tools to be installed on your system:
- CMake (3.21+)
- Conan (2.x)
- A C++ compiler (GCC, Clang, or MSVC)
Install these tools via your package manager or their respective websites.
To build and install c3pg you need the Rust toolchain (see e.g.
rustup.rs).
To pull the latest release from crates.io use
or to build it locally from this git repo, clone it and run
This will install the c3pg binary locally (by default in $HOME/.cargo/bin).
Quick Start
# Create a new project
# ...or spin up a throwaway scratchpad
# Add a dependency, build, and run
# edit src/main.cpp to use fmt ...
# Add and run tests
# edit tests/test_math.cpp ...
Usage
Commands
new
Create a new C++ project.
Options:
--no-git: Do not initialize a Git repository.--standard: Set the C++ standard (default: C++20).--print-path: Print only the directory path, for use in shell compositions.
Examples:
# Create and jump straight in
scratch
Create a throwaway project in a temporary directory. Useful for quick C++ experiments.
Options:
--standard: Set the C++ standard (default: C++20).--print-path: Print only the directory path, for use in shell compositions.
Examples:
# Create a scratchpad and see the path
# Jump straight into a scratchpad
init
Initialize a c3pg project in the current directory.
Options:
--no-git: Do not initialize a Git repository.--standard: Set the C++ standard (default: C++20).
If src/ already contains source files, they are left untouched. Otherwise a
starter main.cpp is created.
add
Add a dependency to the current project.
Example:
c3pg looks for the latest version in the default Conan remote. Optionally, you can
specify a version and/or a user/channel:
remove
Remove a dependency from the current project.
build
Build the current project.
Options:
--release, -r: Build in release mode (default: debug).--asan: Enable AddressSanitizer.--tsan: Enable ThreadSanitizer.--ubsan: Enable UndefinedBehaviorSanitizer.
run
Run the current project (builds first if necessary).
Options:
--release, -r: Build in release mode (default: debug).--target <name>: Which executable to run (required when multiple exist).--asan,--tsan,--ubsan: Enable sanitizers.
test
Manage and run the project's test suite. GTest is added automatically the first time a test is created.
Subcommands:
add <name>: Scaffold a new GTest source file (tests/test_<name>.cpp). On first use, this also addsgtestas a dependency.
Options (when running tests):
--filter, -f: Expression to match test cases to run.--jobs, -j: Number of parallel test jobs.--asan,--tsan,--ubsan: Enable sanitizers.
Examples:
# Create a test (lazily adds gtest on first use)
# Run all tests
# Run only tests matching "math" with 4 jobs
fmt
Format C/C++ source files with clang-format.
Options:
--check: Check formatting without modifying files (exit with error if unformatted).
lint
Lint C/C++ source files with clang-tidy (requires a prior c3pg build for
compile_commands.json).
Options:
--fix: Apply suggested fixes in-place.
clean
Remove all build artifacts.
How It Works
Project Structure
When you create a new project, c3pg generates the following:
my_project/
c3pg.toml # Project configuration
src/
main.cpp # "Hello World" starter
build/
CMakeLists.txt # Generated CMake configuration
conanfile.py # Generated Conan recipe
.gitignore # (if Git is initialized)
Tests are added on demand via c3pg test add:
my_project/
tests/
test_math.cpp # Scaffolded GTest file
Configuration
c3pg.toml
The configuration follows a convention-over-configuration approach. A fresh project needs only a project name:
[]
= "my_project"
= "Cpp20"
All sources in src/ are compiled into a single executable named after the project.
This is the default when no [[lib]]/[[bin]] sections are present.
Dependencies
Dependencies are declared in a [dependencies] table, similar to Cargo.toml. A
simple dependency only needs a version string. For packages from a private Conan
remote you can specify user and channel using inline-table syntax:
[]
= "my_project"
= "Cpp20"
[]
= "11.0.0"
= "1.88"
= { = "2.1.0", = "team", = "stable" }
Multi-target project (library + executables)
When you need library targets or multiple executables, add [[lib]] and [[bin]]
sections (similar to Cargo's [[bin]] / [lib]):
[]
= "my_project"
[]
= "11.0.0"
[[]]
= "mylib"
= ["src/lib"]
= ["include"]
[[]]
= "my_project"
= ["src/main.cpp"]
= ["mylib"]
Optional sections
These sections can be added to override defaults:
[]
= false # default: true
[]
= "/usr/local/bin/conan" # default: "conan"
= "my_remote" # default: first configured remote
[]
= "test" # default: "tests"
Sections
[project]: Project name, C++ standard, and build cache directory.[dependencies](optional): Conan packages with version strings or detailed inline tables ({ version, user, channel }).[[lib]](optional): Library targets with sources, public include dirs, and inter-library linking.[[bin]](optional): Executable targets with sources and library linking. Omit both[[lib]]and[[bin]]for convention-based single-executable projects.[cmake](optional): CMake-specific settings.[conan](optional): Conan binary path and remote override.[testing](optional): Test source directory.
Development
Running tests
# Unit + integration tests (no external tools needed)
# End-to-end tests (requires cmake, conan, and a C++ compiler)
C3PG_E2E=1
Linting