Workspace Dependencies¶
Overview¶
CCGO provides workspace support for managing multiple related C++ packages in a monorepo structure. Workspaces enable:
- đĸ Monorepo Management - Organize multiple packages in a single repository
- đ Shared Dependencies - Define dependencies once, use across all members
- đ Dependency Inheritance - Members inherit workspace dependencies
- đĻ Coordinated Builds - Build multiple packages in dependency order
- đ¯ Selective Builds - Build specific members or all at once
Benefits¶
- Simplified Dependency Management - Define shared dependencies in one place
- Consistent Versions - All members use the same versions of shared dependencies
- Faster Development - No need to publish internal dependencies
- Flexible Configuration - Members can override or extend workspace dependencies
- Build Optimization - Smart build ordering based on inter-member dependencies
Quick Start¶
1. Create Workspace Root¶
Create a workspace with multiple packages:
# /workspace/CCGO.toml
[workspace]
members = ["core", "utils", "examples/*"]
exclude = ["examples/experimental"]
# Shared dependencies for all workspace members
[[workspace.dependencies]]
name = "fmt"
version = "10.0.0"
[[workspace.dependencies]]
name = "spdlog"
version = "1.12.0"
2. Create Workspace Members¶
Each member has its own CCGO.toml:
# /workspace/core/CCGO.toml
[package]
name = "core"
version = "1.0.0"
# Inherit workspace dependency
[[dependencies]]
name = "fmt"
workspace = true
# Add additional features
[[dependencies]]
name = "spdlog"
workspace = true
features = ["async"]
# Member-specific dependency
[[dependencies]]
name = "boost"
version = "1.80.0"
3. Build Workspace¶
# Build all workspace members
ccgo build --workspace
# Build specific member
ccgo build --package core
# Build in dependency order
ccgo build --workspace --ordered
Workspace Configuration¶
Workspace Section¶
Define the workspace in the root CCGO.toml:
[workspace]
# Required: List of member packages (supports glob patterns)
members = [
"core", # Direct path
"libs/*", # All directories in libs/
"examples/**" # Recursive glob
]
# Optional: Exclude specific paths
exclude = [
"examples/test",
"old/*"
]
# Optional: Default members to build when no package specified
default_members = ["core", "utils"]
# Optional: Workspace-level resolver version (default: "2")
resolver = "2"
# Workspace-level dependencies
[[workspace.dependencies]]
name = "fmt"
version = "10.0.0"
Member Configuration¶
Each workspace member is a regular CCGO package with optional workspace inheritance:
[package]
name = "my-package"
version = "1.0.0"
# Inherit workspace dependency
[[dependencies]]
name = "fmt"
workspace = true
# Inherit and extend with features
[[dependencies]]
name = "spdlog"
workspace = true
features = ["async", "custom-formatter"]
# Inherit and override default_features
[[dependencies]]
name = "boost"
workspace = true
default_features = false
features = ["filesystem"]
# Member-specific dependency (not from workspace)
[[dependencies]]
name = "rapidjson"
version = "1.1.0"
Workspace Member Discovery¶
Glob Patterns¶
CCGO supports glob patterns for discovering workspace members:
[workspace]
members = [
"core", # Exact path
"libs/*", # All immediate children
"examples/**", # Recursive (all descendants)
"tests/integration_*" # Pattern matching
]
Pattern Syntax:
- * - Matches any characters except path separator
- ** - Matches any characters including path separators (recursive)
- ? - Matches any single character
- [abc] - Matches any character in brackets
Example Structure:
workspace/
âââ CCGO.toml (workspace root)
âââ core/
â âââ CCGO.toml
âââ libs/
â âââ utils/
â â âââ CCGO.toml
â âââ helpers/
â âââ CCGO.toml
âââ examples/
âââ basic/
â âââ CCGO.toml
âââ advanced/
âââ CCGO.toml
With members = ["core", "libs/*", "examples/*"], all 5 packages are discovered.
Exclude Patterns¶
Exclude specific paths from workspace:
[workspace]
members = ["libs/*", "examples/*"]
exclude = [
"examples/experimental", # Exclude specific directory
"libs/old" # Exclude outdated code
]
Dependency Inheritance¶
Basic Inheritance¶
Members use workspace = true to inherit dependencies:
Workspace Root:
Member:
Feature Extension¶
Members can add additional features:
Workspace Root:
Member:
[[dependencies]]
name = "spdlog"
workspace = true
features = ["async"] # Final features: ["console", "async"]
Override default_features¶
Members can control default features:
Workspace Root:
Member:
[[dependencies]]
name = "boost"
workspace = true
default_features = false # Override to disable defaults
features = ["filesystem"] # Only enable specific features
Mixed Dependencies¶
Members can have both workspace and member-specific dependencies:
[package]
name = "my-package"
# From workspace
[[dependencies]]
name = "fmt"
workspace = true
# Member-specific
[[dependencies]]
name = "rapidjson"
version = "1.1.0"
# From workspace with extensions
[[dependencies]]
name = "spdlog"
workspace = true
features = ["custom"]
Build Order and Dependencies¶
Inter-Member Dependencies¶
Workspace members can depend on each other:
# core/CCGO.toml
[package]
name = "core"
# utils/CCGO.toml
[package]
name = "utils"
[[dependencies]]
name = "core"
path = "../core" # Depend on sibling package
Topological Build Order¶
CCGO automatically determines build order based on dependencies:
workspace/
âââ core/ (no dependencies)
âââ utils/ (depends on core)
âââ app/ (depends on utils)
Build order: core â utils â app
Usage:
# Build in dependency order
ccgo build --workspace --ordered
# Build fails if circular dependencies detected
Circular Dependency Detection¶
CCGO detects and prevents circular dependencies:
core â utils â helpers â core â CIRCULAR!
Error: Circular dependency detected involving 'core'
Commands¶
Build Commands¶
Build all workspace members:
Build specific member:
Build multiple members:
Build in dependency order:
Build default members only:
List Commands¶
List all workspace members:
ccgo workspace list
# Output:
# Workspace: /path/to/workspace
# Members: 5
# - core (1.0.0)
# - utils (1.0.0)
# - helpers (1.0.0)
# - example-basic (0.1.0)
# - example-advanced (0.1.0)
List member dependencies:
ccgo workspace deps core
# Output:
# Dependencies for core:
# fmt 10.0.0 (from workspace)
# spdlog 1.12.0 (from workspace)
# boost 1.80.0 (member-specific)
Check Commands¶
Check workspace consistency:
ccgo workspace check
# Validates:
# - All members have valid CCGO.toml
# - No duplicate member names
# - Workspace dependencies exist
# - No circular dependencies
Examples¶
Example 1: Simple Library Workspace¶
Structure:
mylib/
âââ CCGO.toml
âââ core/
â âââ CCGO.toml
â âââ include/
â âââ src/
âââ utils/
âââ CCGO.toml
âââ include/
âââ src/
Workspace Root (mylib/CCGO.toml):
[workspace]
members = ["core", "utils"]
[[workspace.dependencies]]
name = "fmt"
version = "10.0.0"
[[workspace.dependencies]]
name = "gtest"
version = "1.14.0"
Core Package (mylib/core/CCGO.toml):
Utils Package (mylib/utils/CCGO.toml):
[package]
name = "mylib-utils"
version = "1.0.0"
[[dependencies]]
name = "fmt"
workspace = true
[[dependencies]]
name = "mylib-core"
path = "../core"
Build:
Example 2: Glob Pattern Discovery¶
Structure:
project/
âââ CCGO.toml
âââ core/
â âââ CCGO.toml
âââ libs/
â âââ utils/
â â âââ CCGO.toml
â âââ helpers/
â â âââ CCGO.toml
â âââ common/
â âââ CCGO.toml
âââ examples/
âââ basic/
â âââ CCGO.toml
âââ advanced/
âââ CCGO.toml
Workspace Root:
[workspace]
members = [
"core",
"libs/*", # Discovers: utils, helpers, common
"examples/*" # Discovers: basic, advanced
]
exclude = []
# Total members: 6
Example 3: Feature Extensions¶
Workspace Root:
[workspace]
members = ["server", "client", "shared"]
[[workspace.dependencies]]
name = "spdlog"
version = "1.12.0"
features = ["console"] # Base feature
Server (server/CCGO.toml):
[package]
name = "server"
[[dependencies]]
name = "spdlog"
workspace = true
features = ["async", "multithreaded"]
# Final features: ["console", "async", "multithreaded"]
Client (client/CCGO.toml):
[package]
name = "client"
[[dependencies]]
name = "spdlog"
workspace = true
# Only uses workspace features: ["console"]
Example 4: Default Members¶
Workspace Root:
[workspace]
members = ["core", "utils", "examples/*"]
default_members = ["core", "utils"] # Don't build examples by default
[[workspace.dependencies]]
name = "fmt"
version = "10.0.0"
Build Behavior:
# Builds only core and utils (default members)
ccgo build
# Build all members including examples
ccgo build --workspace
# Build specific example
ccgo build --package example-advanced
Advanced Usage¶
Resolver Versions¶
Control dependency resolution behavior:
Resolver v1: - Legacy resolver - May have edge cases with feature unification
Resolver v2 (recommended): - Modern resolver - Better feature unification - Improved performance - Default for new projects
Virtual Workspaces¶
Create a workspace without a root package:
# Workspace root with no [package] section
[workspace]
members = ["package1", "package2"]
# This is a "virtual workspace" - only for organization
# No library/binary at workspace root
Nested Workspaces¶
Not Supported: Workspaces cannot be nested.
workspace/
âââ CCGO.toml (workspace)
âââ subproject/
âââ CCGO.toml (workspace) â Error!
Alternative: Use workspace members:
workspace/
âââ CCGO.toml (workspace)
âââ project1/
â âââ CCGO.toml (member)
âââ project2/
âââ CCGO.toml (member)
Troubleshooting¶
Duplicate Member Names¶
Error:
Solution: Ensure all workspace members have unique names in their [package] section.
Missing Workspace Dependency¶
Error:
Error: Member 'core' declares dependency 'fmt' with workspace=true,
but it's not defined in workspace dependencies
Solution: Add the dependency to workspace root:
Circular Dependencies¶
Error:
Solution: Review inter-member dependencies and break the cycle:
Member Not Found¶
Error:
Solution:
1. Verify the path exists
2. Ensure member has CCGO.toml
3. Check for typos in workspace.members
Glob Pattern Issues¶
Problem: Expected members not discovered
Debug:
Common Issues:
- Forgot * or ** in pattern
- Path is in exclude list
- Member missing CCGO.toml
Best Practices¶
DO¶
â Use workspace dependencies for shared libraries:
â Use glob patterns for consistent directory structures:
â Define default_members for common builds:
â Use semantic versioning for workspace members:
â Build in dependency order for inter-dependent members:
DON'T¶
â Don't nest workspaces:
â Don't duplicate workspace dependencies in members:
# Bad
[[dependencies]]
name = "fmt"
version = "10.0.0" # Should use workspace = true
# Good
[[dependencies]]
name = "fmt"
workspace = true
â Don't use inconsistent versions:
# Bad: Members use different versions
# member1: fmt 9.0.0
# member2: fmt 10.0.0
# Good: All use workspace dependency
â Don't create circular dependencies:
Implementation Details¶
Member Discovery Algorithm¶
- Read workspace.members patterns
- Expand glob patterns to concrete paths
- Filter out workspace.exclude patterns
- For each path:
- Check if directory exists
- Check for CCGO.toml presence
- Load and validate configuration
- Check for duplicate names
- Return discovered members
Dependency Resolution¶
- For each member dependency:
- If
workspace = true:- Find dependency in workspace.dependencies
- Inherit version, features, etc.
- Merge member-specific features
- Apply member default_features override
- Else:
- Use member's own dependency spec
- Return resolved dependencies
Build Order Calculation¶
Uses topological sort (depth-first search):
- Create dependency graph of workspace members
- Detect cycles (circular dependencies)
- Perform DFS to order members
- Return build order (dependencies before dependents)
Time Complexity: O(V + E) where V = members, E = dependencies
See Also¶
- Dependency Management - Overall dependency system
- Version Conflict Resolution - Handle version conflicts
- Project Structure - Project organization
Changelog¶
v3.0.12 (2026-01-21)¶
- â Workspace support for monorepo management
- â Glob pattern discovery for workspace members
- â
Dependency inheritance via
workspace = true - â Inter-member dependency resolution
- â Topological build ordering
- â Circular dependency detection
- â Feature extension and default_features override
Workspace dependencies enable efficient monorepo management with shared dependencies and coordinated builds.