# 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:
```toml
# /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:
```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
```bash
# 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`:
```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:
```toml
[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:
```toml
[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:
```toml
[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**:
```toml
[[workspace.dependencies]]
name = "fmt"
version = "10.0.0"
```
**Member**:
```toml
[[dependencies]]
name = "fmt"
workspace = true # Inherits version 10.0.0
```
### Feature Extension
Members can add additional features:
**Workspace Root**:
```toml
[[workspace.dependencies]]
name = "spdlog"
version = "1.12.0"
features = ["console"]
```
**Member**:
```toml
[[dependencies]]
name = "spdlog"
workspace = true
features = ["async"] # Final features: ["console", "async"]
```
### Override default_features
Members can control default features:
**Workspace Root**:
```toml
[[workspace.dependencies]]
name = "boost"
version = "1.80.0"
default_features = true
```
**Member**:
```toml
[[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:
```toml
[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:
```toml
# 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**:
```bash
# 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**:
```bash
ccgo build --workspace
```
**Build specific member**:
```bash
ccgo build --package core
ccgo build -p utils
```
**Build multiple members**:
```bash
ccgo build --package core --package utils
```
**Build in dependency order**:
```bash
ccgo build --workspace --ordered
```
**Build default members only**:
```bash
# Uses workspace.default_members if specified
ccgo build
```
### List Commands
**List all workspace members**:
```bash
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**:
```bash
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**:
```bash
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`):
```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`):
```toml
[package]
name = "mylib-core"
version = "1.0.0"
[[dependencies]]
name = "fmt"
workspace = true
```
**Utils Package** (`mylib/utils/CCGO.toml`):
```toml
[package]
name = "mylib-utils"
version = "1.0.0"
[[dependencies]]
name = "fmt"
workspace = true
[[dependencies]]
name = "mylib-core"
path = "../core"
```
**Build**:
```bash
cd mylib
ccgo build --workspace --ordered
# Builds: core first, then utils
```
### 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**:
```toml
[workspace]
members = [
"core",
"libs/*", # Discovers: utils, helpers, common
"examples/*" # Discovers: basic, advanced
]
exclude = []
# Total members: 6
```
### Example 3: Feature Extensions
**Workspace Root**:
```toml
[workspace]
members = ["server", "client", "shared"]
[[workspace.dependencies]]
name = "spdlog"
version = "1.12.0"
features = ["console"] # Base feature
```
**Server** (`server/CCGO.toml`):
```toml
[package]
name = "server"
[[dependencies]]
name = "spdlog"
workspace = true
features = ["async", "multithreaded"]
# Final features: ["console", "async", "multithreaded"]
```
**Client** (`client/CCGO.toml`):
```toml
[package]
name = "client"
[[dependencies]]
name = "spdlog"
workspace = true
# Only uses workspace features: ["console"]
```
### Example 4: Default Members
**Workspace Root**:
```toml
[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**:
```bash
# 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:
```toml
[workspace]
resolver = "2" # Use resolver v2 (recommended)
members = ["core", "utils"]
```
**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:
```toml
# 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**:
```
Error: Duplicate workspace member name 'utils' at libs/utils
```
**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:
```toml
[[workspace.dependencies]]
name = "fmt"
version = "10.0.0"
```
### Circular Dependencies
**Error**:
```
Error: Circular dependency detected involving 'core'
```
**Solution**: Review inter-member dependencies and break the cycle:
```
core → utils → core ❌
Solution:
core → utils ✅
(Remove utils dependency on core)
```
### Member Not Found
**Error**:
```
Error: Workspace member not found: libs/utils
```
**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**:
```bash
# List discovered members
ccgo workspace list
# Check paths manually
ls -la libs/*/CCGO.toml
```
**Common Issues**:
- Forgot `*` or `**` in pattern
- Path is in exclude list
- Member missing CCGO.toml
## Best Practices
### DO
✅ **Use workspace dependencies** for shared libraries:
```toml
# Workspace root
[[workspace.dependencies]]
name = "fmt"
version = "10.0.0"
```
✅ **Use glob patterns** for consistent directory structures:
```toml
members = ["libs/*", "examples/*"]
```
✅ **Define default_members** for common builds:
```toml
default_members = ["core", "app"] # Skip examples/tests
```
✅ **Use semantic versioning** for workspace members:
```toml
[package]
name = "core"
version = "1.2.3" # Proper semver
```
✅ **Build in dependency order** for inter-dependent members:
```bash
ccgo build --workspace --ordered
```
### DON'T
❌ **Don't nest workspaces**:
```toml
# Not supported - use single workspace
```
❌ **Don't duplicate workspace dependencies in members**:
```toml
# Bad
[[dependencies]]
name = "fmt"
version = "10.0.0" # Should use workspace = true
# Good
[[dependencies]]
name = "fmt"
workspace = true
```
❌ **Don't use inconsistent versions**:
```toml
# 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**:
```toml
# Bad: core → utils → core
# Good: core → utils (one direction)
```
## Implementation Details
### Member Discovery Algorithm
1. Read workspace.members patterns
2. Expand glob patterns to concrete paths
3. Filter out workspace.exclude patterns
4. For each path:
- Check if directory exists
- Check for CCGO.toml presence
- Load and validate configuration
5. Check for duplicate names
6. Return discovered members
### Dependency Resolution
1. 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
2. Return resolved dependencies
### Build Order Calculation
Uses topological sort (depth-first search):
1. Create dependency graph of workspace members
2. Detect cycles (circular dependencies)
3. Perform DFS to order members
4. Return build order (dependencies before dependents)
**Time Complexity**: O(V + E) where V = members, E = dependencies
## See Also
- [Dependency Management](features/dependency-management.md) - Overall dependency system
- [Version Conflict Resolution](version-conflict-resolution.md) - Handle version conflicts
- [Project Structure](getting-started/project-structure.md) - 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.*