Dependency Management
Porters provides flexible dependency management for C/C++ projects with support for multiple sources and isolation strategies.
Adding Dependencies
Basic Usage
Add a dependency from a Git repository:
porters add fmt --git https://github.com/fmtlib/fmt
This adds fmt to your porters.toml:
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt" }
Adding Dev Dependencies
Development-only dependencies (tests, benchmarks):
porters add catch2 --git https://github.com/catchorg/Catch2 --dev
Adding Optional Dependencies
Optional features:
porters add zlib --git https://github.com/madler/zlib --optional
Global vs Local Dependencies
Porters supports two dependency scopes:
Local Dependencies (Default)
Dependencies added with porters add are installed to the project's ports/ folder:
porters add fmt --git https://github.com/fmtlib/fmt
Location: ./ports/fmt/
Characteristics:
- Isolated per-project
- Version-locked via
porters.lock - Perfect for project-specific needs
Global Dependencies
Install packages globally to ~/.porters/packages/:
porters install fmt --git https://github.com/fmtlib/fmt
Location (Linux/macOS): ~/.porters/packages/fmt/
Location (Windows): C:\Users\<username>\.porters\packages\fmt\
Characteristics:
- Shared across all projects
- Faster setup for frequently-used libraries
- Centralized cache
Git Dependencies
Porters supports both HTTPS and SSH Git URLs:
HTTPS URLs
porters add fmt --git https://github.com/fmtlib/fmt
SSH URLs
porters add fmt --git git@github.com:fmtlib/fmt.git
Specific Branch
porters add fmt --git https://github.com/fmtlib/fmt --branch stable
Specific Tag
porters add fmt --git https://github.com/fmtlib/fmt --tag 10.1.1
In porters.toml:
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
Syncing Dependencies
The sync command ensures all dependencies from porters.toml are installed:
porters sync
This will:
- Read dependencies from
porters.toml - Download missing packages to
ports/ - Resolve version constraints
- Update
porters.lock
Include Dev Dependencies
porters sync --dev
Syncs both regular and dev dependencies.
Include Optional Dependencies
porters sync --optional
Syncs both regular and optional dependencies.
Include Everything
porters sync --dev --optional
Lock File
The porters.lock file tracks resolved dependency versions.
Generating/Updating Lock File
porters lock
This updates porters.lock with current installed dependencies.
Lock File Format
version = "1"
updated_at = "2024-01-15T10:30:00Z"
[dependencies.fmt]
name = "fmt"
version = "10.1.1"
source = { Git = { url = "https://github.com/fmtlib/fmt", rev = "a1b2c3d" } }
checksum = "sha256:..."
dependencies = []
Why Use Lock Files?
- Reproducibility: Same versions across all environments
- Team Collaboration: Everyone gets identical dependencies
- CI/CD: Reliable builds in pipelines
Dependency Sources
Porters supports multiple dependency sources:
Git Repository
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt" }
spdlog = { git = "git@github.com:gabime/spdlog.git", branch = "v1.x" }
Local Path
[dependencies]
mylib = { path = "../mylib" }
Registry (Future)
Support for package registries is planned:
[dependencies]
boost = { registry = "conan", version = "1.80" }
Dependency Resolution
Porters resolves dependencies in this order:
- Check
porters.lockfor existing resolution - Fetch from Git/path source
- Verify constraints (version, branch, tag)
- Clone to
ports/directory - Update
porters.lock
Constraint Validation
Porters validates:
- Version requirements
- Branch/tag specifications
- Dependency conflicts
Best Practices
Version Pinning
Always specify versions or tags for production:
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
Lock File in Version Control
Commit porters.lock to ensure reproducible builds:
git add porters.lock
git commit -m "Update dependencies"
Separate Dev Dependencies
Keep development tools separate:
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt" }
[dev-dependencies]
catch2 = { git = "https://github.com/catchorg/Catch2" }
benchmark = { git = "https://github.com/google/benchmark" }
Use Global Install for Common Libraries
Install frequently-used libraries globally:
porters install boost --git https://github.com/boostorg/boost
porters install gtest --git https://github.com/google/googletest
Then reference them in projects without re-downloading.
Troubleshooting
Dependency Not Found
Ensure the Git URL is correct and accessible:
git clone https://github.com/fmtlib/fmt # Test manually
Version Conflicts
Check porters.lock and resolve conflicts:
porters lock # Regenerate lock file
Sync Failures
Clear the cache and retry:
rm -rf ports/
porters sync
Next Steps
- Explore Build Configuration
- Review Command Reference
- Check Troubleshooting