CMake 项目中的 vcpkg

vcpkg 提供与 CMake 的无缝集成,让你在项目中可以自动使用已安装的包。 vcpkg 集成的机制是通过提供 CMake 工具链文件。

CMake 首次配置项目时会运行内部搜索例程来查找可行的工具链(编译器、链接器等)。 此搜索发生在 CMakeLists.txt 中的 project() 函数中。

CMake 支持使用自定义 CMake 语言脚本(称为工具链文件)来自定义工具链选择过程。 通过设置 CMAKE_TOOLCHAIN_FILE 变量来指定工具链文件。 CMake 会评估所提供的工具链脚本的内容,并设置变量定义、所需生成工具的路径和其他生成参数,例如交叉编译标志。

如果将 CMAKE_TOOLCHAIN_FILE 设置为使用 vcpkg 工具链 (<vcpkg-root>/scripts/buildsystems/vcpkg.cmake),vcpkg 利用工具链文件机制将代码以透明方式与内置的 CMake 函数集成。

通过 VCPKG_CHAINLOAD_TOOLCHAIN_FILE 三联密码变量,仍可使用工具链文件来配置自己的工具集。

vcpkg 集成的工作方式因所使用的操作模式有所不同:

经典模式下,vcpkg 适当地设置 CMake 搜索路径以通过 find_package()find_library()find_path() 函数让已安装的包可供使用。

清单模式下,除了上述文件以外,工具链还会检测清单文件(vcpkg.json 文件),并运行 vcpkg install 以自动获取项目的依赖项。

由于工具链文件是在 project() 调用期间进行计算的,因此必须在第一次调用 project() 之前设置修改 vcpkg 设置的所有 CMake 级变量。 如果修改会导致 ABI 哈希发生变化的任何 vcpkg 设置,则可能还必需要重新配置 CMake 项目。

有关使用 CMake 的完全工作示例,请参阅安装和使用包示例:sqlite

CMAKE_TOOLCHAIN_FILE

注意

如果在 CMakeList.txt 文件中设置 CMAKE_TOOLCHAIN_FILE,请确保在调用 project() 之前设置变量。

配置为使用 vcpkg 工具链文件(通过 CMake 设置 CMAKE_TOOLCHAIN_FILE)的项目可以使用标准 CMake 函数查找 vcpkg 中的库:find_package()find_path()find_library()

建议使用 CMake 预设来指定工具链文件。 例如,如果定义了环境变量 VCPKG_ROOT,则可以使用以下 CMakePresets.json 变量并在配置行上传递 --preset debug

{
  "version": 2,

  "configurePresets": [
    {
      "name": "debug",
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
      }
    }
  ]
}
cmake -B build -S /my/project --preset debug

如果需要为特定于当前计算机的 vcpkg 使用绝对路径,可以使用 CMakeUserPresets.json 并将其添加到 .gitignore 文件中。

{
  "version": 2,

  "configurePresets": [
    {
      "name": "debug",
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
      }
    }
  ]
}

低于 3.19 的 CMake 版本必须在配置命令行上传递工具链文件:

cmake ../my/project -DCMAKE_TOOLCHAIN_FILE=<vcpkg-root>/scripts/buildsystems/vcpkg.cmake

使用库

vcpkg 支持 CMake 的本机机制来查找库:find_package()find_library()find_path()。 安装具有特定 CMake 支持的库时,vcpkg 将显示有关如何使用库的使用情况信息:

The package zlib is compatible with built-in CMake targets:

    find_package(ZLIB REQUIRED)
    target_link_libraries(main PRIVATE ZLIB::ZLIB)

vcpkg 不会自动将任何包含路径或链接路径添加到项目中。 若要使用仅标头库,可以使用能在所有平台上工作的 find_path()

# To find and use catch2
find_path(CATCH_INCLUDE_DIR NAMES catch.hpp PATH_SUFFIXES catch2)
target_include_directories(main PRIVATE ${CATCH_INCLUDE_DIR})

IDE 集成

Visual Studio/Visual Studio Code

建议在 Visual Studio 和 Visual Studio Code 中使用 CMake 预设

有关详细信息,请参阅在 Visual Studio 中使用 CMake 预设进行配置和生成在 Visual Studio Code 中使用 CMake 预设进行配置和生成

CLion

打开工具链设置(Windows 和 Linux 上的 File > Settings,macOS 上的 CLion > Preferences),然后转到 CMake 设置 (Build, Execution, Deployment > CMake)。 在 CMake options 中,添加以下行:

-DCMAKE_TOOLCHAIN_FILE=<vcpkg-root>/scripts/buildsystems/vcpkg.cmake

必须单独将此行添加到每个配置文件。

使用多个工具链文件

若要将 vcpkg 的工具链文件与其他工具链文件合并,可以设置 CMake 缓存变量 VCPKG_CHAINLOAD_TOOLCHAIN_FILE

cmake ../my/project \
   -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake \
   -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=../my/project/toolchain.cmake

或者,可以在主工具链文件的末尾包含 vcpkg 工具链:

# MyToolchain.cmake
set(CMAKE_CXX_COMPILER ...)
set(VCPKG_TARGET_TRIPLET x64-my-custom-windows-triplet)
include(/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake)

注意

vcpkg 不会在生成库时自动应用工具链的设置,例如编译器或编译标志。 若要更改 vcpkg 的库设置,必须创建自定义三联密码文件(可以共享工具链)**

引用参考:

所有 vcpkg 影响的变量都必须通过命令行或 set() 语句在第一个 project() 指令之前定义(例如,CMakePresets.json"cacheVariables" 映射)。

VCPKG_TARGET_TRIPLET

此设置控制 vcpkg 会从其安装和使用库的三联密码

如果未设置,vcpkg 将自动检测给定当前编译器设置的相应默认三联密码。 如果更改此 CMake 变量,则必须删除缓存并重新配置。

VCPKG_HOST_TRIPLET

此变量控制将为哪个三联密码安装主机依赖项。

如果未设置,vcpkg 将自动检测合适的本机三联密码(x64-windows、x64-osx、x64-linux)。

另请参阅主机依赖项

VCPKG_INSTALLED_DIR

此变量用于设置将会从哪个位置安装和使用库。

在清单模式下,此变量默认为 ${CMAKE_BINARY_DIR}/vcpkg_installed

在经典模式下,此变量默认为 ${VCPKG_ROOT}/installed.

VCPKG_MANIFEST_MODE

此变量强制 vcpkg 在清单模式或经典模式下运行。

VCPKG_MANIFEST_DIR 为非空或 ${CMAKE_SOURCE_DIR}/vcpkg.json 存在时,默认为 ON

若要在检测到 vcpkg.json 时禁用清单模式,请将此变量设置为 OFF

VCPKG_MANIFEST_DIR

此变量指定包含 vcpkg.json 清单的备用文件夹。

如果 ${CMAKE_SOURCE_DIR}/vcpkg.json 存在,则默认为 ${CMAKE_SOURCE_DIR}

VCPKG_MANIFEST_INSTALL

此变量控制 vcpkg 是否会在配置步骤期间自动运行以安装依赖项。

如果 VCPKG_MANIFEST_MODEON,则默认为 ON

VCPKG_BOOTSTRAP_OPTIONS

可将此变量设置为要传递给 ./bootstrap-vcpkg 的其他命令参数。

在清单模式下,如果可执行文件不存在,vcpkg 将自动启动。

VCPKG_OVERLAY_TRIPLETS

可将此变量设置为在命令行上要作为 --overlay-triplets=... 传递的路径列表。

VCPKG_OVERLAY_PORTS

可将此变量设置为在命令行上要作为 --overlay-ports=... 传递的路径列表。

VCPKG_MANIFEST_FEATURES

可将此变量设置为从清单进行安装时的功能列表。

例如,项目可以使用功能来控制使用其他依赖项的生成是启用测试还是示例。

{
  "name": "mylibrary",
  "version": "1.0",
  "dependencies": [ "curl" ],
  "features": {
    "samples": {
      "description": "Build Samples",
      "dependencies": [ "fltk" ]
    },
    "tests": {
      "description": "Build Tests",
      "dependencies": [ "gtest" ]
    }
  }
}

此设置可以直接由 CMake 预设"cacheVariables"控制,也可以基于其他设置间接控制:

# CMakeLists.txt

option(BUILD_TESTING "Build tests" OFF)
if(BUILD_TESTING)
  list(APPEND VCPKG_MANIFEST_FEATURES "tests")
endif()

option(BUILD_SAMPLES "Build samples" OFF)
if(BUILD_SAMPLES)
  list(APPEND VCPKG_MANIFEST_FEATURES "samples")
endif()

project(myapp)

# ...

VCPKG_MANIFEST_NO_DEFAULT_FEATURES

除了在 VCPKG_MANIFEST_FEATURES 中列出的那些功能以外,此变量还控制默认功能的激活。 如设置为 ON,则默认功能不会自动激活。

默认为 OFF

VCPKG_INSTALL_OPTIONS

可将此变量设置为要在自动安装过程中传递给 vcpkg 工具的其他命令行参数的列表。

VCPKG_PREFER_SYSTEM_LIBS

警告

此功能已弃用。 请改用空的覆盖端口。

此变量控制 vcpkg 是否会将其路径追加到 CMAKE_PREFIX_PATHCMAKE_LIBRARY_PATHCMAKE_FIND_ROOT_PATH,使得可以在工具链/系统库包之后找到 vcpkg 库包。

默认为 OFF

VCPKG_FEATURE_FLAGS

可将此变量设置为要在自动安装过程中要传递给 vcpkg 工具的功能标志列表,以加入实验行为。

有关详细信息,请参阅 --feature-flags= 命令行选项。

VCPKG_TRACE_FIND_PACKAGE

设置为 ON 时,打印对每个调用的调用 find_package。 嵌套调用(例如通过 find_dependency)根据嵌套深度进行缩进。