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:
{
"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 文件中:
{
"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 的变量都必须在首个 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_MODE 为 ON,默认值为 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_PATH、CMAKE_LIBRARY_PATH 和 CMAKE_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 配合使用,避免对传递依赖项产生意外影响。