Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. Read dependencies from porters.toml
  2. Download missing packages to ports/
  3. Resolve version constraints
  4. 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:

  1. Check porters.lock for existing resolution
  2. Fetch from Git/path source
  3. Verify constraints (version, branch, tag)
  4. Clone to ports/ directory
  5. 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