适配鸿蒙PC sha_ohos.patch 补丁文件详解
欢迎大家加入鸿蒙PC社区
📋 目录
补丁文件概述
什么是补丁文件?
补丁文件(Patch File)是一种记录源代码差异的文本文件,用于描述如何将一组修改应用到原始代码上。它是开源社区中代码审查、版本控制和跨平台适配的重要工具。
sha_ohos.patch 的作用
sha_ohos.patch 是 SHA 库适配 OpenHarmony 平台的核心文件,它记录了所有必要的代码修改,使得原始的 BrianGladman/sha 库能够在 OpenHarmony 平台上正确编译和运行。
为什么使用补丁?
优势
-
保持原始代码完整性
- 原始源码不受影响
- 便于版本升级和上游合并
- 清晰的修改历史
-
可追溯性
- 知道修改了什么
- 知道为什么修改
- 便于代码审查
-
可移植性
- 补丁可以应用到不同版本
- 支持跨平台适配
- 便于共享和复用
-
版本控制友好
- Git 原生支持补丁格式
- 便于存储和管理
- 支持自动化应用
与直接修改的对比
| 特性 | 使用补丁 | 直接修改 |
|---|---|---|
| 原始代码 | 保持不变 | 被修改 |
| 版本升级 | 容易 | 困难 |
| 修改记录 | 清晰 | 不清晰 |
| 代码审查 | 容易 | 困难 |
| 可移植性 | 高 | 低 |
| 维护成本 | 低 | 高 |
补丁文件格式
标准补丁格式
补丁文件使用标准的 unified diff 格式:
diff -aurN 原始文件 修改后文件
--- 原始文件 时间戳
+++ 修改后文件 时间戳
@@ -起始行,行数 +起始行,行数 @@
上下文行
-删除的行
+添加的行
上下文行
格式详解
1. 文件头
diff
diff -aurN sha/cmake/PackageConfig.cmake.in sha_patch/cmake/PackageConfig.cmake.in
diff: 命令名称-a: 将所有文件视为文本-u: 使用 unified diff 格式-r: 递归处理子目录-N: 将不存在的文件视为空文件sha/cmake/PackageConfig.cmake.in: 原始文件路径sha_patch/cmake/PackageConfig.cmake.in: 修改后文件路径
2. 时间戳行
diff
--- sha/cmake/PackageConfig.cmake.in 1969-12-31 16:00:00.000000000 -0800
+++ sha_patch/cmake/PackageConfig.cmake.in 2023-09-04 02:06:35.266667302 -0700
---: 原始文件标记+++: 修改后文件标记- 时间戳:文件的修改时间
3. 差异块
diff
@@ -0,0 +1,11 @@
-0,0: 原始文件从第 0 行开始,共 0 行+1,11: 修改后文件从第 1 行开始,共 11 行- 表示这是一个新增的文件块
4. 修改内容
diff
+@PACKAGE_INIT@
+
+set(@PROJECT_NAME@_INCLUDE_DIRS ${PACKAGE_PREFIX_DIR}/include ${PACKAGE_PREFIX_DIR}/include/@TARGET_NAME@)
+: 表示新增的行-: 表示删除的行- 无标记: 表示未修改的上下文行
补丁内容详解
sha_ohos.patch 完整内容分析
1. 新增 CMake 包配置文件
diff
diff -aurN sha/cmake/PackageConfig.cmake.in sha_patch/cmake/PackageConfig.cmake.in
--- sha/cmake/PackageConfig.cmake.in 1969-12-31 16:00:00.000000000 -0800
+++ sha_patch/cmake/PackageConfig.cmake.in 2023-09-04 02:06:35.266667302 -0700
@@ -0,0 +1,11 @@
+@PACKAGE_INIT@
+
+set(@PROJECT_NAME@_INCLUDE_DIRS ${PACKAGE_PREFIX_DIR}/include ${PACKAGE_PREFIX_DIR}/include/@TARGET_NAME@)
+
+set(@PROJECT_NAME@_SHARED_LIBRARIES ${PACKAGE_PREFIX_DIR}/lib/lib@TARGET_NAME@.so)
+set(@PROJECT_NAME@_STATIC_LIBRARIES ${PACKAGE_PREFIX_DIR}/lib/lib@TARGET_NAME@_static.a)
+
+include(CMakeFindDependencyMacro)
+
+include(${CMAKE_CURRENT_LIST_DIR}/@TARGET_NAME@Targets.cmake)
+check_required_components(@TARGET_NAME)
文件说明:
PackageConfig.cmake.in 是 CMake 包配置模板文件,用于支持其他项目通过 find_package() 命令查找和使用 SHA 库。
逐行解析:
cmake
@PACKAGE_INIT@
- CMake 宏,初始化包配置
cmake
set(@PROJECT_NAME@_INCLUDE_DIRS ${PACKAGE_PREFIX_DIR}/include ${PACKAGE_PREFIX_DIR}/include/@TARGET_NAME@)
- 设置头文件路径变量
@PROJECT_NAME@将被替换为sha@TARGET_NAME@将被替换为sha- 结果:
set(sha_INCLUDE_DIRS ...)和set(sha_INCLUDE_DIRS .../sha)
cmake
set(@PROJECT_NAME@_SHARED_LIBRARIES ${PACKAGE_PREFIX_DIR}/lib/lib@TARGET_NAME@.so)
set(@PROJECT_NAME@_STATIC_LIBRARIES ${PACKAGE_PREFIX_DIR}/lib/lib@TARGET_NAME@_static.a)
- 设置库文件路径变量
- 结果:
set(sha_SHARED_LIBRARIES .../lib/libsha.so) - 结果:
set(sha_STATIC_LIBRARIES .../lib/libsha_static.a)
cmake
include(CMakeFindDependencyMacro)
- 包含 CMake 查找依赖宏
cmake
include(${CMAKE_CURRENT_LIST_DIR}/@TARGET_NAME@Targets.cmake)
- 包含目标配置文件
- 结果:
include(.../shaTargets.cmake)
cmake
check_required_components(@TARGET_NAME@)
- 检查必需的组件
- 结果:
check_required_components(sha)
使用示例:
cmake
# 在其他项目的 CMakeLists.txt 中
find_package(sha REQUIRED)
# 使用头文件
target_include_directories(myapp PRIVATE ${sha_INCLUDE_DIRS})
# 链接库
target_link_libraries(myapp PRIVATE ${sha_STATIC_LIBRARIES})
2. 新增完整的 CMakeLists.txt
diff
diff -aurN sha/CMakeLists.txt sha_patch/CMakeLists.txt
--- sha/CMakeLists.txt 1969-12-31 16:00:00.000000000 -0800
+++ sha_patch/CMakeLists.txt 2023-09-04 02:59:30.903920444 -0700
@@ -0,0 +1,103 @@
+cmake_minimum_required (VERSION 3.12)
+project(SHA)
+enable_language(C CXX)
+
+set(TARGET_NAME sha)
+set(TARGET_INSTALL_INCLUDEDIR include)
+set(TARGET_INSTALL_BINDIR bin)
+set(TARGET_INSTALL_LIBDIR lib)
+set(TARGET_INSTALL_ELEMENT "")
+
+include_directories(./)
+
+add_library(sha SHARED sha1.c sha2.c hmac.c)
+list(APPEND TARGET_INSTALL_ELEMENT sha)
+
+add_library(sha_static STATIC sha1.c sha2.c hmac.c)
+list(APPEND TARGET_INSTALL_ELEMENT sha_static)
+
+add_executable(hmac hmac_test.c)
+target_link_libraries(hmac PRIVATE sha_static)
+list(APPEND TARGET_INSTALL_ELEMENT hmac)
+
+add_executable(pwd2key pwd2key.c)
+target_link_libraries(pwd2key PRIVATE sha_static)
+target_compile_definitions(pwd2key PRIVATE -DTEST)
+list(APPEND TARGET_INSTALL_ELEMENT pwd2key)
+
+add_executable(sha_test sha_test.c)
+target_link_libraries(sha_test PRIVATE sha_static)
+if(OHOS)
+target_compile_options(sha_test PRIVATE -Wno-format-security)
+endif()
+list(APPEND TARGET_INSTALL_ELEMENT sha_test)
+
+if(WIN32)
+add_executable(sha_time sha_time.c)
+target_link_libraries(sha_time PRIVATE sha)
+list(APPEND TARGET_INSTALL_ELEMENT sha_time)
+endif()
+
+add_executable(sha256sum shasum.c)
+target_link_libraries(sha256sum PRIVATE sha_static)
+list(APPEND TARGET_INSTALL_ELEMENT sha256sum)
+
+enable_testing()
+add_test(NAME test_hmac COMMAND hmac)
+add_test(NAME test_pwd2key COMMAND pwd2key)
+add_test(NAME test_sha COMMAND sha_test)
+if(WIN32)
+add_test(NAME test_time COMMAND sha_time)
+endif()
+
+install(
+ TARGETS
+ ${TARGET_INSTALL_ELEMENT}
+ EXPORT
+ ${TARGET_NAME}
+ PUBLIC_HEADER DESTINATION
+ ${TARGET_INSTALL_INCLUDEDIR}
+ PRIVATE_HEADER DESTINATION
+ ${TARGET_INSTALL_INCLUDEDIR}
+ RUNTIME DESTINATION
+ ${TARGET_INSTALL_BINDIR}
+ LIBRARY DESTINATION
+ ${TARGET_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION
+ ${TARGET_INSTALL_LIBDIR})
+
+file(GLOB ALL_HEAD "*.h")
+install(
+ FILES
+ ${ALL_HEAD}
+ DESTINATION
+ ${TARGET_INSTALL_INCLUDEDIR}/${TARGET_NAME})
+install(
+ EXPORT
+ ${TARGET_NAME}
+ FILE
+ ${TARGET_NAME}Targets.cmake
+ DESTINATION
+ ${TARGET_INSTALL_LIBDIR}/cmake/${TARGET_NAME}
+)
+
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file(
+ ${TARGET_NAME}ConfigVersion.cmake
+ VERSION
+ ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
+ COMPATIBILITY SameMajorVersion
+)
+configure_package_config_file(
+ cmake/PackageConfig.cmake.in ${TARGET_NAME}Config.cmake
+ INSTALL_DESTINATION
+ ${TARGET_INSTALL_LIBDIR}/cmake/${TARGET_NAME}
+)
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}Config.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}ConfigVersion.cmake
+ DESTINATION
+ ${TARGET_INSTALL_LIBDIR}/cmake/${TARGET_NAME}
+)
CMakeLists.txt 详细解析:
第一部分:基本设置
cmake
cmake_minimum_required (VERSION 3.12)
project(SHA)
enable_language(C CXX)
set(TARGET_NAME sha)
set(TARGET_INSTALL_INCLUDEDIR include)
set(TARGET_INSTALL_BINDIR bin)
set(TARGET_INSTALL_LIBDIR lib)
set(TARGET_INSTALL_ELEMENT "")
说明:
- 要求 CMake 3.12 或更高版本
- 定义项目名称为 SHA
- 启用 C 和 C++ 语言支持
- 设置目标名称和安装路径变量
第二部分:包含头文件
cmake
include_directories(./)
说明:
- 将当前目录添加到头文件搜索路径
- 使得源文件可以直接包含项目内的头文件
第三部分:构建库文件
cmake
add_library(sha SHARED sha1.c sha2.c hmac.c)
list(APPEND TARGET_INSTALL_ELEMENT sha)
add_library(sha_static STATIC sha1.c sha2.c hmac.c)
list(APPEND TARGET_INSTALL_ELEMENT sha_static)
关键点:
-
同时构建动态库和静态库
cmakeadd_library(sha SHARED sha1.c sha2.c hmac.c) # 动态库 add_library(sha_static STATIC sha1.c sha2.c hmac.c) # 静态库 -
使用相同的源文件
- 两个库都使用
sha1.c,sha2.c,hmac.c - 避免代码重复
- 便于维护
- 两个库都使用
-
添加到安装列表
cmakelist(APPEND TARGET_INSTALL_ELEMENT sha) list(APPEND TARGET_INSTALL_ELEMENT sha_static)
第四部分:构建可执行文件 ⭐(关键修改)
cmake
add_executable(hmac hmac_test.c)
target_link_libraries(hmac PRIVATE sha_static)
list(APPEND TARGET_INSTALL_ELEMENT hmac)
add_executable(pwd2key pwd2key.c)
target_link_libraries(pwd2key PRIVATE sha_static)
target_compile_definitions(pwd2key PRIVATE -DTEST)
list(APPEND TARGET_INSTALL_ELEMENT pwd2key)
add_executable(sha_test sha_test.c)
target_link_libraries(sha_test PRIVATE sha_static)
if(OHOS)
target_compile_options(sha_test PRIVATE -Wno-format-security)
endif()
list(APPEND TARGET_INSTALL_ELEMENT sha_test)
add_executable(sha256sum shasum.c)
target_link_libraries(sha256sum PRIVATE sha_static)
list(APPEND TARGET_INSTALL_ELEMENT sha256sum)
关键修改详解:
修改 1:静态链接
原始代码(假设):
cmake
target_link_libraries(hmac PRIVATE sha)
修改后:
cmake
target_link_libraries(hmac PRIVATE sha_static)
原因分析:
-
动态链接的问题:
- 运行时需要
libsha.so - 错误:
Error loading shared library libsha.so: No such file or directory - 需要设置
LD_LIBRARY_PATH
- 运行时需要
-
静态链接的优势:
- 可执行文件独立运行
- 无需管理库路径
- 避免版本冲突
- 适合工具程序
-
适用场景:
- HMAC 工具:独立运行的测试工具
- pwd2key 工具:密钥派生工具
- sha_test 工具:测试工具
- sha256sum 工具:校验和工具
修改 2:OpenHarmony 特定配置
cmake
add_executable(sha_test sha_test.c)
target_link_libraries(sha_test PRIVATE sha_static)
if(OHOS)
target_compile_options(sha_test PRIVATE -Wno-format-security)
endif()
list(APPEND TARGET_INSTALL_ELEMENT sha_test)
说明:
if(OHOS): 仅在 OpenHarmony 平台执行-Wno-format-security: 禁用格式安全警告PRIVATE: 编译选项仅对当前目标有效
为什么需要这个选项?
OpenHarmony 的编译器对格式化字符串检查更严格,某些合法的代码可能触发警告。使用 -Wno-format-security 可以避免这些不必要的警告。
第五部分:测试配置
cmake
enable_testing()
add_test(NAME test_hmac COMMAND hmac)
add_test(NAME test_pwd2key COMMAND pwd2key)
add_test(NAME test_sha COMMAND sha_test)
if(WIN32)
add_test(NAME test_time COMMAND sha_time)
endif()
说明:
enable_testing(): 启用 CTest 测试框架add_test(): 定义测试用例NAME: 测试用例名称COMMAND: 要执行的命令
测试内容:
| 测试名称 | 测试内容 | 测试文件 |
|---|---|---|
| test_hmac | HMAC 功能测试 | hmac |
| test_pwd2key | 密钥派生测试 | pwd2key |
| test_sha | SHA 算法测试 | sha_test |
| test_time | 性能测试(仅 Windows) | sha_time |
第六部分:安装规则
cmake
install(
TARGETS
${TARGET_INSTALL_ELEMENT}
EXPORT
${TARGET_NAME}
PUBLIC_HEADER DESTINATION
${TARGET_INSTALL_INCLUDEDIR}
PRIVATE_HEADER DESTINATION
${TARGET_INSTALL_INCLUDEDIR}
RUNTIME DESTINATION
${TARGET_INSTALL_BINDIR}
LIBRARY DESTINATION
${TARGET_INSTALL_LIBDIR}
ARCHIVE DESTINATION
${TARGET_INSTALL_LIBDIR})
安装规则说明:
| 安装类型 | 目标路径 | 说明 |
|---|---|---|
| RUNTIME | bin/ |
可执行文件 |
| LIBRARY | lib/ |
动态库 (.so) |
| ARCHIVE | lib/ |
静态库 (.a) |
| PUBLIC_HEADER | include/ |
公共头文件 |
| PRIVATE_HEADER | include/ |
私有头文件 |
安装后的目录结构:
usr/sha/{arch}/
├── bin/
│ ├── hmac
│ ├── pwd2key
│ ├── sha_test
│ └── sha256sum
├── include/
│ └── sha/
│ ├── sha1.h
│ ├── sha2.h
│ ├── hmac.h
│ └── pwd2key.h
└── lib/
├── libsha.so
├── libsha_static.a
└── cmake/
└── sha/
├── shaConfig.cmake
├── shaConfigVersion.cmake
└── shaTargets.cmake
第七部分:安装头文件
cmake
file(GLOB ALL_HEAD "*.h")
install(
FILES
${ALL_HEAD}
DESTINATION
${TARGET_INSTALL_INCLUDEDIR}/${TARGET_NAME})
说明:
file(GLOB ALL_HEAD "*.h"): 查找所有头文件- 安装到
include/sha/目录下
安装的头文件:
include/sha/
├── sha1.h
├── sha2.h
├── hmac.h
├── pwd2key.h
├── brg_endian.h
├── brg_types.h
└── rdtsc.h
第八部分:生成 CMake 配置文件
cmake
install(
EXPORT
${TARGET_NAME}
FILE
${TARGET_NAME}Targets.cmake
DESTINATION
${TARGET_INSTALL_LIBDIR}/cmake/${TARGET_NAME}
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${TARGET_NAME}ConfigVersion.cmake
VERSION
${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
COMPATIBILITY SameMajorVersion
)
configure_package_config_file(
cmake/PackageConfig.cmake.in ${TARGET_NAME}Config.cmake
INSTALL_DESTINATION
${TARGET_INSTALL_LIBDIR}/cmake/${TARGET_NAME}
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}ConfigVersion.cmake
DESTINATION
${TARGET_INSTALL_LIBDIR}/cmake/${TARGET_NAME}
)
生成的文件:
-
shaTargets.cmake: 目标配置文件
- 定义库的导入目标
- 包含编译选项和链接选项
-
shaConfigVersion.cmake: 版本配置文件
- 定义包的版本信息
- 版本兼容性规则
-
shaConfig.cmake: 主配置文件
- 包含所有必要的信息
- 支持
find_package(sha)命令
使用示例:
cmake
# 在其他项目的 CMakeLists.txt 中
find_package(sha REQUIRED)
# 使用导入目标
target_link_libraries(myapp PRIVATE sha::sha_static)
# 或者使用变量
target_include_directories(myapp PRIVATE ${sha_INCLUDE_DIRS})
target_link_libraries(myapp PRIVATE ${sha_STATIC_LIBRARIES})
补丁应用流程
应用补丁的完整流程
┌─────────────────────────────────────┐
│ 补丁应用流程 │
└─────────────────────────────────────┘
│
▼
┌───────────────────┐
│ 1. 准备原始源码 │
│ git clone │
└───────────────────┘
│
▼
┌───────────────────┐
│ 2. 切换到指定版本 │
│ git reset --hard │
└───────────────────┘
│
▼
┌───────────────────┐
│ 3. 应用补丁 │
│ patch -p1 < │
│ sha_ohos.patch │
└───────────────────┘
│
▼
┌───────────────────┐
│ 4. 验证修改 │
│ 检查文件是否正确 │
└───────────────────┘
│
▼
┌───────────────────┐
│ 5. 构建和测试 │
│ 验证功能正常性 │
└───────────────────┘
在 HPKBUILD 中的应用
bash
prepare() {
if [ "$download_and_patch_flag" == true ]; then
# 步骤 1: 克隆源码
git clone $source $builddir
if [ $? -ne 0 ]; then
return -1
fi
# 步骤 2: 切换到指定版本
cd $builddir
git reset --hard $pkgver
if [ $? -ne 0 ]; then
cd $OLDPWD
return -2
fi
# 步骤 3: 应用补丁
patch -p1 < ../sha_ohos.patch
cd $OLDPWD
# 标记已完成
download_and_patch_flag=false
fi
# 步骤 4: 创建构建目录
mkdir -p $builddir/$ARCH-build
}
手动应用补丁
bash
# 1. 进入源码目录
cd sha-3ee0d88fc4f629b2e084f1b4cbf22cd3597542fb
# 2. 应用补丁
patch -p1 < ../sha_ohos.patch
# 3. 查看修改
git diff
# 4. 如果需要撤销补丁
patch -R -p1 < ../sha_ohos.patch
补丁应用参数说明
bash
patch -p1 < ../sha_ohos.patch
-
-p1: 去除路径的第一层- 补丁文件中的路径:
sha/cmake/PackageConfig.cmake.in - 实际文件路径:
cmake/PackageConfig.cmake.in -p1表示去掉sha/这一层
- 补丁文件中的路径:
-
<: 从标准输入读取补丁 -
../sha_ohos.patch: 补丁文件路径(相对于源码目录)
常见问题处理
问题 1:补丁应用失败
错误信息:
patch: **** Can't rename .git/cmake/PackageConfig.cmake.in to cmake/PackageConfig.cmake.in.orig : No such file or directory
解决方案:
bash
# 清理 git 状态
git clean -fd
# 重新应用补丁
patch -p1 < ../sha_ohos.patch
问题 2:版本不匹配
错误信息:
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED
可能原因:
- 源码版本与补丁版本不匹配
- 文件已被修改
解决方案:
bash
# 检查源码版本
git log --oneline -1
# 确认版本是否匹配
# 如果不匹配,需要重新生成补丁
问题 3:文件已存在
错误信息:
File exists: cmake/PackageConfig.cmake.in
解决方案:
bash
# 删除已存在的文件
rm cmake/PackageConfig.cmake.in
# 重新应用补丁
patch -p1 < ../sha_ohos.patch
关键修改说明
修改 1:静态链接策略 ⭐
原始代码(假设)
cmake
add_executable(hmac hmac_test.c)
target_link_libraries(hmac PRIVATE sha)
修改后
cmake
add_executable(hmac hmac_test.c)
target_link_libraries(hmac PRIVATE sha_static)
影响的文件
hmac→sha_staticpwd2key→sha_staticsha_test→sha_staticsha256sum→sha_static
为什么这样修改?
问题:
Error loading shared library libsha.so: No such file or directory
原因:
- 可执行文件在运行时需要动态链接库
libsha.so不在系统的库搜索路径中- 需要设置
LD_LIBRARY_PATH环境变量
解决:
- 使用静态链接
- 将库代码直接编译到可执行文件中
- 可执行文件独立运行,无需额外配置
优缺点对比
| 特性 | 动态链接 | 静态链接(采用) |
|---|---|---|
| 文件大小 | 小 | 大 |
| 内存占用 | 低(多进程共享) | 高 |
| 部署复杂度 | 高 | 低 |
| 运行时依赖 | 需要库文件 | 无 |
| 更新便利性 | 高 | 低 |
| 适用场景 | 系统库、频繁更新的库 | 工具程序、独立应用 |
选择静态链接的理由
-
SHA 库体积小
- 源代码文件少
- 编译后的库文件不大
- 静态链接增加的体积可忽略
-
简化部署
- 不需要管理库路径
- 不需要设置环境变量
- 避免版本冲突问题
-
适合工具程序
- HMAC、pwd2key 等是独立工具
- 通常单独运行
- 不需要共享库的优势
-
提高可靠性
- 减少运行时错误
- 避免库版本不匹配
- 便于调试和测试
修改 2:OpenHarmony 特定配置
cmake
add_executable(sha_test sha_test.c)
target_link_libraries(sha_test PRIVATE sha_static)
if(OHOS)
target_compile_options(sha_test PRIVATE -Wno-format-security)
endif()
list(APPEND TARGET_INSTALL_ELEMENT sha_test)
为什么需要这个配置?
编译器警告:
warning: format not a string literal and no format arguments [-Wformat-security]
原因:
- OpenHarmony 的 Clang 编译器对格式化字符串检查更严格
- 某些合法的代码可能触发警告
- 不影响功能,但会产生大量警告信息
解决方案:
- 使用
-Wno-format-security禁用此警告 - 仅在 OpenHarmony 平台应用
- 不影响其他平台
修改 3:新增 CMake 配置文件
PackageConfig.cmake.in
作用:
- 支持
find_package(sha)命令 - 提供库的路径和依赖关系
- 便于其他项目集成
使用示例:
cmake
# 在其他项目中
find_package(sha REQUIRED)
# 使用头文件
target_include_directories(myapp PRIVATE ${sha_INCLUDE_DIRS})
# 链接库
target_link_libraries(myapp PRIVATE ${sha_STATIC_LIBRARIES})
修改 4:完整的测试配置
cmake
enable_testing()
add_test(NAME test_hmac COMMAND hmac)
add_test(NAME test_pwd2key COMMAND pwd2key)
add_test(NAME test_sha COMMAND sha_test)
测试内容:
- HMAC 功能测试
- 密钥派生测试
- SHA 算法测试
运行测试:
bash
cd build
ctest
补丁管理最佳实践
1. 补丁文件命名
推荐格式:
{库名}_{平台}_{描述}.patch
示例:
sha_ohos.patch- SHA 库的 OpenHarmony 适配补丁sha_fix_memory_leak.patch- 修复内存泄漏的补丁sha_add_feature.patch- 添加新功能的补丁
2. 补丁文件组织
推荐目录结构:
patches/
├── sha_ohos.patch
├── sha_fix_memory_leak.patch
└── README.md
README.md 内容:
markdown
# 补丁文件说明
## sha_ohos.patch
- 描述:OpenHarmony 平台适配
- 版本:v1.0
- 应用版本:3ee0d88
- 修改内容:
- 静态链接配置
- CMake 配置文件
- OpenHarmony 特定选项
## sha_fix_memory_leak.patch
- 描述:修复内存泄漏问题
- 版本:v1.1
- 应用版本:3ee0d88
- 修改内容:
- 修复 hmac.c 中的内存泄漏
- 添加资源释放代码
3. 补丁版本管理
版本号规则:
v1.0: 初始版本v1.1: 修复版本v2.0: 重大更新
版本兼容性:
sha_ohos_v1.0.patch → 适用于 3ee0d88 版本
sha_ohos_v1.1.patch → 适用于 3ee0d88 版本(修复)
sha_ohos_v2.0.patch → 适用于 abcdef12 版本(重大更新)
4. 补丁测试流程
bash
# 1. 测试补丁应用
cd test_source_dir
patch -p1 < ../sha_ohos.patch
# 2. 验证修改
git diff
# 3. 构建测试
mkdir build && cd build
cmake ..
make
# 4. 功能测试
./bin/sha_test
./bin/hmac
# 5. 清理
cd ..
rm -rf build
patch -R -p1 < ../sha_ohos.patch
5. 补丁生成方法
方法 1:使用 git diff
bash
# 1. 克隆原始仓库
git clone https://github.com/BrianGladman/sha.git sha_orig
# 2. 克隆修改后的仓库
git clone https://github.com/yourname/sha.git sha_mod
# 3. 生成补丁
git diff sha_orig sha_mod > sha_ohos.patch
方法 2:使用 diff 命令
bash
# 生成补丁
diff -aurN sha_orig sha_mod > sha_ohos.patch
方法 3:使用 git format-patch
bash
# 在修改后的仓库中
git format-patch -1 HEAD > sha_ohos.patch
6. 补丁审查清单
在应用补丁前,检查以下内容:
- 补丁格式正确
- 版本信息完整
- 修改说明清晰
- 不包含敏感信息
- 测试通过
- 文档更新
常见问题
Q1: 如何撤销已应用的补丁?
解决方案:
bash
# 方法 1:使用 patch -R
patch -R -p1 < ../sha_ohos.patch
# 方法 2:使用 git(如果使用 git 管理)
git checkout .
# 方法 3:手动删除修改的文件
rm CMakeLists.txt cmake/PackageConfig.cmake.in
Q2: 补丁应用后如何验证修改?
解决方案:
bash
# 查看修改的文件
git status
# 查看具体修改
git diff CMakeLists.txt
# 查看新增的文件
git ls-files --others --exclude-standard
Q3: 如何修改补丁文件?
解决方案:
bash
# 1. 撤销补丁
patch -R -p1 < ../sha_ohos.patch
# 2. 手动修改代码
# 编辑需要修改的文件
# 3. 重新生成补丁
git diff > sha_ohos_new.patch
# 4. 替换原补丁
mv sha_ohos_new.patch sha_ohos.patch
Q4: 补丁文件太大怎么办?
解决方案:
bash
# 1. 检查补丁内容
head -50 sha_ohos.patch
# 2. 排除不必要的文件
# 在生成补丁时使用 .gitignore
# 3. 分离补丁
# 将不同功能的修改分成多个补丁文件
Q5: 如何处理补丁冲突?
解决方案:
bash
# 1. 应用补丁时显示冲突
patch -p1 < ../sha_ohos.patch
# 2. 手动解决冲突
# 编辑标记为冲突的文件
# 3. 标记为已解决
patch -p1 < ../sha_ohos.patch
# 4. 验证修改
git diff
Q6: 补丁文件包含二进制文件怎么办?
解决方案:
bash
# 1. 使用 git binary diff
git diff --binary > sha_ohos.patch
# 2. 使用 xxd 转换
xxd -b binary_file > binary_file.hex
# 3. 在补丁中包含转换后的文件
# 应用时再转换回来
Q7: 如何确保补丁可重现?
解决方案:
bash
# 1. 记录补丁生成环境
echo "OS: $(uname -s)" >> sha_ohos.patch.meta
echo "Patch version: v1.0" >> sha_ohos.patch.meta
echo "Source version: 3ee0d88" >> sha_ohos.patch.meta
# 2. 记录测试结果
echo "Test status: PASSED" >> sha_ohos.patch.meta
echo "Test date: $(date)" >> sha_ohos.patch.meta
Q8: 补丁文件的安全性如何保证?
解决方案:
-
使用 SHA512 校验
bashsha512sum sha_ohos.patch > sha_ohos.patch.sha512 -
使用 GPG 签名
bashgpg --detach-sign --armor sha_ohos.patch -
验证补丁
bash# 验证校验和 sha512sum -c sha_ohos.patch.sha512 # 验证签名 gpg --verify sha_ohos.patch.asc
总结
sha_ohos.patch 是 SHA 库适配 OpenHarmony 平台的核心文件,它记录了所有必要的代码修改。通过本文档的详细解析,我们了解了:
核心要点
- 补丁文件格式:标准的 unified diff 格式
- 补丁内容:CMake 配置、静态链接、OpenHarmony 特定选项
- 关键修改:静态链接解决动态库问题
- 应用流程:从源码获取到补丁应用的完整步骤
- 最佳实践:补丁管理和维护的经验
技术要点
- ✅ 静态链接策略避免运行时依赖
- ✅ OpenHarmony 特定配置处理编译警告
- ✅ 完整的 CMake 配置支持跨平台
- ✅ 自动化测试确保功能正确性
实践建议
- 使用补丁管理代码修改
- 保持原始代码完整性
- 详细记录补丁信息和测试结果
- 定期更新和维护补丁文件
通过正确使用和管理补丁文件,我们可以高效地进行跨平台适配,同时保持代码的可维护性和可追溯性。
文档版本 : 1.0.0
最后更新: 2026-04-08