Abel'Blog

我干了什么?究竟拿了时间换了什么?

0%

vcpkg-c++包管理

概述

vcpkg 是一个 C++ 包管理器,用于 Windows、Linux 和 macOS。它由 Microsoft 维护,并支持大量的 C++ 库。使用 vcpkg,你可以轻松地安装、升级和管理 C++ 依赖库。

实践

安装 vcpkg

git clone https://github.com/microsoft/vcpkg

./bootstrap-vcpkg.sh
./vcpkg —version
vcpkg package management program version 2024-04-23-d6945642ee5c3076addd1a42c331bbf4cfc97457

See LICENSE.txt for license information.

vcpkg integrate bash
Adding vcpkg completion entry to /home/abel/.bashrc.

将目录增加到 PATH 里面方便运行。

尝试基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

vcpkg search boost

vcpkg
usage: vcpkg <command> [--switches] [--options=values] [arguments] @response_file
@response_file Contains one argument per line expanded at that location

Package Installation:
export Creates a standalone deployment of installed ports
install Installs a package
remove Uninstalls a package
x-set-installed Installs, upgrades, or removes packages such that that installed matches
exactly those supplied
upgrade Rebuilds all outdated packages

Package Discovery:
x-check-support Tests whether a port is supported without building it
depend-info Displays a list of dependencies for ports
list Lists installed libraries
owns Searches for the owner of a file in installed packages
x-package-info Display detailed information on packages
portsdiff Diffs changes in port versions between commits
search Searches for packages available to be built
update Lists packages that can be upgraded

Package Manipulation:
add Adds dependency to manifest
x-add-version Adds a version to the version database
create Creates a new port
edit Edits a port, optionally with $EDITOR, defaults to "code"
env Creates a clean shell environment for development or compiling
format-manifest Prettyfies vcpkg.json
hash Gets a file's SHA256 or SHA512
x-init-registry Creates a blank git registry
new Creates a new manifest
x-update-baseline Updates baselines of git registries in a manifest to those registries' HEAD
commit

Other:
ci Tries building all ports for CI testing
x-ci-verify-versions Checks integrity of the version database
contact Displays contact information to send feedback
fetch Fetches something from the system or the internet
integrate Integrates vcpkg with machines, projects, or shells

For More Help:
help topics Displays full list of help topics
help <topic> Displays specific help topic
help commands Displays full list of commands, including rare ones not listed here
help <command> Displays help detail for <command>

For more help (including examples) see https://learn.microsoft.com/vcpkg

build

1
2
3
4
# 设置好 VCPKG_ROOT 环境变量
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake
# 当找不到 cmake 文件的时候,可以直接去目录里面搜索一下 *.cmake ,就能解决问题了
${VCPKG_ROOT}/packages/boost-test_xxx/

不要去使用,因为没有用。

1
2
set(CMAKE_TOOLCHAIN_FILE "/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "Vcpkg toolchain file")

在使用 vcpkg 管理项目依赖时,vcpkg.json 是一个配置文件,专门用来定义项目所需的依赖库以及版本信息。通过这种方式,vcpkg 会自动解析并安装这些库,从而让项目构建更加方便和可重复。

vcpkg.json 的主要功能
• 定义项目所依赖的库及版本号。
• 自动管理依赖库的安装、更新和清理。
• 与 CMake 等构建工具无缝集成。

vcpkg.json 文件的基本结构

以下是一个示例的 vcpkg.json 配置文件:

{
“name”: “my-cool-project”,
“version”: “1.0.0”,
“description”: “A project using vcpkg to manage dependencies.”,
“dependencies”: [
{ “name”: “fmt”, “version>=”: “9.1.0” },
“boost”,
“openssl”
],
“builtin-baseline”: “abcd1234efgh5678ijkl9012mnop3456qrst7890”
}

字段说明

1.    name:
•    项目名称,通常是你项目的标识符。
•    例如:"my-cool-project"
2.    version:
•    项目版本号,遵循语义化版本规则。
•    例如:"1.0.0"
3.    description:
•    对项目的简要描述(可选)。
•    例如:"A project using vcpkg to manage dependencies."
4.    dependencies:
•    项目依赖的库,可以是库名或指定版本的对象。
•    支持的格式:
•    仅指定库名:"boost"
•    指定版本范围:{ "name": "fmt", "version>=": "9.1.0" }
5.    builtin-baseline:
•    指定 vcpkg 使用的 Git 基线版本(必须匹配你的 vcpkg 克隆仓库的某次提交),确保依赖解析的一致性。
•    例如:"abcd1234efgh5678ijkl9012mnop3456qrst7890"

使用 vcpkg.json 管理项目依赖

  1. 初始化 vcpkg.json

在项目根目录创建 vcpkg.json 文件并填入依赖信息。例如:

{
“name”: “my-example”,
“version”: “1.0.0”,
“dependencies”: [
“fmt”,
“boost”,
{ “name”: “openssl”, “version>=”: “1.1.1” }
],
“builtin-baseline”: “abcd1234efgh5678ijkl9012mnop3456qrst7890”
}

  1. 运行依赖安装命令

在 vcpkg 根目录下,运行以下命令解析和安装依赖:

vcpkg install

•    该命令会读取项目的 vcpkg.json 文件,自动安装依赖库及其版本。
  1. 与 CMake 项目集成

在项目的 CMakeLists.txt 文件中,启用 vcpkg.json 集成:

CMakeLists.txt

设置 vcpkg 的工具链文件

set(CMAKE_TOOLCHAIN_FILE “${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake”)

项目定义

project(my-example)

添加依赖的库

find_package(fmt CONFIG REQUIRED)
find_package(Boost REQUIRED)

链接库到目标

add_executable(main main.cpp)
target_link_libraries(main PRIVATE fmt::fmt Boost::Boost)

运行 CMake 时会自动解析和使用 vcpkg.json 中定义的依赖。

  1. 其他有用的命令
    • 升级依赖库:

vcpkg upgrade

根据 vcpkg.json 检查并升级依赖库版本。

•    移除未使用的库:

vcpkg remove —outdated

•    查看安装的库:

vcpkg list

依赖版本管理

在 dependencies 中可以使用以下方式定义版本:

1.    不指定版本(默认最新):

“dependencies”: [“fmt”, “boost”]

2.    指定最小版本:

“dependencies”: [
{ “name”: “fmt”, “version>=”: “9.1.0” }
]

3.    指定精确版本:

“dependencies”: [
{ “name”: “fmt”, “version”: “9.1.0” }
]

4.    版本范围(不常用):

“dependencies”: [
{ “name”: “fmt”, “version>=”: “9.0.0”, “version<=”: “9.1.0” }
]

使用场景和优势
• 简化依赖管理:开发者只需定义依赖,vcpkg 自动安装和管理。
• 一致性保证:builtin-baseline 确保团队中的每个人使用相同版本的依赖。
• 版本更新简单:通过更新 vcpkg.json 和 builtin-baseline 即可完成依赖升级。

如果你需要帮助配置具体依赖或项目集成,欢迎提供更多信息!

好的,我帮你整理一份 vcpkg 使用手册(Markdown 格式),结合你在 macOS 上遇到的问题和常见操作,同时包含 Linux 下的用法。文档会标明常见坑和注意事项。

vcpkg 使用手册

  1. vcpkg 简介

vcpkg 是微软提供的 C/C++ 包管理工具,支持跨平台安装第三方库,适合在 macOS、Linux、Windows 下统一管理依赖。
• 管理依赖:boost, protobuf, mysql, redis++ 等。
• 与 CMake 集成,通过 CMAKE_TOOLCHAIN_FILE 指定。
• 支持多平台、arm64/x86 架构。

  1. 基本操作

2.1 克隆 vcpkg

git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh # Linux/macOS
.\bootstrap-vcpkg.bat # Windows

2.2 安装库

./vcpkg install <库名>:

•    <triplet> 指编译平台和架构,例如:
•    x64-osx → macOS x64
•    arm64-osx → macOS ARM
•    x64-linux → Linux x64

示例:

./vcpkg install boost:arm64-osx —without-python
./vcpkg install protobuf:arm64-osx
./vcpkg install libmysql:arm64-osx
./vcpkg install spdlog:arm64-osx
./vcpkg install redis++:arm64-osx
./vcpkg install nlohmann-json:arm64-osx
./vcpkg install curl:arm64-osx

2.3 搜索库

./vcpkg search <关键字>

示例:

./vcpkg search mysql

输出可能包含:
• libmysql → 官方 MySQL 客户端库
• libmariadb → MariaDB Connector/C(兼容 MySQL)
• boost-mysql → Boost MySQL 模块
• mysql-connector-cpp → MySQL C++ 连接器

⚠️ 注意:有些旧库(如 mysql-connector-c、mariadb-connector-c)在新版 vcpkg 已经不存在,使用 libmysql 或 libmariadb 替代。

2.4 列出已安装库

./vcpkg list

2.5 更新 vcpkg

git pull
./vcpkg update

2.6 移除库

./vcpkg remove <库名>

2.7 清理 / 重装库

如果出现 SDK 路径错误或编译失败:

./vcpkg remove —outdated
./vcpkg remove <库名>
./vcpkg install <库名>:

macOS 上常见问题:SDK 版本不一致(如 Xcode 升级后仍指向 MacOSX14.5.sdk),需要重新指定:

export CMAKE_OSX_SYSROOT=$(xcrun —sdk macosx —show-sdk-path)

或者在 CMake 命令中指定:

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_OSX_SYSROOT=$(xcrun —sdk macosx —show-sdk-path)

  1. CMake 集成

3.1 使用 vcpkg toolchain

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

•    macOS 上可指定 SDK:

-DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk

3.2 在 CMakeLists.txt 中引用

find_package(Boost REQUIRED CONFIG COMPONENTS system filesystem program_options)
find_package(Protobuf CONFIG REQUIRED)
find_package(MySQL REQUIRED)
find_package(spdlog CONFIG REQUIRED)
find_package(redis++ CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(CURL REQUIRED)

target_link_libraries(your_target PRIVATE
Boost::system
Boost::filesystem
protobuf::libprotobuf
MySQL::MySQL
spdlog::spdlog_header_only
redis++::redis++
nlohmann_json::nlohmann_json
CURL::libcurl
)

  1. macOS SDK 常见问题
    1. libresolv.tbd / SDK 错误
      • 出现 /usr/lib/libresolv.tbd 丢失或指向旧 SDK(MacOSX14.5.sdk)。
      • 解决方法:
    2. 检查 SDK 路径:

xcrun —sdk macosx —show-sdk-path

2.    重新生成 CMake:

rm -rf build/
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_OSX_SYSROOT=$(xcrun —sdk macosx —show-sdk-path)

2.    强制替换旧 SDK
•    如果 vcpkg port 文件中写死了旧 SDK,可以批量替换:

grep -rl “MacOSX14.5.sdk” ./vcpkg/installed/arm64-osx | while read f; do
sed -i ‘’ ‘s#MacOSX14.5.sdk#MacOSX.sdk#g’ “$f”
done

  1. Linux 使用示例
    • 安装库(x64 Linux):

./vcpkg install boost:x64-linux
./vcpkg install protobuf:x64-linux
./vcpkg install libmysql:x64-linux
./vcpkg install spdlog:x64-linux
./vcpkg install redis++:x64-linux
./vcpkg install nlohmann-json:x64-linux
./vcpkg install curl:x64-linux

•    CMake 集成与 macOS 一样:

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

  1. 小技巧 / 常见坑

问题 原因 解决方法
找不到 libmysql / MySQLConfig.cmake 端口名不对(旧库) 使用 libmysql 或 libmariadb
编译 boost 时不需要 Python 默认启用 python ./vcpkg install boost —without-python
macOS SDK 版本错误 port 文件写死旧 SDK 替换 SDK 或重新安装库
编译失败 python3:arm64-osx vcpkg python3 port 构建问题 可跳过 python 依赖,或者查看 官方问题
搜索到 binary 文件匹配 grep -R 也会匹配二进制 用 grep -a 或 strings 过滤可读文本

  1. 安装示例脚本(macOS arm64)

!/bin/bash

VCPKG_ROOT=~/vcpkg
TRIPLET=arm64-osx

更新 vcpkg

cd $VCPKG_ROOT
git pull
./bootstrap-vcpkg.sh

安装依赖

./vcpkg install boost:$TRIPLET —without-python
./vcpkg install protobuf:$TRIPLET
./vcpkg install libmysql:$TRIPLET
./vcpkg install spdlog:$TRIPLET
./vcpkg install redis++:$TRIPLET
./vcpkg install nlohmann-json:$TRIPLET
./vcpkg install curl:$TRIPLET

我可以帮你再生成一个 Linux 版本的安装脚本,和一个 CLion / VSCode 配置模板,直接就能在不同平台上切换。

你希望我帮你写吗?

完全对,你的担心很合理。问题在于:

1️⃣ 原因

你当前的 vcpkg 包(比如 libmysql、Boost 等)在编译时已经绑定了某个 SDK 版本(比如 MacOSX14.5.sdk)。这会导致:
• vcpkg 内部的 CMake 配置文件里硬编码了 SDK 路径:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk

•    如果系统升级了 Xcode 或 macOS SDK,旧路径就不存在,编译就会报错(找不到 libresolv.tbd、libdl.tbd 等)。

2️⃣ 为什么会出现这种情况
• vcpkg 默认会在 第一次构建时捕获环境中的 SDK,然后把路径写进 installed/arm64-osx/share/… 里的 *_targets.cmake 文件。
• 这些 cmake 文件里面的 INTERFACE_LINK_LIBRARIES 或 CMAKE_OSX_SYSROOT 都指向了旧 SDK。
• 之后即使你把 CMAKE_OSX_SYSROOT 改成新 SDK,vcpkg 的库仍然依赖旧路径。

3️⃣ 解决方法

方法 A:清理重装库

1.    删除整个 vcpkg 的 installed 目录(或针对 arm64-osx 清理):

rm -rf ~/vcpkg/installed/arm64-osx

2.    使用新 SDK 重新安装依赖:

./vcpkg install libmysql boost spdlog nlohmann-json redis-plus-plus curl

•    可在命令行加上指定 SDK:

cmake -DCMAKE_OSX_SYSROOT=$(xcrun —sdk macosx —show-sdk-path) …

方法 B:不绑定 SDK(更灵活)
• 安装时加上 VCPKG_FORCE_SYSTEM_BINARIES 或 VCPKG_CMAKE_SYSTEM_NAME,让 vcpkg 不硬编码 SDK。
• 或者使用 vcpkg 的 toolchain.cmake 在 CMake 中动态设置 SDK:

if(NOT DEFINED CMAKE_OSX_SYSROOT)
execute_process(
COMMAND xcrun —sdk macosx —show-sdk-path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()

方法 C:升级 vcpkg port 文件
• vcpkg 的新版本有些 port 会自动适配新 SDK,尤其是常用库如 Boost、libmysql。
• 执行:

git pull
./vcpkg update
./vcpkg upgrade —no-dry-run

💡 总结
• 依赖旧 SDK 是 vcpkg 构建机制导致的,属于硬编码问题。
• 最稳妥的办法是 清理 installed 目录 + 用新 SDK 重新编译所有依赖。
• 如果想长期避免,每次 SDK 升级后都可以重装依赖,或者用上面动态获取 SDK 的方法。

我可以帮你写一个 macOS vcpkg 自动升级 SDK 并重装依赖的 bash 脚本,保证以后 SDK 升级后直接一键更新。

你希望我帮你写吗?

cmake -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.5.sdk ..

echo $CMAKE_OSX_SYSROOT
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.5.sdk

引用