cpmDocsintro
v0.2.1GitHub
Modern C/C++ Package Manager

cpm Documentation

cpm is a blazingly fast, isolated package manager for C and C++ projects. Think of it as uv or cargo for C++, featuring reproducible Nix-powered dependency isolation, global caching, and portable standalone production releases.

Instant Symlinking

Header-only libraries are cloned once to global cache and instantly symlinked into your project.

Isolated Nix Builds

Compiled packages build inside isolated hermetic nix-shells with zero host contamination.

Portable Bundles

cpm build --release outputs a self-contained dist/ folder ready for any server.

Installation

Get CPM running on any Linux system in seconds. The installer configures compiler toolchains, Nix build isolation, and registers the cpm binary globally.

1. Automatic One-Line Installer (Recommended)

Linux x86_64
curl -fsSL https://cpm.ranadolui.me/install.sh | sh

2. Building From Source

bash
# Clone the repository
git clone https://github.com/Rana718/cpm.git
cd cpm

# Build with CMake & Ninja
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)

# Install binary
sudo cp cpm /usr/local/bin/

3. Verify Installation

bash
cpm --version
Prerequisites
cpm runs on Linux (x86_64). Required build tools: git, curl, cmake, and g++ (auto-configured by install script).

Quick Start

Create your first project or run a standalone C++ script in 30 seconds:

Create a New C++ Project

bash
# Initialize a new project directory
cpm init myapp
cd myapp

# Add dependencies (e.g. nlohmann/json and fmtlib)
cpm add github:nlohmann/json
cpm add github:fmtlib/fmt

# Compile and run immediately!
cpm run

cpm init automatically generates:

  • cpm.toml — Manifest file declaring compiler, standards, and dependencies.
  • main.cpp — Starter source file ready to edit.
  • compile_commands.json — Full LSP auto-completion for VS Code, Neovim, CLion.

Run a Single C/C++ File (No Project Needed)

Quickly test algorithms or single files without creating a cpm.toml:

bash
cpm run test.cpp
cpm run hello.c

Manifest Specification (cpm.toml)

The cpm.toml file is the declarative manifest for your C/C++ project, similar to Cargo.toml or package.json.

cpm.toml
[project]
name = "myapp"
version = "0.2.1"
cpp_standard = "20"        # Options: 11, 14, 17, 20, 23, 26
compiler = "gcc-13"        # Optional: gcc, gcc-13, clang-17
entry = "main.cpp"
output = "myapp"
nix_config = "./shell.nix" # Optional: custom user nix-shell

[scripts]
start = "./myapp"
test = "cpm run tests/test_main.cpp"

[dependencies]
# 1. Header-only libraries (Fastest — cloned & symlinked instantly)
json = "github:nlohmann/json@v3.11.3"
fmt  = "github:fmtlib/fmt@10.2.1"
glm  = "github:g-truc/glm@1.0.1"

[system-dependencies]
# 2. Compiled libraries (Cloned source & built inside nix-shell)
hiredis    = "github:redis/hiredis@v1.2.0"
sdl3       = "github:libsdl-org/SDL@release-3.2.14"
uwebsockets = "github:uNetworking/uWebSockets@v20.67.0"

[libs]
# 3. System libraries (Pre-compiled nixpkgs binaries)
opengl = "libGL"
glew   = "glew"
vulkan = "vulkan-loader"

Manifest Field Reference

KeyTypeDefaultDescription
project.namestringrequiredName of the executable binary.
project.cpp_standardstring"20"C++ standard: 11, 14, 17, 20, 23, 26.
project.compilerstring"gcc"Compiler version (gcc, gcc-13, clang-17).
project.entrystring"main.cpp"Main source file path.
project.nix_configstringnullPath to custom user shell.nix.

Static Safety Checks

cpm check never runs your binary. It analyzes every project C/C++ translation unit with the compiler analyzer, Clang-Tidy when installed, cppcheck when installed, and project policy rules.

cpm.toml — optional checker configuration
[check]
# Omit this key to keep the built-in checks (true by default).
use_defaults = true

# Added to the built-in compiler flags.
flags = ["-Wconversion", "-Wsign-conversion", "-Wshadow"]

# Replaces the default Clang-Tidy check list when provided.
tidy_checks = ["clang-analyzer-*", "bugprone-*", "cert-*", "concurrency-*", "performance-*"]

# Replaces cppcheck's default categories when provided.
cppcheck_enable = ["warning", "performance", "portability", "style"]

# Report ignored return values for these calls.
unchecked_calls = ["pthread_create", "pthread_join", "pthread_detach"]

# Functions that must visibly acquire a lock.
lock_functions = ["find_item", "delete_item"]
Defaults and overrides
use_defaults is true when omitted. Custom compiler flags extend the defaults. Set it to false only when replacing the compiler flag set entirely. The tidy and cppcheck arrays replace their respective tool defaults.

Dependency Paradigms

C and C++ libraries vary widely in how they are compiled and packaged. CPM organizes dependencies into three distinct sections to give you total control over build times and portability.

[dependencies]

Header-Only

No source compilation required. CPM clones the repository, finds headers, and symlinks them into .cpm/include/.

⚡ Instant build time
[system-dependencies]

Compiled Source

Libraries requiring compilation (.a / .so). CPM executes CMake/Make/Meson inside hermetic Nix shells.

🔨 Auto-compiled in Nix
[libs]

Nix System Libs

OS-level hardware and graphics drivers (OpenGL, Vulkan, ALSA, X11). Pre-built binary packages fetched from cache.nixos.org.

🌐 Pre-built binaries

Directory Architecture

Local & Global Filesystem Structure
my-project/
├── cpm.toml                ← Project manifest
├── main.cpp                ← Entry point
├── .cpm/
│   ├── include/            ← Symlinked C/C++ header files (all libraries)
│   ├── lib/                ← Compiled static (.a) & shared (.so) libraries
│   ├── packages/           ← Local repository checkouts
│   └── compile_commands.json ← Editor LSP definitions
└── dist/                   ← Production release bundle (cpm build --release)

~/.cpm/cache/               ← Global package cache (shared across all projects)
├── nlohmann-json-v3.11.3/  ← Header-only package cache
├── redis-hiredis-v1.2.0/   ← System-dep source & build cache
└── nix-store/              ← Cached pre-compiled nixpkgs binaries

Command Line Interface (CLI)

Search or browse all available commands in the cpm CLI toolkit:

cpm init <name>
Create a new modern C/C++ project with starter files and compile_commands.json
cpm install (or cpm i)
Resolve and download all dependencies declared in cpm.toml
cpm add <pkg>
Add a library, e.g. cpm add github:nlohmann/json@v3.11.3
cpm remove <name>
Remove a dependency and clean local include symlinks
cpm update
Update dependencies to their latest compatible tags or commit HEAD
cpm list
List all active header-only, compiled, and system packages
cpm run
One-step: resolve deps + compile project + execute binary
cpm run file.cpp
Fast single-file runner without requiring a project manifest
cpm build
Compile current project into local debug binary
cpm build --release
Create standalone portable production bundle in dist/ with stripped libs
cpm check
Run whole-codebase static safety analysis without executing the binary
cpm start
Run the pre-compiled binary instantly without rebuilding
cpm setup
Install Nix build daemon and initialize multi-user environment
cpm --version
Display installed cpm version and environment details

Static Safety Analysis (cpm check)

cpm check runs an automated, multi-layer static analysis suite across your entire codebase at compile time — similar to the safety guarantees of modern systems languages, tailored for C and C++.

bash
cpm check
Zero-Execution Safety Guarantee
cpm check never executes your compiled binary. It compiles and analyzes all translation units in parallel, making it completely safe for headless CI runners and untrusted source code.

The 4-Layer Verification Engine

Layer 1 · Compiler Static Analysis

GCC -fanalyzer & Clang Analyzer

Deep symbolic path analysis catching null dereferences, uninitialized memory reads, memory leaks (-Wanalyzer-malloc-leak), double-frees, use-after-free, and open file descriptor leaks.

Layer 2 · Cppcheck Engine

Bug & Portability Detection

Static analysis detecting buffer overruns, out-of-bounds pointer arithmetic, integer truncation/overflow, invalid shifts, and portability defects across architectures.

Layer 3 · Clang-Tidy Verification

Lifetime, Concurrency & CERT

Enforces CERT C/C++ guidelines (cert-err33-c), validates object lifetime/ownership, flags ignored return values, and inspects thread concurrency patterns.

Layer 4 · Policy & Concurrency Rules

Custom Codebase Policies

Configurable rules verifying that critical function return values are checked (e.g. pthread_create) and ensuring that declared shared-state functions visibly acquire locks.

Configuring [check] in cpm.toml

Customize which rules and flags are applied during cpm check:

cpm.toml → [check]
[check]
# Set false to completely replace built-in compiler warning flags
use_defaults = true

# Additional compiler diagnostic flags
flags = ["-Wconversion", "-Wsign-conversion", "-Wshadow"]

# Specific Clang-Tidy check patterns (replaces defaults)
tidy_checks = [
  "clang-analyzer-*",
  "bugprone-*",
  "cert-*",
  "concurrency-*",
  "performance-*"
]

# Cppcheck categories to enable
cppcheck_enable = ["warning", "performance", "portability", "style"]

# Enforce that return values from these calls are never discarded
unchecked_calls = ["pthread_create", "pthread_join", "socket", "listen"]

# Shared-state functions that must visibly contain a lock acquisition
lock_functions = ["find_item", "delete_item", "update_cache"]

Bring Your Own Nix Shell (shell.nix)

CPM natively merges user-managed shell.nix configurations. You can declare specific compiler versions, development tools, and hooks while CPM auto-injects detected library dependencies without duplicate builds.

Example Custom shell.nix

shell.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  packages = with pkgs; [
    openssl
    postgresql
    valgrind
  ];

  shellHook = ''
    echo "⚡ CPM development environment ready"
  '';
}

Linking in cpm.toml

cpm.toml
[project]
name = "secure-server"
version = "0.1.0"
nix_config = "./shell.nix"

Production Packaging (dist/)

Deploying C++ applications to production servers without matching system dependencies can be difficult. CPM solves this with standalone self-contained release bundles.

bash
cpm build --release

This creates a portable dist/ directory:

dist/ contents
dist/
├── myapp        ← Optimized, stripped native binary
├── lib*.so      ← Bundled shared library dependencies
└── run.sh       ← Portable launcher configuring LD_LIBRARY_PATH
Zero Dependencies on Target Server
Simply copy dist/ to any Linux x86_64 host and execute ./dist/run.sh. It runs immediately without installing packages on the host machine.

Frequently Asked Questions