教程:从清单文件安装依赖项
kmpkg 有两种运行模式:经典模式(classic mode)和清单模式(manifest mode)。本文介绍如何使用清单模式安装包,这是大多数用户的推荐使用方式。
在清单模式下,你需要在名为 kmpkg.json 的清单文件中声明项目的直接依赖项。
清单文件会将依赖项安装到专属的 kmpkg_installed 目录中;而经典模式下,所有包都会安装到公共的 %KMPKG_ROOT%/installed 目录。因此,每个项目都可拥有独立的清单和依赖项集合,不会与其他项目的依赖项产生冲突。
此外,使用版本控制、自定义注册表等高级功能也必须启用清单模式。
在本教程中,你将掌握以下操作:
前提条件
- kmpkg
- 终端
- 代码编辑器
- C++ 编译器
- (可选)CMake 或 MSBuild
创建 C++ 项目
在新文件夹中创建名为 main.cxx 的源文件,内容如下:
main.cxx
#include <cxxopts.hpp>
#include <fmt/format.h>
#include <range/v3/view.hpp>
namespace view = ranges::views;
int fib(int x)
{
int a = 0, b = 1;
for (int it : view::repeat(0) | view::take(x))
{
(void)it;
int tmp = a;
a += b;
b = tmp;
}
return a;
}
int main(int argc, char **argv)
{
cxxopts::Options options("fibo", "Print the fibonacci sequence up to a value 'n'");
options.add_options()("n,value", "The value to print to", cxxopts::value<int>()->default_value("10"));
auto result = options.parse(argc, argv);
auto n = result["value"].as<int>();
for (int x : view::iota(1) | view::take(n))
{
fmt::print("fib({}) = {}\n", x, fib(x));
}
}
示例代码引用了以下开源库:cxxopts、fmt 和 range-v3,这些库均可在 kmpkg 公共注册表(https://github.com/kumose/kmpkg)中获取。
创建 kmpkg 清单(kmpkg.json)
要声明这些依赖项,请在项目同级目录下创建 kmpkg.json 文件:
kmpkg.json
{
"dependencies": [
"cxxopts",
"fmt",
"range-v3"
]
}
你只需在 "dependencies" 列表中指定项目的直接依赖项,kmpkg 会自动解析并安装所需的所有传递依赖项(transitive dependencies)。
将 kmpkg 与构建系统集成
本步骤将演示如何将 kmpkg 与 CMake 或 MSBuild 集成,使项目构建时自动安装/还原依赖项。
若你使用其他构建系统,可跳过此步骤,直接进入:使用 kmpkg 安装依赖项。
MSBuild
要在 MSBuild 项目中使用 kmpkg,请运行以下命令:
kmpkg integrate install
只需在首次启用 MSBuild 集成时运行 kmpkg integrate install 命令。该操作会为所有现有及未来的项目启用 MSBuild 集成;若需移除系统级集成,可使用 kmpkg integrate remove。
此集成方式会自动将 kmpkg 安装的包添加到项目的以下属性中:包含目录(Include Directories)、库目录(Link Directories)和链接库(Link Libraries);同时会创建一个后期构建操作,确保所有必需的 DLL 文件被复制到构建输出目录。该功能适用于 Visual Studio 2015 及更高版本的所有解决方案和项目。
CMake
要在 CMake 项目中使用 kmpkg,需将 CMAKE_TOOLCHAIN_FILE 变量设置为 kmpkg 的 CMake 工具链文件。工具链文件路径为 %KMPKG_ROOT%/scripts/buildsystems/kmpkg.cmake(%KMPKG_ROOT% 为你的 kmpkg 安装路径)。
可通过以下任意方式设置工具链文件:
- 在
CMakePresets.json文件中配置CMAKE_TOOLCHAIN_FILE; - 在 CMake 配置命令中传入参数:
-DCMAKE_TOOLCHAIN_FILE=<path/to/kmpkg>/scripts/buildsystems/kmpkg.cmake; - 在
CMakeLists.txt文件中首次调用project()前,设置CMAKE_TOOLCHAIN_FILE变量。
使用 kmpkg 安装依赖项
若你使用 CMake/MSBuild 并完成了上一步配置,可直接跳至:构建项目。
若你使用其他构建系统,或希望手动安装依赖项,只需在清单文件所在目录运行 kmpkg install 命令:
PS D:\projects\manifest-example> kmpkg install
Detecting compiler hash for triplet x64-windows...
The following packages will be built and installed:
cxxopts:x64-windows -> 3.1.1
fmt:x64-windows -> 10.0.0
range-v3:x64-windows -> 0.12.0#1
* kmpkg-cmake:x64-windows -> 2023-05-04
* kmpkg-cmake-config:x64-windows -> 2022-02-06#1
Additional packages (*) will be modified to complete this operation.
Installing 1/5 kmpkg-cmake-config:x64-windows...
Installing 2/5 kmpkg-cmake:x64-windows...
Installing 3/5 cxxopts:x64-windows...
Installing 4/5 fmt:x64-windows...
Installing 5/5 range-v3:x64-windows...
Total install time: 48 s
cxxopts provides CMake targets:
# this is heuristically generated, and may not be correct
find_package(cxxopts CONFIG REQUIRED)
target_link_libraries(main PRIVATE cxxopts::cxxopts)
The package fmt provides CMake targets:
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE fmt::fmt)
# Or use the header-only version
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE fmt::fmt-header-only)
range-v3 provides CMake targets:
# this is heuristically generated, and may not be correct
find_package(range-v3 CONFIG REQUIRED)
target_link_libraries(main PRIVATE range-v3::meta range-v3::concepts range-v3::range-v3)
命令执行完成后,所有构建好的包会被放入 kmpkg_installed 目录。该目录的具体位置取决于构建系统:通常在构建系统的默认输出目录内,或 kmpkg.json 文件同级目录。
构建项目
MSBuild
默认情况下,MSBuild 项目中清单模式处于禁用状态。
要在项目中启用清单模式,需在 .vcxproj 文件中设置 KmpkgEnableManifest 属性:
<PropertyGroup Label="Kmpkg">
<KmpkgEnableManifest>true</KmpkgEnableManifest>
</PropertyGroup>
也可在调用 MSBuild 时通过参数启用:msbuild /p:KmpkgEnableManifest=true。
PS D:\projects\manifest-example> msbuild /p:KmpkgEnableManifest=true
MSBuild version 17.7.0-preview-23319-02+6829506b8 for .NET Framework
Build started 8/11/2023 11:29:50 AM.
Project "D:\projects\manifest-example\manifest-example.sln" on node 1 (default targets).
ValidateSolutionConfiguration:
Building solution configuration "Debug|x64".
Project "D:\projects\manifest-example\manifest-example.sln" (1) is building "D:\projects\manifest-example\manifest-example.vcxproj" (2) on node 1 (default targets).
PrepareForBuild:
(omitted)
InitializeBuildStatus:
(omitted)
ComputeStdModulesCompileInputs:
(omitted)
SetModuleDependencies:
Creating directory "x64\Debug\manifest.ceffc6eb_MD.tlog\".
KmpkgTripletSelection:
Using triplet "x64-windows" from "D:\projects\manifest-example\kmpkg_installed\x64-windows\x64-windows\"
Using normalized configuration "Debug"
KmpkgInstallManifestDependencies:
Installing kmpkg dependencies to D:\projects\manifest-example\kmpkg_installed\x64-windows\
Creating directory "D:\projects\manifest-example\kmpkg_installed\x64-windows\".
"D:\kmpkg\kmpkg.exe" install --x-wait-for-lock --triplet "x64-windows" --kmpkg-root "D:\kmpkg\" "--x-manifest-root=D:\projects\manifest-example\" "--x-install-root=D:\projects\manifest-example\kmpkg_installed\x64-windows\"
"D:\kmpkg\kmpkg.exe" install --x-wait-for-lock --triplet "x64-windows" --kmpkg-root "D:\kmpkg\" "--x-manifest-root=D:\projects\manifest-example\" "--x-install-root=D:\projects\manifest-example\kmpkg_installed\x64-windows\"
Detecting compiler hash for triplet x64-windows...
The following packages will be built and installed:
cxxopts:x64-windows -> 3.1.1
fmt:x64-windows -> 10.0.0
range-v3:x64-windows -> 0.12.0#1
* kmpkg-cmake:x64-windows -> 2023-05-04
* kmpkg-cmake-config:x64-windows -> 2022-02-06#1
(omitted)
ClCompile:
(omitted)
Link:
(omitted)
AppLocalFromInstalled:
pwsh.exe -ExecutionPolicy Bypass -noprofile -File "D:\kmpkg\scripts\buildsystems\msbuild\applocal.ps1" "D:\projects\manif
est-mode-msbuild\x64\Debug\manifest-example.exe" "D:\projects\manifest-example\kmpkg_installed\x64-windows\x64-windows\debug\bin"
"x64\Debug\manifest.ceffc6eb.tlog\manifest-example.write.1u.tlog" "x64\Debug\kmpkg.applocal.log"
D:\projects\manifest-example\x64\Debug\fmtd.dll
FinalizeBuildStatus:
(omitted)
Done Building Project "D:\projects\manifest-example\manifest-example.vcxproj" (default targets).
Done Building Project "D:\projects\manifest-example\manifest-example.sln" (default targets).
Build succeeded.
Visual Studio
默认情况下,Visual Studio 项目中清单模式处于禁用状态。要启用清单模式:
- 在解决方案资源管理器中右键单击项目,选择属性;
- 在左侧面板中选择 kmpkg 选项卡;
- 将
Use Kmpkg Manifest设置为 Yes。
(注:此处对应原文图片说明:Visual Studio 项目属性中启用 kmpkg 清单的界面)
在解决方案资源管理器中右键单击项目,选择生成即可构建项目:
Build started...
1>------ Build started: Project: manifest-example, Configuration: Debug x64 ------
1>Installing kmpkg dependencies to D:\projects\manifest-example\kmpkg_installed\x64-windows\
1>"D:\kmpkg\kmpkg.exe" install --x-wait-for-lock --triplet "x64-windows" --kmpkg-root "D:\kmpkg\" "--x-manifest-root=D:\projects\manifest-example\" "--x-install-root=D:\projects\manifest-example\kmpkg_installed\x64-windows\"
1>Detecting compiler hash for triplet x64-windows...
1>The following packages will be built and installed:
1> cxxopts:x64-windows -> 3.1.1
1> fmt:x64-windows -> 10.0.0
1> range-v3:x64-windows -> 0.12.0#1
1> * kmpkg-cmake:x64-windows -> 2023-05-04
1> * kmpkg-cmake-config:x64-windows -> 2022-02-06#1
1> (omitted)
1>main.cxx
1>manifest-example.vcxproj -> D:\projects\manifest-example\x64\Debug\manifest-example.exe
1>Done building project "manifest-example.vcxproj".
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
========== Build started at 12:07 PM and took 15.320 seconds ==========
CMake
1 - 创建 CMakeLists.txt 文件
在项目文件夹中添加以下 CMakeLists.txt 文件:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
project(fibonacci CXX)
find_package(fmt CONFIG REQUIRED)
find_package(range-v3 CONFIG REQUIRED)
find_package(cxxopts CONFIG REQUIRED)
set(CMAKE_CXX_STANDARD 17)
add_executable(fibo main.cxx)
target_link_libraries(fibo
PRIVATE
fmt::fmt
range-v3::range-v3
cxxopts::cxxopts)
2 - 配置 CMake 项目
运行以下命令(将 %KMPKG_ROOT% 替换为你的 kmpkg 安装路径):
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=%KMPKG_ROOT%\scripts\buildsystems\kmpkg.cmake
注意:项目依赖项会在配置过程中自动安装。
PS D:\projects\manifest-example> cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=D:\kmpkg\scripts\buildsystems\kmpkg.cmake
-- Running kmpkg install
Detecting compiler hash for triplet x64-windows...
The following packages will be built and installed:
cxxopts:x64-windows -> 3.1.1
fmt:x64-windows -> 10.0.0
range-v3:x64-windows -> 0.12.0#1
* kmpkg-cmake:x64-windows -> 2023-05-04
* kmpkg-cmake-config:x64-windows -> 2022-02-06#1
<omitted output>
-- Running kmpkg install - done
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
-- The CXX compiler identification is MSVC 19.27.29111.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: D:/projects/manifest-example/build
3 - 构建 CMake 项目
运行以下命令构建项目:
cmake --build build
PS D:\projects\manifest-example> cmake --build build
Microsoft (R) Build Engine version 16.7.0+b89cb5fde for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Checking Build System
Building Custom Rule D:\projects\manifest-example\CMakeLists.txt
main.cxx
fibo.vcxproj -> D:\projects\manifest-example\build\Debug\fibo.exe
Building Custom Rule D:\projects\manifest-example\CMakeLists.txt
后续步骤
本教程中,你通过清单文件为简单项目安装了依赖项。
可尝试以下进阶操作:
- 使用三元组(triplet)为自定义平台、编译器或构建架构安装包;
- 使用版本控制锁定版本,实现可重复构建;
- 使用二进制缓存在本地或持续集成环境中复用二进制文件;
- 使用自定义注册表管理私有库。