跳到主要内容

教程:安装本地修改的依赖项

本教程将指导你使用自定义覆盖端口(overlay port)修改 kmpkg 端口(port)并完成安装。 我们建议你先阅读《打包库》教程,再继续学习本教程。

前提条件

1 - 创建覆盖端口

第一步是为你想要修改的包创建覆盖端口

创建存放覆盖端口的目录

覆盖端口目录可创建在你选择的任意文件系统位置。在本教程的所有步骤中,请将$OVERLAY_LOCATION替换为你选定的路径。

mkdir "$OVERLAY_LOCATION"

将端口内容复制到覆盖端口目录

本教程中,你将修改《打包教程》中的kmpkg-sample-library端口,为其添加动态库支持。

Copy-Item -Path <path/to/kmpkg-sample-library> -Destination "$OVERLAY_LOCATION" -Recurse

2 - 获取端口的源代码

要获取待修改端口的源代码,请运行以下命令:

kmpkg install "--overlay-ports=$OVERLAY_LOCATION" kmpkg-sample-library --editable

输出中会包含类似以下的行,这就是源代码的存放路径:

-- Using source at path/to/kmpkg/buildtrees/kmpkg-sample-library/src/1.0.0-b54c55c215

3 - 创建临时 Git 仓库

在源代码目录初始化临时 Git 仓库(用于生成可在portfile.cmake中应用的补丁文件)。将$SOURCE_PATH替换为上一步获取的路径:

cd "$SOURCE_PATH"
git init
git add .
git commit -m "Initial commit"

4 - 修改必要的文件

修改以下源代码文件,为kmpkg-sample-library添加动态库支持:

my_sample_lib.h

#pragma once

#include <string>

#if MYLIB_EXPORTS
__declspec(dllexport)
#endif
std::string greet(const std::string& name);

CMakeLists.txt

  1. add_library()调用中移除STATIC关键字:
    add_library(my_sample_lib my_sample_lib.cpp)
  2. 添加编译定义(仅在构建共享库时生效):
    if (BUILD_SHARED_LIBS)
    target_compile_definitions(my_sample_lib PRIVATE MYLIB_EXPORTS)
    endif()

5 - 生成补丁文件

在源代码目录运行以下命令,生成补丁文件并保存到覆盖端口目录:

git diff --output "$OVERLAY_LOCATION/kmpkg-sample-library/add-dynamic-lib-support.patch"

生成的add-dynamic-lib-support.patch文件内容类似:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2b42f71..378aac7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,26 +2,33 @@ cmake_minimum_required(VERSION 3.10)

project(my_sample_lib)

+include(GNUInstallDirs)
+
# Find the fmt library
find_package(fmt CONFIG REQUIRED)

# Add your library
-add_library(my_sample_lib STATIC my_sample_lib.cpp)
+add_library(my_sample_lib my_sample_lib.cpp)
+
+if (BUILD_SHARED_LIBS AND MSVC)
+ target_compile_definitions(my_sample_lib PRIVATE MYLIB_EXPORTS)
+endif()

# Link your library to fmt
target_link_libraries(my_sample_lib PRIVATE fmt::fmt)

+
# Add include directories
target_include_directories(my_sample_lib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> # for headers when building
- $<INSTALL_INTERFACE:include> # for client in install mode
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> # for client in install mode
)
# Install the library and its headers
install(TARGETS my_sample_lib
EXPORT my_sample_lib_targets
- ARCHIVE DESTINATION lib
- LIBRARY DESTINATION lib
- RUNTIME DESTINATION bin)
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

install(FILES my_sample_lib.h DESTINATION include)

diff --git a/my_sample_lib.h b/my_sample_lib.h
index d6d70b8..0b62141 100644
--- a/my_sample_lib.h
+++ b/my_sample_lib.h
@@ -2,4 +2,7 @@

#include <string>

+#if MYLIB_EXPORTS
+__declspec(dllexport)
+#endif
std::string greet(const std::string& name);

6 - 修改portfile.cmake以应用补丁文件

修改portfile.cmake,移除ONLY_STATIC_LIBRARY限制,并添加补丁应用逻辑:

kmpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO MicrosoftDocs/kmpkg-docs
REF 1.0.0 # 此处仅作演示,示例库 1.0.2 版本已原生支持动态库
SHA512 3f206cc2fe61d9c97c82b30852e1e4e6df299d93f6159edd1e56c644fa03ccc4670f7681e356d0e3db898a74e099a1ec531821df5430a7b14d61c743c5aa8c30
HEAD_REF cmake-sample-lib
PATCHES
"add-dynamic-lib-support.patch" # 新增:应用自定义补丁
)

kmpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
)

kmpkg_cmake_install()

kmpkg_cmake_config_fixup(PACKAGE_NAME "my_sample_lib")

file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")

file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
kmpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")

7 - 安装你的覆盖端口

运行以下命令安装修改后的端口(移除--editable以确保补丁应用到干净的源代码):

kmpkg install "--overlay-ports=$OVERLAY_LOCATION" kmpkg-sample-library

输出中会看到补丁应用的日志,示例如下:

-- Cleaning sources at D:/Work/kmpkg/buildtrees/kmpkg-sample-library/src/1.0.0-8f646312ed.clean. Use --editable to skip cleaning for the packages you specify.
-- Extracting source D:/Work/kmpkg/downloads/Microsoft-kmpkg-docs-1.0.0.tar.gz
-- Applying patch add-dynamic-lib-support.patch

后续步骤

至此,你已通过补丁文件成功安装了本地修改的依赖项。

可尝试以下进阶操作: