diff --git a/bsdiff/BUILD.gn b/bsdiff/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..93f0194fa1d5fcdf8276e4420d3b95202754dd60 --- /dev/null +++ b/bsdiff/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +declare_args() { + enable_bsdiff_test = false +} + +ohos_shared_library("bsdiff_bspatch") { + sources = [ + "bsdiff/bsdiff.c", + "bsdiff/bspatch.c", + ] + + include_dirs = [ "./bsdiff" ] + + part_name = "bsdiff" +} + +ohos_executable("bsdiff_example") { + sources = [ "bsdiff/bsdiff.c" ] + include_dirs = [ + "./bsdiff", + "//third_party/bzip2", + ] + + deps = [ "//third_party/bzip2:libbz2" ] + cflags = [ "-DBSDIFF_EXECUTABLE" ] + + part_name = "bsdiff" +} + +ohos_executable("bspatch_example") { + sources = [ "bsdiff/bspatch.c" ] + include_dirs = [ + "./bsdiff", + "//third_party/bzip2", + ] + + deps = [ "//third_party/bzip2:libbz2" ] + cflags = [ "-DBSPATCH_EXECUTABLE" ] + part_name = "bsdiff" +} + +group("bsdiff") { + deps = [ ":bsdiff_bspatch" ] + if (enable_bsdiff_test) { + deps += [ + ":bsdiff_example", + ":bspatch_example", + ] + } +} diff --git a/bsdiff/README.OpenSource b/bsdiff/README.OpenSource new file mode 100755 index 0000000000000000000000000000000000000000..1256fa9ee6eca763e4ec1ce1c59abf3f5e6cbb7b --- /dev/null +++ b/bsdiff/README.OpenSource @@ -0,0 +1,11 @@ +[ + { + "Name": "bsdiff", + "License": "BSD 2-clause license", + "License File": "LICENSE", + "Version Number": "master", + "Owner": "zhongluping1@huawei.com", + "Upstream URL": "https://github.com/mendsley/bsdiff", + "Description": "bsdiff and bspatch are libraries for building and applying patches to binary files." + } +] diff --git a/bsdiff/README_zh.md b/bsdiff/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..379ed1cc95121e656d9588979d3b853bdc4cc6d8 --- /dev/null +++ b/bsdiff/README_zh.md @@ -0,0 +1,16 @@ +# bisdiff 三方库说明 + +## 功能简介 + +bsdiff是一个提供二进制文件拆分以及合并能力的三方库。 + +## 使用约束 + ++ Rom版本:OpenHarmony3.2 beta3 ++ 三方库版本:master ++ 当前适配的功能:实现文件的拆分以及合并功能。 ++ License:[BSD 2-clause license](https://github.com/mendsley/bsdiff/blob/master/LICENSE) + +## 集成方式 + ++ [系统Rom包集成](docs/rom_integrate.md) diff --git a/bsdiff/bundle.json b/bsdiff/bundle.json new file mode 100755 index 0000000000000000000000000000000000000000..985a97ddd6caa665a053f4ff33116eb9ac2f51bb --- /dev/null +++ b/bsdiff/bundle.json @@ -0,0 +1,30 @@ +{ + "name": "@ohos/bsdiff", + "description": "bsdiff and bspatch are libraries for building and applying patches to binary files.", + "version": "v4.3", + "license": "BSD 2-clause license", + "publishAs": "code-segment", + "segment": { + "destPath": "third_party/bsdiff" + }, + "dirs": {}, + "scripts": {}, + "component": { + "name": "bsdiff", + "subsystem": "", + "syscap": [], + "features": [], + "adapted_system_type": [], + "rom": "", + "ram": "", + "deps": { + "components": [], + "third_party": [] + }, + "build": { + "sub_component": ["//third_party/bsdiff:bsdiff"], + "inner_kits": [], + "test": [] + } + } +} \ No newline at end of file diff --git a/bsdiff/docs/rom_integrate.md b/bsdiff/docs/rom_integrate.md new file mode 100755 index 0000000000000000000000000000000000000000..41adb5581764f1cc31bf7978c90f97ea4119646d --- /dev/null +++ b/bsdiff/docs/rom_integrate.md @@ -0,0 +1,147 @@ +# bsdiff 如何集成到系统Rom + +## 准备源码工程 + +本库是基于OpenHarmony 3.2 beta3版本适配,并在润和RK3568开发板上验证的。 +RK3568开发板如何使用可以参照[润和RK3568开发板标准系统快速上手](https://gitee.com/openharmony-sig/knowledge_demo_temp/blob/master/docs/rk3568_helloworld/README.md)。 + +### 准备系统Rom源码 + +源码获取方法请参照:[OpenHarmony3.2beta3源码下载](https://gitee.com/openharmony/docs/blob/OpenHarmony-3.2-Beta5/zh-cn/release-notes/OpenHarmony-v3.2-beta3.md#%E6%BA%90%E7%A0%81%E8%8E%B7%E5%8F%96) + +### 增加构建脚本及配置文件 + +- 下载本仓库代码 + + ```sh + cd ~/ + git clone git@gitee.com:openharmony-sig/tpc_c_cplusplus.git --depth=1 + ``` + +- 仓库代码目录结构说明 + + ```shell + cd ~/tpc_c_cplusplus/bsdiff/ ## 进入到仓库代码库目录 + ``` + + ```sh + bsdiff + |-- BUILD.gn ## Rom版编译构建脚本 + |-- export_api.txt ## bsdiff库对外导出的api接口 + |-- tested_api.txt ## 测试用例已测试的api接口 + |-- bundle.json ## 组件定义文件 + |-- README_zh.md ## bsdiff 说明文档 + |-- README.OpenSource ## bsdiff 开源信息说明文档 + |-- docs ## 存放nsdiff相关文档 + |-- media ## 存放图片的文件夹 + |-- testdata ## 存放测试数据 + |-- run_test.sh ## 测试用例运行脚本,注意:在运行该测试用例时,需要将做拆分与合并的2个测试应用程序放到当前路径下。 + |-- note.txt ## 测试用例文件 + |-- note_new.txt ## 测试用例新文件,与之前文件存在差异,通过测试用例做拆分与合并,最终生成一个新的文件与该文件一致。 + ``` + +- 将本仓库bsdiff文件夹拷贝到OpenHarmony的third_party下 + + ```shell + cp -arf ~/tpc_c_cplusplus/bsdiff ~/OpenHarmony/third_party + ``` + +### 准备三方库源码 + +- 将源码下载到bsdiff目录并将其解压出来。 + + ```shell + cd ~/OpenHarmony/third_party/bsdiff ## 进入到bsdiff目录 + git clone https://github.com/mendsley/bsdiff.git ## 下载三方库 + ``` + +## 系统Rom中引入三方库 + +准备完三方库代码后,我们需要将三方库加入到编译构建体系中。标准系统编译构建可以参考文档[标准系统编译构建指导](https://gitee.com/openharmony/docs/blob/OpenHarmony-3.2-Beta1/zh-cn/device-dev/subsystems/subsys-build-standard-large.md)。 +这里我们三方库默认添加到thirdparty子系统中(详细信息参照文档[如何添加一个三方库到OpenHarmony系统中](https://gitee.com/openharmony-sig/knowledge/blob/master/docs/openharmony_getstarted/port_thirdparty/README.md#%E5%8A%A0%E5%85%A5%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BA%E4%BD%93%E7%B3%BB))。相关配置已在bundle.json中完成,我们只需要在产品定义中添加iconv组件即可。 + +- 在产品配置文件中添加bsdiff的组件 + + 打开//vendor/hihope/rk3568/config.json文件,找到thirdparty子系统并添加bsdiff的组件,如果文件中未指定thirdparty子系统,需要手动将子系统信息加上: + + ```json + { + "subsystem": "thirdparty", + "components": [ + { + "component": "bsdiff", + "features": [] + } + ] + } + ``` + +## 系统Rom中引入三方库测试程序 + +bsdiff原生库提供了测试用例,如需要引入测试程序,在OpenHarmony源码的vendor/hihope/rk3568/config.json文件,对应组件的features中打开编译选项: + +```json +{ + "subsystem": "thirdparty", + "components": [ + { + "component": "bsdiff", + "features": [ "enable_bsdiff_test=true" ] + } + ] +} +``` + +## 编译工程 + +- 选择产品 + + ``` shell + hb set ## 运行hb set后会出现产品列表,在此我们选择 rk3568 + ``` + +- 运行编译 + + ``` shell + hb build --target-cpu arm -f ## --target-cpu arm 编译32位系统(未配置默认编译32位),如果需要编译64位的需要改为--target-cpu arm64; -f 全量编译,不加-f则为增量编译。每次设置完产品后建议进行全量编译。 + ``` + +- 正常编译完后会在out/rk3568/packages/phone/system/bin下生成bsdiff_example和bspatch_example2个测试用例以及在out/rk3568/packages/phone/system/lib下生成libbsdiff_bspatch.z.so。 + +## 安装应用程序 + +将编译生成的库和测试文件放到板子上运行,为避免每次将文件推入设备都烧录整个镜像,我们使用hdc_std工具将文件推到开发板上。 + +- 通过源码编译生成hdc_std工具 + + ```shell + hb set # 源码根目录下使用hb set 选择产品ohos-sdk + hb build # 最后工具编译出来在out/sdk/ohos-sdk/windows/toolchains/hdc_std.exe + ``` + +- 将工具拷贝到Windows,可以为工具目录配置环境变量,也可以在工具所在目录打开windows命令 +- 将原生库测试需要的所有文件打包成bsdiff.tar,并拷贝到windows下 +- 将文件推送到开发板 ,具体步骤如下: + + ```shell + hdc_std.exe file send bsdiff.tar /data/ ## 推送文件到开发板系统的data目录 + hdc_std.exe shell + cd /data/ + tar -xvf bsdiff.tar ## 解压文件包 + cd bsdiff + cp libbsdiff_bspatch.z.so /lib/ ## 将库文件拷贝到系统lib目录 + ``` + +## 运行效果 + +运行测试脚本`./run_test.sh ohos`,测试结果如下图所示: + +![result](../media/ohos_result.png) + +## 参考资料 + +- [润和RK3568开发板标准系统快速上手](https://gitee.com/openharmony-sig/knowledge_demo_temp/blob/master/docs/rk3568_helloworld/README.md)。 +- [如何为三方库组件中添加一个三方库](https://gitee.com/openharmony-sig/knowledge/blob/master/docs/openharmony_getstarted/port_thirdparty/README.md)。 +- [OpenHarmony3.2beta3介绍](https://gitee.com/openharmony/docs/blob/OpenHarmony-3.2-Beta5/zh-cn/release-notes/OpenHarmony-v3.2-beta3.md)。 +- [OpenHarmony三方库组织地址](https://gitee.com/openharmony-tpc)。 +- [知识体系](https://gitee.com/openharmony-sig/knowledge)。 diff --git a/bsdiff/export_api.txt b/bsdiff/export_api.txt new file mode 100755 index 0000000000000000000000000000000000000000..557776c85ca088a5f3f5f7f129cf60919404b58b --- /dev/null +++ b/bsdiff/export_api.txt @@ -0,0 +1,2 @@ +int bsdiff(const uint8_t* old, int64_t oldsize, const uint8_t* new, int64_t newsize, struct bsdiff_stream* stream); +int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, struct bspatch_stream* stream); diff --git a/bsdiff/media/ohos_result.png b/bsdiff/media/ohos_result.png new file mode 100755 index 0000000000000000000000000000000000000000..b50cab0b4d851d04f549f23f90c58410a67989c7 Binary files /dev/null and b/bsdiff/media/ohos_result.png differ diff --git a/bsdiff/testdata/note.txt b/bsdiff/testdata/note.txt new file mode 100755 index 0000000000000000000000000000000000000000..48778cbcfa5178b2ef27b1e2619a920779e4ac1c --- /dev/null +++ b/bsdiff/testdata/note.txt @@ -0,0 +1,13 @@ +Overview +There are two separate libraries in the project, bsdiff and bspatch. Each are self contained in bsdiff.c and bspatch.c The easiest way to integrate is to simply copy the c file to your source folder and build it. + +The overarching goal was to modify the original bsdiff/bspatch code from Colin and eliminate external dependencies and provide a simple interface to the core functionality. + +I've exposed relevant functions via the _stream classes. The only external dependency not exposed is memcmp in bsdiff. + +This library generates patches that are not compatible with the original bsdiff tool. The incompatibilities were motivated by the patching needs for the game AirMech https://www.carbongames.com and the following requirements: + +1. Eliminate/minimize any seek operations when applying patches +2. Eliminate any required disk I/O and support embedded streams +3. Ability to easily embed the routines as a library instead of an external binary +4. Compile+run on all platforms we use to build the game (Windows, Linux, NaCl, OSX) \ No newline at end of file diff --git a/bsdiff/testdata/note_new.txt b/bsdiff/testdata/note_new.txt new file mode 100755 index 0000000000000000000000000000000000000000..1093e10ae04b57ac7860d36d0e51d6196b9e21f0 --- /dev/null +++ b/bsdiff/testdata/note_new.txt @@ -0,0 +1,19 @@ +License +Copyright 2003-2005 Colin Percival +Copyright 2012 Matthew Endsley + +This project is governed by the BSD 2-clause license. For details see the file titled LICENSE in the project root folder. + +Overview +There are two separate libraries in the project, bsdiff and bspatch. Each are self contained in bsdiff.c and bspatch.c The easiest way to integrate is to simply copy the c file to your source folder and build it. + +The overarching goal was to modify the original bsdiff/bspatch code from Colin and eliminate external dependencies and provide a simple interface to the core functionality. + +I've exposed relevant functions via the _stream classes. The only external dependency not exposed is memcmp in bsdiff. + +This library generates patches that are not compatible with the original bsdiff tool. The incompatibilities were motivated by the patching needs for the game AirMech https://www.carbongames.com and the following requirements: + +1. Eliminate/minimize any seek operations when applying patches +2. Eliminate any required disk I/O and support embedded streams +3. Ability to easily embed the routines as a library instead of an external binary +4. Compile+run on all platforms we use to build the game (Windows, Linux, NaCl, OSX) \ No newline at end of file diff --git a/bsdiff/testdata/run_test.sh b/bsdiff/testdata/run_test.sh new file mode 100755 index 0000000000000000000000000000000000000000..ccd219c50a1181e0956d1951cb543901b70a9d6a --- /dev/null +++ b/bsdiff/testdata/run_test.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +ERROR_MSG="run bsdiff demo failed!" +SUCCESS_MSG="run bsdiff demo over!!" + +BSDIFF=bsdiff +BSPATCH=bspatch +OLD_FILE=note.txt +DIFF_NEW_FILE=note_new.txt +PATCH_FILE=note.patch +PATCH_NEW_FILE=note_news.txt +MD5_CMD=md5sum + +if [[ ! -z "$1" ]] && [[ $1 == "linux" ]]; then +TEST_RESULT_FILE=test_result_linux.txt +else +TEST_RESULT_FILE=test_result_ohos.txt +BSDIFF=bsdiff_example +BSPATCH=bspatch_example +fi + +echo "" +echo "bsdiff demo run notice:" +echo "the demo file[$BSDIFF/$BSPATCH] &&" +echo "the test file[note.txt/note_new.txt]" +echo "must be setted the same folder with $0" +echo "" + +if [[ ! -f "$BSDIFF" ]] || [[ ! -f "$BSPATCH" ]]; then + echo "no test demo file!" + echo $ERROR_MSG > $TEST_RESULT_FILE + exit 1 +fi + +if [[ ! -f "$OLD_FILE" ]] || [[ ! -f "$DIFF_NEW_FILE" ]]; then + echo "this test demo need a old file(note.txt) and a new file(note_new.txt)!" + echo $ERROR_MSG > $TEST_RESULT_FILE + exit 1 +fi + +echo "start run bsdiff test" > $TEST_RESULT_FILE +./$BSDIFF $OLD_FILE $DIFF_NEW_FILE $PATCH_FILE + +if [ $? -ne 0 ]; then + echo "run bsdiff test failed!" >> $TEST_RESULT_FILE + echo $ERROR_MSG >> $TEST_RESULT_FILE + exit 1 +fi +echo "run bsdiff test success!" >> $TEST_RESULT_FILE +echo "" >> $TEST_RESULT_FILE + +echo "start run bspatch test" >> $TEST_RESULT_FILE +./$BSPATCH $OLD_FILE $PATCH_NEW_FILE $PATCH_FILE +if [[ $? -ne 0 ]] || [[ ! -f "$PATCH_NEW_FILE" ]]; then + echo "run bspatch test failed!" >> $TEST_RESULT_FILE + echo $ERROR_MSG >> $TEST_RESULT_FILE + exit 1 +fi +echo "run bspatch test success!" >> $TEST_RESULT_FILE +echo "" >> $TEST_RESULT_FILE + +echo "start compare diff new file and patch new file:" >> $TEST_RESULT_FILE +MD5_OLD=`$MD5_CMD $DIFF_NEW_FILE` +MD5_OLD=${MD5_OLD:0:32} +echo "$MD5_OLD" >> $TEST_RESULT_FILE +MD5_NEW=`$MD5_CMD $DIFF_NEW_FILE` +MD5_NEW=${MD5_NEW:0:32} +echo "$MD5_NEW" >> $TEST_RESULT_FILE + +if [ "$MD5_OLD" = "$MD5_NEW" ]; then + echo "check MD5 success" >> $TEST_RESULT_FILE +else + echo "check MD5 failed" >> $TEST_RESULT_FILE +fi +echo "" >> $TEST_RESULT_FILE +echo "#########################" >> $TEST_RESULT_FILE +echo $SUCCESS_MSG >> $TEST_RESULT_FILE +echo "#########################" >> $TEST_RESULT_FILE +echo "" >> $TEST_RESULT_FILE + +cat $TEST_RESULT_FILE + +#eof + diff --git a/bsdiff/tested_api.txt b/bsdiff/tested_api.txt new file mode 100755 index 0000000000000000000000000000000000000000..557776c85ca088a5f3f5f7f129cf60919404b58b --- /dev/null +++ b/bsdiff/tested_api.txt @@ -0,0 +1,2 @@ +int bsdiff(const uint8_t* old, int64_t oldsize, const uint8_t* new, int64_t newsize, struct bsdiff_stream* stream); +int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, struct bspatch_stream* stream);