Migration from Conan to CCGO¶
Version: v3.0.10 | Updated: 2026-01-21
Overview¶
This guide helps you migrate C++ projects from Conan to CCGO. Both are C++ package managers, but CCGO provides a more integrated cross-platform build system optimized for mobile and embedded platforms.
Why Migrate to CCGO?¶
| Feature | Conan | CCGO |
|---|---|---|
| Cross-Platform Builds | Manual per-platform setup | Single command for 8+ platforms |
| Mobile Focus | Android/iOS require complex setup | First-class Android, iOS, OpenHarmony support |
| Configuration | conanfile.py/txt + CMake | Unified CCGO.toml |
| Publishing | Conan Center, custom servers | Maven, CocoaPods, SPM, OHPM, Conan |
| Docker Builds | Manual setup | Built-in universal cross-compilation |
| Dependency Locking | conan.lock | CCGO.lock |
| Gradual Migration | N/A | Can use Conan packages as CCGO deps |
Migration Effort¶
Typical small project: 1-2 hours Medium project with 10+ deps: 4-8 hours Large project with custom Conan recipes: 1-2 days
Quick Comparison¶
Conan vs CCGO Concepts¶
| Conan Concept | CCGO Equivalent | Notes |
|---|---|---|
conanfile.txt |
CCGO.toml |
TOML format for dependencies |
conanfile.py |
CCGO.toml + CMakeLists.txt |
Build logic moves to CMake |
conan install |
ccgo install |
Install dependencies |
conan create |
ccgo build |
Build package |
conan upload |
ccgo publish |
Publish to registry |
| Conan Center | CCGO Registry (planned) | Currently uses Git deps |
requires |
[dependencies] |
Dependency declarations |
tool_requires |
N/A | Use system tools or Docker |
| Profile | Platform flags | --arch, --toolchain, etc. |
| Generator | CMake integration | Direct CMake module |
| Package recipe | CCGO.toml + CMakeLists.txt | Simpler declarative format |
Migration Paths¶
Path 1: Simple Dependencies Only (conanfile.txt)¶
Best for: Projects that only consume packages, no custom recipes
Steps:
1. Convert conanfile.txt → CCGO.toml
2. Update CMakeLists.txt includes
3. Test builds
Time: 30 minutes - 2 hours
Path 2: Custom Package Recipe (conanfile.py)¶
Best for: Projects with custom Conan packages
Steps:
1. Extract dependency list → CCGO.toml [dependencies]
2. Convert build logic → CMakeLists.txt
3. Update publishing config → CCGO.toml [publish]
4. Test builds and publishing
Time: 2-8 hours
Path 3: Hybrid Approach (Gradual Migration)¶
Best for: Large projects, minimal disruption
Steps: 1. Keep Conan for most deps 2. Use CCGO for cross-platform builds 3. Gradually replace Conan deps with CCGO/Git deps 4. Remove Conan when ready
Time: Spread over weeks/months
Step-by-Step Migration¶
Step 1: Analyze Current Conan Setup¶
Identify Dependency Sources¶
# List all Conan dependencies
conan info . --only requires
# Check which deps are from Conan Center
conan search <package> --remote=conancenter
# Identify custom recipes (local or private server)
conan search --remote=all
Categorize dependencies: - Conan Center: May have Git alternatives - Custom recipes: Need to port or keep as Conan - System libraries: Can use system or build from source
Step 2: Create CCGO.toml¶
From conanfile.txt¶
Before (conanfile.txt):
[requires]
fmt/10.1.1
spdlog/1.12.0
boost/1.82.0
[generators]
cmake_find_package
cmake_paths
[options]
fmt:shared=False
boost:shared=False
After (CCGO.toml):
[package]
name = "myproject"
version = "1.0.0"
[dependencies]
# Option 1: Use Conan packages (hybrid mode)
fmt = { version = "10.1.1", source = "conan" }
spdlog = { version = "1.12.0", source = "conan" }
# Option 2: Use Git repositories
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
spdlog = { git = "https://github.com/gabime/spdlog", tag = "v1.12.0" }
# Option 3: Mix both
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
boost = { version = "1.82.0", source = "conan" } # Keep Conan for complex deps
[build]
cmake_version = "3.22.1"
Advantages of Git dependencies: - ✅ No Conan server needed - ✅ Lock exact commit/tag - ✅ Build from source with your exact flags - ❌ Slower first build (no binary cache)
From conanfile.py¶
Before (conanfile.py):
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout
class MyProjectConan(ConanFile):
name = "myproject"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False]}
default_options = {"shared": False}
exports_sources = "CMakeLists.txt", "src/*", "include/*"
def requirements(self):
self.requires("fmt/10.1.1")
if self.options.shared:
self.requires("spdlog/1.12.0")
def layout(self):
cmake_layout(self)
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
After (CCGO.toml):
[package]
name = "myproject"
version = "1.0.0"
description = "My C++ project"
license = "MIT"
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
[dependencies.spdlog]
git = "https://github.com/gabime/spdlog"
tag = "v1.12.0"
optional = true
[features]
default = []
with-logging = ["spdlog"] # Conditional dependency
[build]
cmake_version = "3.22.1"
link_type = "static" # or "shared"
[android]
min_sdk = 21
compile_sdk = 34
default_archs = ["armeabi-v7a", "arm64-v8a", "x86_64"]
[ios]
deployment_target = "13.0"
[publish.maven]
group_id = "com.example"
artifact_id = "myproject"
Note: Build logic (CMake configuration/build/install) moves to your CMakeLists.txt - see Step 3.
Step 3: Update CMake Integration¶
Conan CMake Integration¶
Before (with Conan):
cmake_minimum_required(VERSION 3.15)
project(MyProject)
# Conan integration (multiple approaches)
# Option 1: cmake-conan
include(${CMAKE_BINARY_DIR}/conan.cmake)
conan_cmake_configure(REQUIRES fmt/10.1.1
GENERATORS cmake_find_package)
conan_cmake_install(...)
# Option 2: CMakeDeps + CMakeToolchain generators
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp fmt::fmt spdlog::spdlog)
CCGO CMake Integration¶
After (with CCGO):
cmake_minimum_required(VERSION 3.18)
project(MyProject VERSION 1.0.0)
# CCGO integration
include(${CCGO_CMAKE_DIR}/CMakeUtils.cmake)
include(${CCGO_CMAKE_DIR}/CCGODependencies.cmake)
# Collect sources (CCGO helper)
add_sub_layer_sources_recursively(MYAPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src)
# Create library/executable
add_library(myproject STATIC ${MYAPP_SOURCES})
# Add all dependency include paths
ccgo_add_dependencies(myproject)
# Link specific dependencies (CCGO will find them in installed deps)
ccgo_link_dependency(myproject fmt fmt)
ccgo_link_dependency(myproject spdlog spdlog)
# Or use CMake's find_package if dependency provides it
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
target_link_libraries(myproject PRIVATE fmt::fmt spdlog::spdlog)
Key Differences:
- ${CCGO_CMAKE_DIR} is set by ccgo build system
- ccgo_add_dependencies() adds all dependency include paths
- ccgo_link_dependency() finds and links specific libraries
- Simpler, less boilerplate than Conan
Step 4: Install Dependencies¶
# Conan
conan install . --output-folder=build --build=missing
# CCGO
ccgo install
# Reads CCGO.toml, installs to .ccgo/deps/
# Generates CCGO.lock for version locking
CCGO Dependency Installation:
- Git deps: Cloned to .ccgo/deps/<name>
- Conan deps (hybrid mode): Uses conan install internally
- Lockfile: CCGO.lock ensures reproducible builds
Step 5: Update Build Commands¶
Platform Builds¶
Conan:
# Android (complex setup)
conan install . --profile=android-armv8 --build=missing
conan build .
# iOS (complex setup)
conan install . --profile=ios-armv8 --build=missing
conan build .
CCGO:
# Android
ccgo build android --arch arm64-v8a,armeabi-v7a,x86_64
# iOS
ccgo build ios
# macOS
ccgo build macos
# All platforms with Docker (any host OS!)
ccgo build android --docker
ccgo build ios --docker
ccgo build windows --docker
CCGO Advantages: - ✅ Single command per platform - ✅ Automatic toolchain setup - ✅ Docker-based universal cross-compilation - ✅ Parallel architecture builds
Step 6: Update Publishing¶
Publishing to Maven (Android)¶
Conan:
# Custom conanfile.py deploy() method
conan create . --profile=android-armv8
conan upload myproject/1.0.0 --remote=myremote
CCGO:
# Configure once in CCGO.toml
[publish.maven]
group_id = "com.example"
artifact_id = "myproject"
# Publish to Maven Central
ccgo publish android --registry official
# Publish to custom Maven
ccgo publish android --registry private --url https://maven.example.com
Publishing to CocoaPods (iOS)¶
Conan: Not directly supported, requires custom scripts
CCGO:
# Configure once in CCGO.toml
[publish.cocoapods]
summary = "My C++ library"
homepage = "https://github.com/user/myproject"
# Publish
ccgo publish apple --manager cocoapods
Common Migration Scenarios¶
Scenario 1: Header-Only Library (e.g., {fmt})¶
Conan conanfile.py:
class FmtConan(ConanFile):
name = "fmt"
version = "10.1.1"
# Header-only, no build()
def package(self):
self.copy("*.h", dst="include", src="include")
CCGO CCGO.toml:
[package]
name = "fmt-wrapper"
version = "10.1.1"
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
# CMakeLists.txt handles include path setup
CMakeLists.txt:
include(${CCGO_CMAKE_DIR}/CCGODependencies.cmake)
add_library(fmt INTERFACE)
ccgo_add_dependencies(fmt) # Adds fmt include paths
# Or use CMake's find_package
add_subdirectory(.ccgo/deps/fmt)
target_link_libraries(myapp PRIVATE fmt::fmt-header-only)
Scenario 2: Library with Build Options¶
Conan conanfile.py:
class MyLibConan(ConanFile):
options = {
"shared": [True, False],
"with_ssl": [True, False]
}
default_options = {
"shared": False,
"with_ssl": True
}
def requirements(self):
if self.options.with_ssl:
self.requires("openssl/3.1.0")
CCGO CCGO.toml:
[package]
name = "mylib"
[dependencies]
openssl = { git = "https://github.com/openssl/openssl", tag = "openssl-3.1.0", optional = true }
[features]
default = ["ssl"]
ssl = ["openssl"]
[build]
link_type = "static" # or "shared"
Build with/without SSL:
Scenario 3: Multi-Package Workspace¶
Conan (separate conanfile.py per package):
myworkspace/
├── core/conanfile.py # Depends on nothing
├── utils/conanfile.py # Depends on core
└── app/conanfile.py # Depends on utils
CCGO (single CCGO.toml at root):
[workspace]
members = ["core", "utils", "app"]
resolver = "2"
# Workspace-level dependency (inherited by all members)
[workspace.dependencies]
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
core/CCGO.toml:
[package]
name = "core"
version = "1.0.0"
[dependencies]
fmt = { workspace = true } # Inherit from workspace
utils/CCGO.toml:
[package]
name = "utils"
version = "1.0.0"
[dependencies]
core = { path = "../core" } # Local dependency
fmt = { workspace = true }
Scenario 4: Private Conan Server¶
Conan:
# Configure remote
conan remote add mycompany https://conan.example.com
conan remote login mycompany admin -p password
# Use packages
conan install . --remote=mycompany
CCGO Hybrid Mode (keep Conan for private deps):
[dependencies]
# Public packages: use Git
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
# Private packages: use Conan
internal-lib = { version = "2.3.0", source = "conan", remote = "mycompany" }
Or Migrate to Git (recommended):
[dependencies]
# Host private packages on Git (GitHub/GitLab/Bitbucket)
internal-lib = { git = "https://github.com/mycompany/internal-lib", tag = "v2.3.0" }
Dependency Mapping¶
Popular Conan Packages → CCGO Equivalents¶
| Conan Package | CCGO Recommended Approach |
|---|---|
fmt |
{ git = "https://github.com/fmtlib/fmt", tag = "10.1.1" } |
spdlog |
{ git = "https://github.com/gabime/spdlog", tag = "v1.12.0" } |
catch2 |
{ git = "https://github.com/catchorg/Catch2", tag = "v3.4.0" } |
gtest |
{ git = "https://github.com/google/googletest", tag = "v1.14.0" } |
nlohmann_json |
{ git = "https://github.com/nlohmann/json", tag = "v3.11.2" } |
boost |
Keep Conan or use system package (too complex for Git) |
openssl |
Keep Conan or use system package (security updates) |
protobuf |
{ git = "https://github.com/protocolbuffers/protobuf", tag = "v23.4" } |
grpc |
Keep Conan (complex build) or use system package |
sqlite3 |
{ git = "https://github.com/sqlite/sqlite", tag = "version-3.42.0" } |
Troubleshooting¶
Issue: Missing Conan Package in CCGO¶
Problem: Package available in Conan Center, but no Git repository
Solutions: 1. Hybrid Mode: Keep using Conan for that package
-
Find Git Source: Search GitHub/GitLab for upstream
-
Vendor the Code: Copy source into your project
Issue: Complex Build Recipe in conanfile.py¶
Problem: Custom build logic in build() method
Solution: Move logic to CMakeLists.txt
Conan conanfile.py:
def build(self):
cmake = CMake(self)
cmake.definitions["CUSTOM_OPTION"] = "ON"
cmake.definitions["BUILD_SHARED"] = self.options.shared
cmake.configure(source_folder="subfolder")
cmake.build(target="mylib")
CCGO CMakeLists.txt:
cmake_minimum_required(VERSION 3.18)
# Set options directly
option(CUSTOM_OPTION "Custom option" ON)
option(BUILD_SHARED_LIBS "Build shared" OFF)
# Configure subfolder
add_subdirectory(subfolder)
# Build target
add_library(mylib ...)
Issue: Conan Generators Not Available¶
Problem: cmake_find_package generator missing in CCGO
Solution: Use CCGO's CMake integration
Before:
After:
include(${CCGO_CMAKE_DIR}/CCGODependencies.cmake)
ccgo_add_dependencies(myapp)
ccgo_link_dependency(myapp fmt fmt)
Issue: Profile Configuration¶
Problem: Conan profiles specify compiler, settings
Conan ~/.conan/profiles/android-armv8:
[settings]
os=Android
os.api_level=21
arch=armv8
compiler=clang
compiler.version=14
compiler.libcxx=c++_shared
build_type=Release
CCGO: Platform settings in CCGO.toml, architecture in command
CCGO.toml:
Command:
Best Practices¶
1. Gradual Migration Strategy¶
✅ Do: Start hybrid (Conan + CCGO)
[dependencies]
# Simple deps: migrate to Git
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
# Complex deps: keep Conan temporarily
boost = { version = "1.82.0", source = "conan" }
✅ Do: Migrate package by package over sprints
2. Lock Dependencies¶
✅ Do: Commit CCGO.lock to version control
ccgo install # Generates CCGO.lock
git add CCGO.lock # Lock exact versions
git commit -m "Lock dependency versions"
3. Test Cross-Platform Builds Early¶
✅ Do: Verify all target platforms after migration
ccgo build android --arch arm64-v8a
ccgo build ios
ccgo build macos
ccgo build windows --docker # Test on macOS/Linux
4. Document Custom Patches¶
✅ Do: Document any Conan package patches in migration notes
[dependencies]
mypackage = { git = "https://github.com/user/mypackage-fork", branch = "custom-fixes" }
# Custom fork with Android NDK r25 fixes
5. Use Docker for Reproducibility¶
✅ Do: Use Docker builds for CI/CD
# .github/workflows/build.yml
- name: Build for all platforms
run: |
ccgo build android --docker --arch arm64-v8a,armeabi-v7a,x86_64
ccgo build ios --docker
ccgo build macos --docker
Migration Checklist¶
Use this checklist to track your migration progress:
Pre-Migration¶
- Audit all Conan dependencies
- Identify custom Conan recipes
- Check platform-specific build configs
- Document current build workflow
- Set up test environment
Migration¶
- Create
CCGO.tomlfromconanfile.txt/conanfile.py - Convert dependency declarations
- Update
CMakeLists.txtincludes - Test dependency installation (
ccgo install) - Verify builds on all platforms
- Test publishing workflow (if applicable)
- Update CI/CD pipelines
- Update developer documentation
Post-Migration¶
- Remove Conan files (
conanfile.*,conan.lock) - Remove Conan-related CI/CD steps
- Archive Conan configuration for reference
- Train team on CCGO workflow
- Monitor build performance
- Gather team feedback
Performance Comparison¶
Build Times (Example Project: 10 dependencies)¶
| Operation | Conan | CCGO | Notes |
|---|---|---|---|
| Install deps (first) | 5-10 min | 3-7 min | CCGO builds from source |
| Install deps (cached) | 30s | 10s | CCGO uses Git cache |
| Android build | 2 min | 90s | CCGO parallel archs |
| iOS build | 3 min | 2 min | CCGO optimized toolchain |
| Cross-platform (4 platforms) | 15 min | 6 min | CCGO Docker parallel |
Times vary by project size and hardware
Additional Resources¶
- Conan Official Docs
- CCGO CLI Reference
- CCGO.toml Configuration
- CMake Integration Guide
- CCGO Dependency Management
Community Support: - CCGO GitHub Discussions - CCGO Discord (coming soon)
FAQ¶
Q: Can I keep using Conan alongside CCGO?¶
A: Yes! CCGO supports hybrid mode:
[dependencies]
conan-package = { version = "1.0.0", source = "conan" }
git-package = { git = "https://github.com/user/package" }
Q: What about binary packages? Conan has prebuilt binaries.¶
A: CCGO currently builds from source for maximum flexibility. Benefits: - ✅ Exact compiler/flag control - ✅ No ABI compatibility issues - ✅ Security (build yourself) - ❌ Slower first build (mitigated by caching)
Future: Binary cache support planned for CCGO Registry.
Q: Can I publish to Conan Center from CCGO?¶
A: Not directly. To publish to Conan Center:
1. Keep a conanfile.py for publishing
2. Use CCGO for development builds
3. Export to Conan: conan create . --profile=...
Or migrate consumers to CCGO gradually.
Q: How do I handle Conan options in CCGO?¶
A: Use CCGO features:
Conan:
CCGO:
Q: What about tool_requires (build tools)?¶
A: CCGO uses system tools or Docker:
Conan:
CCGO:
# Install tools via system package manager
brew install cmake ninja # macOS
apt install cmake ninja-build # Ubuntu
# Or use Docker (tools included)
ccgo build --docker
Summary¶
Migrating from Conan to CCGO simplifies cross-platform C++ development:
Key Benefits:
1. ✅ Unified Configuration: Single CCGO.toml vs multiple files
2. ✅ Mobile-First: Android, iOS, OpenHarmony out-of-the-box
3. ✅ Simpler CMake: Less boilerplate, clearer dependencies
4. ✅ Docker Integration: Universal cross-compilation
5. ✅ Modern Publishing: Maven, CocoaPods, SPM support
Migration Effort: Typically 1-8 hours for most projects
Recommendation: Start with hybrid mode, migrate incrementally
Sources: - GitHub - conan-io/conan: Conan - The open-source C and C++ package manager - Conan 2 - C and C++ Package Manager Documentation - GitHub - conan-io/cmake-conan: CMake wrapper for conan C and C++ package manager
This guide is part of the CCGO documentation. For questions or improvements, open an issue on GitHub.