This presentation, delivered by Kerstin Keller at Meeting C++ 2025, addresses the unique and pervasive difficulties associated with managing third-party dependencies within C++ projects. The core argument posits that, unlike modern languages with standardized package ecosystems (e.g., Python's pip, Node.js's npm), C++ suffers from a lack of standardization in Application Binary Interface (ABI) stability, build systems, and package description formats, resulting in extremely high management costs and poor build reproducibility. The talk contrasts manual methods (system installs, vendoring) with dedicated package managers like Conan and VC package. It details how dependency managers utilize semantic versioning and lock files to achieve consistent version resolution and highlights Conan’s methodology for determining binary compatibility via computed Package IDs. Finally, the discussion advocates strongly for the adoption and development of the Common Package Specification (CPS) as a critical step toward future toolchain-agnostic dependency infrastructure in C++.
Summarization by a Senior Software Architect (C++ Toolchains)
0:57 C++ Dependency Cost: Integrating third-party functionality in C++ incurs a high cost relative to other programming languages due to ecosystem constraints.
2:53 Personal Case Study: The speaker's motivation stems from inheriting a C++ driving stack repository totaling 40 gigabytes, containing scattered, pre-compiled dynamic-link libraries (DLLs) without traceable origins. This configuration severely complicated necessary toolchain migrations (e.g., Visual Studio 2012 to 2015), consuming half a year of engineering effort (4:51).
6:42 Definition of Dependency: A dependency is defined as an external software component with an independent release cycle required for correct compilation, runtime, or operation.
8:42 Dependency Management Objective: Management focuses on orchestrating an evolving network of dependencies and their changes over time, necessitating methods to convey the significance of updates.
9:29 Semantic Versioning (SemVer): SemVer provides a contract between library authors and users, using major (backwards incompatible), minor (backwards compatible additions), and patch (bug fix) increments. The user expectation is that updates within the same major version require no code changes (11:19). SemVer does not imply ABI stability.
13:50 Reproducibility Requirement: A build is reproducible only if a consistent build environment (including specific dependency versions) can be recreated identically over time.
15:46 Current C++ Practices: Survey data indicates C++ projects primarily handle dependencies via: (1) System installation (e.g., apt-get, Brew), which risks being stuck on old versions or lacking reproducibility; (2) Source-code based vendoring (e.g., Git submodules), which mandates the same build system and requires manual transitive dependency conflict resolution; or (3) Build-system level integration (e.g., CMake FetchContent).
24:19 Scaling Constraint: Pinning exact versions (common in vendoring approaches) does not scale in deep dependency graphs, as crucial security fixes require cascading re-releases of all intermediate packages.
26:18 Package Manager Solution: Dependency managers automate version resolution and provisioning. They use lock files to capture the exact, resolved dependency graph versions, ensuring reproducibility on subsequent installs (26:53). Updates are managed intentionally (e.g., audit fix or full update command).
29:17 C++ Unique Challenges: C++ package management is complex due to: (1) Lack of a standard build system, requiring package managers to abstract the build process; (2) Non-trivial binary compatibility determination, as compatibility depends on numerous factors (compiler, platform, architecture, options, and transitive dependencies); and (3) Absence of a standard C++ package artifact definition.
34:36 Conan's Binary Strategy: Conan addresses compatibility by generating a unique Package ID hash based on a comprehensive set of settings (compiler, OS, architecture), options (static/shared), and dependencies defined in a user profile. Identical Package IDs allow reuse of pre-built binaries, saving significant build time (34:53).
36:44 Common Package Specification (CPS): CPS is an emerging mechanism intended to declaratively describe package artifacts (headers, linkage requirements, transitive dependencies) independent of specific tooling (37:09). CMake and Conan are implementing experimental support for CPS (38:16).
39:13 Binary Availability Issue: The combinatorial explosion of settings means no single package registry (like Conan Center Index) can offer pre-built binaries for all possible C++ compatibility combinations, creating a friction point for users who often must rebuild dependencies from source.
47:21 Conan vs. VC package: The speaker’s choice of Conan was driven by the organizational priority for binary dependency management to minimize build times, a feature less central to VC package.
54:16 Internal Package Management: Organizations with complex needs often create internal recipes, mirroring source repositories, and simplifying Conan Center Index recipes to cater only to specific in-house build options, mitigating the combinatorial explosion problem.
58:43 IDE Integration: A coexistence strategy is employed where the package manager CLI (conan install) handles package provisioning, generating necessary toolchain files, allowing developers to then use familiar IDEs (like Visual Studio) for development.