蓝香蕉代码 |【鸿蒙命令行 hdc/bash/hnpcli】
升级的框架,其中有部分库已经疏于维护或其他原因,不足以满足使用,在适配这三个命令的过程中,我们对框架进行了又一次的改造,这次调整了依赖顺序,优先依赖outerrepo中引入的库(这部分库至少我会在长期进行编译验证,确保编译时成功的)在构建hnpcli命令前,首先是找到源码,这是个头疼的问题,我尽管使用了很多次,却并不知道他的源码在哪里,迫不得已重新下载了OpenHarmony的全量源码后,通过检索
鸿蒙开发命令
上次介绍了lycium_plusplus项目,用于C/C++库的开发,同时也简单展示了tree命令在迁移到该项目后的适配方式,在框架中,我们频繁用到了cmake、make等编译框架相关的工具链,这些工具链前期也在鸿蒙电脑上完成了适配,考虑了下,lycium++可能已经基本具备在鸿蒙电脑上进行C/C++代码编译的基本条件,重新梳理后,我们的项目中前期已经预埋了在鸿蒙电脑上编译的分支,这次想想,一次性把几个重大阻碍进行了适配;
bash鸿蒙电脑最新的版本打开终端后,提供了一个zsh的解释器,zsh大名鼎鼎,但对于广泛的bash脚本的兼容性,并不是想想的那么完美,于是引入一个bash显得还是很有必要性的hnpcli我们在鸿蒙电脑上发布命令行的方式仍然以DevBox + hnp为主,因此hnpcli打包工具也是必要的hdchdc作为OpenHarmony官方的开源设备调试器,没有当然不行
基于这三个场景,最近几天将这些命令进行了适配:
框架的改造
由于我们是基于tpc_c_cplusplus升级的框架,其中有部分库已经疏于维护或其他原因,不足以满足使用,在适配这三个命令的过程中,我们对框架进行了又一次的改造,这次调整了依赖顺序,优先依赖outerrepo中引入的库(这部分库至少我会在长期进行编译验证,确保编译时成功的)
此时,在HPKBUILD框架中,依赖的顺序变成了 outer > thirdparty > community,方便我们在处理一些疏于维护的库时,可以自行引入
hnpcli
hnpcli是一个制作OpenHarmony Native package(hnp)的命令行工具,主要在我们框架中承担打包xxx.hnp的动作,这个命令如何编译这里就不再赘述,直接按照代码仓的介绍就可以hnpcli,这里重点讲讲这个命令适配时,都做了什么
源码获取
在构建hnpcli命令前,首先是找到源码,这是个头疼的问题,我尽管使用了很多次,却并不知道他的源码在哪里,迫不得已重新下载了OpenHarmony的全量源码后,通过检索hnpcli的方式找到了代码仓,其位于startup_appspawn中,appspawn官方名称为应用孵化器部件,这时候也就理解了,hnp作为应用的一部分理应归属这里

找到hnp的目录service/hnp,readme也详细介绍了native软件包开发的指南,这也是我们前期在DevBox中新增和发布命令的主要来源

一切都对上了,接下来就完整的了解hnpcli如何构建
理解和编译
在service/hnp/BUILD.gn构建文件中,存放着我们找到的hnpcli的可执行文件构建信息:
ohos_executable("hnpcli") {
include_dirs = [
"pack/include",
"base",
]
sources = [
"${appspawn_path}/service/hnp/base/hnp_file.c",
"${appspawn_path}/service/hnp/base/hnp_json.c",
"${appspawn_path}/service/hnp/base/hnp_log.c",
"${appspawn_path}/service/hnp/base/hnp_zip.c",
"${appspawn_path}/service/hnp/hnpcli_main.c",
"${appspawn_path}/service/hnp/pack/src/hnp_pack.c",
]
configs = []
cflags = []
defines = [ "HNP_CLI" ]
external_deps = [
"bounds_checking_function:libsec_static",
"cJSON:cjson_static",
"zlib:libz",
]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
这里可以看到,hnpcli的源码非常少,依赖也相对简单,bounds_checking_function + cJSON + zlib就是其全部依赖,至此,快速完成hnpcli的可能性极大的提高了,同时也看出,hnpcli主要是用过json进行配置解析,然后进行归档打包的一个工具,并不会非常神秘
首先进行工程改造,我们的编译框架主要使用CMake、Make等编译框架,不太适合完成复刻一次OpenHarmony的GN编译框架(这是一样令人头大的事情,我不愿意为此付出时间)
- 一比一将GN框架修改为CMake框架:由于两个框架间有极大的逻辑相似性,因此改造起来相对轻松
- ohos_executable == add_executable
- target_link_libraries == external_deps
- include_directories == include_dirs
- defines == add_definitions
因此改造后如下:
cmake_minimum_required(VERSION 3.10)
project(hnpcli)
set(CMAKE_C_STANDARD 17)
add_definitions(-DHNP_CLI)
find_library(MYBOUNDS_CHECK libboundscheck.a)
find_library(MYJSON libcjson.a)
find_library(MYZLIB libz_static.a)
find_path(BOUNDS_CHECK_INCLUDE_DIR securec.h)
find_path(CJSON_INCLUDE_DIR cjson/cJSON.h)
find_path(ZLIB_INCLUDE_DIR zlib.h)
message(STATUS "BOUNDS_CHECK library found at: ${MYBOUNDS_CHECK}")
message(STATUS "CJSON library found at: ${MYJSON}")
message(STATUS "ZLIB library found at: ${MYZLIB}")
message(STATUS "BOUNDS_CHECK_INCLUDE_DIR library found at: ${BOUNDS_CHECK_INCLUDE_DIR}")
message(STATUS "CJSON_INCLUDE_DIR library found at: ${CJSON_INCLUDE_DIR}")
message(STATUS "ZLIB_INCLUDE_DIR library found at: ${ZLIB_INCLUDE_DIR}")
set(STARTUP_APPSPAWN_PATH $ENV{HNPCLI_BUILD_DIR})
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/base
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/pack/src
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/pack/include
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/base
${BOUNDS_CHECK_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR}
${CJSON_INCLUDE_DIR}/cjson
)
add_executable(hnpcli
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/base/hnp_file.c
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/base/hnp_json.c
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/base/hnp_log.c
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/base/hnp_zip.c
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/hnpcli_main.c
${CMAKE_CURRENT_SOURCE_DIR}/${STARTUP_APPSPAWN_PATH}/service/hnp/pack/src/hnp_pack.c
)
target_link_libraries(hnpcli
${MYBOUNDS_CHECK}
${MYJSON}
${MYZLIB}
)
install(TARGETS hnpcli
DESTINATION bin
)
-
有了CMakeLists.txt,紧接着就是写编译命令了,CMake+make+make install的编译手法太过简单,直接参考代码,就不在这里啰嗦,核心是在编译框架下需要
-DCMAKE_PREFIX_PATH="$LYCIUM_ROOT/usr/cJson/$ARCH:$LYCIUM_ROOT/usr/libboundscheck/$ARCH:$LYCIUM_ROOT/usr/zlib_static/$ARCH" \指定目录和库的搜索路径,方便在CMakeLists.txt中指定链接库 -
增加hnp.json
-
执行编译
build.sh hnpcli
小插曲 depends=(“cJson” “libboundscheck” “zlib_static”)
为了编译hnpcli,我依赖的几个库居然不是无法编译,就是不存在,strcpy_s这类安全库函数在win上可以很方便使用,但在鸿蒙中并没有纳入标准库,不得不在框架中引入了libboundscheck,zlib又存在编译问题,cJson居然没有在官方适配清单中看到,只好造一次车轮了
- libboundscheck适配起来超级简单,原有的库已经包含了动态库的Makefile,我又想使用静态库的方式让命令更加稳定,因此仅仅是增加了静态库的Makefile参数,很方便的编译成功
- zlib同样使用静态库的方式,同样参考OpenHarmony/third_party_zlib的
BUILD.gn重写了CMakeLists.txt(这里比较傻的是,由于前面适配的惯性,导致我忽略了源代码仓中天然包含了configure和Makefile的情况,不过也无伤大雅) - cJson没什么好说的,代码仓天然有CMakeLists.txt文件(智商已恢复),直接交叉编译
这几个库也都上传到了社区,合入lycium_plusplus,大家需要可以自行选用
至此,hnpcli的适配工作也完成了,在鸿蒙电脑上尝试,也没有什么问题
hdc与bash
这两个命令其实没有什么特殊的,与hnpcli处理逻辑大同小异
- hdc需要额外适配libusb和openssl,这里我选了
openssl 3.6的版本,如果需要openssl 1_1_1f的,要注意接口不兼容哦 - bash适配起来更加容易,
bash作为最底层的工具,无依赖是其关键要求,这里仍有个小插曲,bash-5.3中仍在使用过期的getwd不安全接口,在muslc中未定义该方法,因此在muslc_gext项目中我们替代实现了他,因此编译过程也是非常顺利
muslc_gext
这个项目本意是把一些大家遇到的在鸿蒙适配过程中不兼容的glibc库接口进行再实现,降低适配难度,避免大家都因同一个接口反复折腾,大家有遇到相关的接口也可以一起共享交流muslc_gext
更多推荐



所有评论(0)