跳到主要内容

kmpkg 在 CMake 项目中的使用

kmpkg 提供与 CMake 的无缝集成能力,可自动让已安装的软件包在你的项目中可用。其集成机制是通过提供一个 CMake 工具链文件实现的。

CMake 首次配置项目时,会运行内部搜索程序来定位可用的 工具链(编译器、 链接器等)。该搜索过程在 CMakeLists.txt 文件的 project() 函数中执行。

为自定义工具链选择流程,CMake 支持使用自定义的 CMake 语言脚本(即工具链文件)。可通过设置 CMAKE_TOOLCHAIN_FILE 变量指定工具链文件。CMake 会解析传入的工具链脚本内容,并据此设置变量定义、所需构建工具的路径,以及其他构建参数(如交叉编译标志)。

当你将 CMAKE_TOOLCHAIN_FILE 设置为使用 kmpkg 工具链 (<kmpkg-root>/scripts/buildsystems/kmpkg.cmake)时,kmpkg 会借助工具链文件机制注入代码,以透明的方式与 CMake 内置函数集成。

你仍可通过设置三元组变量 KMPKG_CHAINLOAD_TOOLCHAIN_FILE,使用工具链文件配置自定义工具集。

kmpkg 的集成行为会根据你使用的操作模式而有所不同:

经典模式下,kmpkg 会合理设置 CMake 搜索路径,使已安装的软件包可通过 find_package()find_library()find_path() 函数被找到。

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

由于工具链文件在 project() 调用期间解析,所有修改 kmpkg 配置的 CMake 级变量都必须在首次调用 project() 之前设置。若你修改的任一 kmpkg 配置导致 ABI 哈希 发生变化,可能还需要重新配置 CMake 项目。

有关使用 CMake 的完整示例,请参阅安装和使用软件包示例:sqlite

CMAKE_TOOLCHAIN_FILE

信息

若你在 CMakeList.txt 文件中设置 CMAKE_TOOLCHAIN_FILE,请确保该变量在所有 project() 调用之前设置。

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

我们建议使用 [CMake 预设(CMake Presets)] 指定工具链文件。例如,若你已定义环境变量 KMPKG_ROOT,可使用以下 CMakePresets.json 文件,并在配置命令行中传入 --preset debug

CMakePresets.json
{
"version": 3,
"configurePresets": [
{
"name": "debug",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{KMPKG_ROOT}/scripts/buildsystems/kmpkg.cmake"
}
}
]
}
cmake -B build -S /my/project --preset debug

若你需要为当前机器使用 kmpkg 的绝对路径,可创建 CMakeUserPresets.json 文件,并将其添加到 .gitignore 文件中:

CMakeUserPresets.json
{
"version": 2,
"configurePresets": [
{
"name": "default",
"inherits": "debug",
"environment": {
"KMPKG_ROOT": "<kmpkg 的路径>"
}
}
]
}

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

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

使用库

kmpkg 支持 CMake 原生的库查找机制:find_package()find_library()find_path()。安装带有特定 CMake 支持的库时,kmpkg 会显示该库的使用说明:

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

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

kmpkg 不会自动将任何包含路径或链接路径添加到你的项目中。若要使用仅头文件库,可通过 find_path() 函数实现(该函数可在所有平台上正常工作):

# 查找并使用 catch2
find_path(CATCH_INCLUDE_DIR NAMES catch.hpp PATH_SUFFIXES catch2)
target_include_directories(main PRIVATE ${CATCH_INCLUDE_DIR})

IDE 集成

CLion

打开工具链设置(Windows 和 Linux 系统:File > Settings;macOS 系统:CLion > Preferences),然后进入 CMake 设置(Build, Execution, Deployment > CMake)。在 CMake options 中添加以下内容:

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

你需要为每个配置文件分别添加此行。

使用多个工具链文件

若要将 kmpkg 工具链文件与其他工具链文件结合使用,可设置 CMake 缓存变量 KMPKG_CHAINLOAD_TOOLCHAIN_FILE

cmake ../my/project \
-DCMAKE_TOOLCHAIN_FILE=C:/kmpkg/scripts/buildsystems/kmpkg.cmake \
-DKMPKG_CHAINLOAD_TOOLCHAIN_FILE=../my/project/toolchain.cmake

或者,你也可在主工具链文件的末尾引入 kmpkg 工具链:

# MyToolchain.cmake
set(CMAKE_CXX_COMPILER ...)
set(KMPKG_TARGET_TRIPLET x64-my-custom-windows-triplet)
include(/path/to/kmpkg/scripts/buildsystems/kmpkg.cmake)
信息

构建库时,kmpkg 不会自动应用你的工具链配置(如编译器或编译标志)。若要修改 kmpkg 的库配置,你必须创建自定义三元组文件(该文件可共享你的工具链配置)。

配置项参考

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

KMPKG_TARGET_TRIPLET

该配置项控制 kmpkg 安装和使用库时采用的三元组

若未设置,kmpkg 会根据当前编译器配置自动检测合适的默认三元组。若你修改了该 CMake 变量,必须删除缓存并重新配置项目。

KMPKG_HOST_TRIPLET

该变量控制安装宿主依赖项时使用的三元组

若未设置,kmpkg 会自动检测合适的原生三元组(x64-windows、x64-osx、x64-linux)。

另请参阅宿主依赖项

KMPKG_INSTALLED_DIR

该变量设置库的安装和使用路径。

在清单模式下,默认路径为 ${CMAKE_BINARY_DIR}/kmpkg_installed

在经典模式下,默认路径为 ${KMPKG_ROOT}/installed

KMPKG_MANIFEST_MODE

该变量强制 kmpkg 以清单模式或经典模式运行。

KMPKG_MANIFEST_DIR 非空,或 ${CMAKE_SOURCE_DIR}/kmpkg.json 文件存在时,默认值为 ON

若检测到 kmpkg.json 文件但需禁用清单模式,可将该变量设为 OFF

KMPKG_MANIFEST_DIR

该变量指定包含 kmpkg.json 清单的备用目录。

${CMAKE_SOURCE_DIR}/kmpkg.json 文件存在,默认值为 ${CMAKE_SOURCE_DIR}

KMPKG_MANIFEST_INSTALL

该变量控制 kmpkg 是否在配置阶段自动运行以安装依赖项。

KMPKG_MANIFEST_MODEON,默认值为 ON

KMPKG_BOOTSTRAP_OPTIONS

该变量可设置为传递给 ./bootstrap-kmpkg 命令的额外参数。

在清单模式下,若 kmpkg 可执行文件不存在,会自动引导(bootstrap)kmpkg。

KMPKG_OVERLAY_TRIPLETS

该变量可设置为路径列表,这些路径会以 --overlay-triplets=... 的形式传递到命令行。

KMPKG_OVERLAY_PORTS

该变量可设置为路径列表,这些路径会以 --overlay-ports=... 的形式传递到命令行。

KMPKG_MANIFEST_FEATURES

该变量可设置为清单安装时要激活的功能列表。

例如,项目可通过功能控制是否构建包含额外依赖项的测试或示例代码:

{
"name": "mylibrary",
"version": "1.0",
"dependencies": [ "curl" ],
"features": {
"samples": {
"description": "构建示例代码",
"dependencies": [ "fltk" ]
},
"tests": {
"description": "构建测试代码",
"dependencies": [ "gtest" ]
}
}
}

可直接通过 [CMake 预设(CMake Presets)] 的 "cacheVariables" 控制该配置项,或根据其他配置项间接控制:

# CMakeLists.txt

option(BUILD_TESTING "构建测试代码" OFF)
if(BUILD_TESTING)
list(APPEND KMPKG_MANIFEST_FEATURES "tests")
endif()

option(BUILD_SAMPLES "构建示例代码" OFF)
if(BUILD_SAMPLES)
list(APPEND KMPKG_MANIFEST_FEATURES "samples")
endif()

project(myapp)

# ...

KMPKG_MANIFEST_NO_DEFAULT_FEATURES

该变量控制是否在 KMPKG_MANIFEST_FEATURES 列出的功能之外激活默认功能。若设为 ON,默认功能将不会自动激活。

默认值为 OFF

KMPKG_INSTALL_OPTIONS

该变量可设置为列表,包含自动安装期间传递给 kmpkg 工具的额外命令行参数。

KMPKG_PREFER_SYSTEM_LIBS

注意

该功能已被弃用。请改用空的覆盖端口(overlay ports)。

该变量控制 kmpkg 是将其路径追加(而非前置)到 CMAKE_PREFIX_PATHCMAKE_LIBRARY_PATHCMAKE_FIND_ROOT_PATH,使 kmpkg 库/软件包在工具链/系统库/软件包之后被找到。

默认值为 OFF

KMPKG_FEATURE_FLAGS

该变量可设置为功能标志列表,在自动安装期间传递给 kmpkg 工具,以启用实验性行为。

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

KMPKG_TRACE_FIND_PACKAGE

设为 ON 时,会打印每次 find_package 的调用。嵌套调用(如通过 find_dependency)会根据嵌套深度缩进显示。

KMPKG_LOCK_FIND_PACKAGE_<Pkg>

设置该选项后,对 find_package 的非嵌套调用会被强制启用(KMPKG_LOCK_FIND_PACKAGE_<Pkg>=ON)或禁用(KMPKG_LOCK_FIND_PACKAGE_<Pkg>=OFF)。

该变量是一个工具,用于控制使用 CMake 构建系统的 kmpkg 端口中的直接依赖项及相关功能。它可与 kmpkg_check_features 配合使用,避免对传递依赖项产生意外影响。