4、包管理(vcpkg/conan):C++包管理方案对比、vcpkg安装与使用、conan基础配置、私有仓库搭建
聊到C++的包管理,很多人的第一反应是「头疼」。
说实话,我做了这么多年游戏开发,早期最痛苦的事情之一就是「配环境」。你想想看,项目里要用个json库、用个protobuf,手动下载、编译、配置include路径、链接lib文件……一套流程下来,半小时没了。而且换台机器,又得重来一遍。
后来我接触了vcpkg和conan,才算是真正解放了双手。今天咱们就好好聊聊这两个工具。
4.1 C++包管理方案对比
在进入具体工具之前,我先说说市面上常见的几种方案。
| 方案 | 特点 | 适用场景 |
|---|---|---|
| 手动管理(git submodule + 手动编译) | 完全可控,但极其繁琐 | 小项目、对依赖版本有极端要求 |
| vcpkg | 微软出品,Windows友好,集成CMake方便 | Windows为主、跨平台需求不强的项目 |
| Conan | 去中心化、支持多平台、多编译器 | 大型项目、需要私有仓库、多平台构建 |
| 系统包管理器(apt/brew) | 简单但版本老旧,不可控 | 快速原型、个人项目 |
我个人习惯是:团队项目用Conan,个人小项目或者Windows独占项目用vcpkg。为什么?往下看你就明白了。
4.2 vcpkg安装与使用
vcpkg最大的优点就是「开箱即用」。我记得第一次用的时候,从安装到跑起来,不到5分钟。
4.2.1 安装vcpkg
# 克隆仓库
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
# 编译vcpkg(Windows下执行bootstrap-vcpkg.bat)
./bootstrap-vcpkg.sh
# 设置环境变量(可选,但建议)
export VCPKG_ROOT=/path/to/vcpkg
export PATH=$VCPKG_ROOT:$PATH
嗯,这里要注意:vcpkg本身是C++写的,所以你的机器上得有C++编译器。Windows下需要安装VS的C++工作负载,Linux下需要g++或clang。
4.2.2 安装包
# 搜索包
vcpkg search fmt
# 安装包(默认x86)
vcpkg install fmt
# 安装64位版本
vcpkg install fmt:x64-windows
# 安装带静态链接的版本
vcpkg install fmt:x64-windows-static
我在项目中遇到过一个问题:默认安装的是动态库,但我们的游戏引擎要求静态链接。当时我查了半天,才发现加个 -static 后缀就行。这个坑我踩过,你们别踩了。
4.2.3 与CMake集成
vcpkg和CMake的集成堪称「无缝」。你只需要在CMakeLists.txt里加上一行:
# 在CMakeLists.txt中
find_package(fmt CONFIG REQUIRED)
target_link_libraries(my_project PRIVATE fmt::fmt)
然后编译时指定工具链文件:
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build build
CMAKE_TOOLCHAIN_FILE 写到 CMakePresets.json 里,这样团队成员就不用每次都手动指定了。
4.3 Conan基础配置
Conan和vcpkg最大的区别在于:Conan是去中心化的。你可以自己搭建私有仓库,也可以从公共仓库拉取。说白了,它更像Python的pip或者Node.js的npm。
4.3.1 安装Conan
# 用pip安装
pip install conan
# 验证安装
conan --version
Conan是用Python写的,所以安装起来特别简单。不过要注意:Conan 2.x和1.x的API有较大差异,我建议新项目直接用Conan 2.x。
4.3.2 配置Conan
# 查看当前配置
conan config list
# 设置默认编译器
conan profile detect
# 查看生成的profile
conan profile show
Conan的profile文件很重要。它定义了你的编译器、构建类型、架构等信息。我一般会为不同的平台创建不同的profile:
# 创建Windows MSVC profile
conan profile detect --name=msvc
# 创建Linux GCC profile
conan profile detect --name=gcc
4.3.3 使用Conan管理依赖
在项目根目录创建 conanfile.txt:
[requires]
fmt/10.1.1
spdlog/1.12.0
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
然后执行:
conan install . --output-folder=build --build=missing
这会生成CMake的配置文件。接着在CMakeLists.txt里引用:
# CMakeLists.txt
find_package(fmt CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
target_link_libraries(my_project PRIVATE fmt::fmt spdlog::spdlog)
build 目录下。如果你改了输出目录,记得在CMake里设置 CMAKE_PREFIX_PATH。
4.4 私有仓库搭建
说到私有仓库,这其实是大项目的刚需。你想想看,公司内部有一些自研的库,不想公开到公共仓库,怎么办?
Conan在这方面做得特别好。它支持多种私有仓库方案:
- Artifactory:JFrog出品,功能最全,但需要付费
- Nexus:Sonatype出品,免费版够用
- Conan Server:Conan自带的轻量级服务器
- 本地文件系统:最简单,适合小团队
我个人推荐小团队先用 Conan Server,简单快速。大团队直接上 Artifactory。
4.4.1 搭建Conan Server
# 安装conan-server
pip install conan-server
# 启动服务器(默认端口9300)
conan_server
然后配置客户端:
# 添加远程仓库
conan remote add my_private http://localhost:9300
# 上传包到私有仓库
conan upload fmt/10.1.1 -r=my_private
4.4.2 使用私有仓库
在 conanfile.txt 中指定远程仓库:
[requires]
my_private_lib/1.0.0
[remotes]
my_private http://192.168.1.100:9300
或者通过命令行指定:
conan install . --remote=my_private
company_name/library_name/version,避免混乱。
4.5 我的选择建议
最后,我总结一下我的个人经验:
- 如果你是Windows游戏开发,用vcpkg就够了。它和VS的集成度很高,省心。
- 如果你做跨平台游戏(比如PC+主机+移动端),Conan是更好的选择。它的profile机制可以让你轻松切换不同平台。
- 如果你需要私有仓库,直接上Conan。vcpkg的私有仓库支持比较弱。
我曾经在一个跨平台项目中,同时用了vcpkg和Conan。Windows端用vcpkg,其他平台用Conan。结果维护起来特别痛苦——两套依赖管理,两套构建脚本。后来我统一成Conan,世界清净了。
所以我的建议是:除非你100%确定只用Windows,否则直接上Conan。虽然初期配置稍微复杂一点,但长期来看,收益远大于成本。