news 2026/8/14 21:20:28

蓝香蕉代码 |【鸿蒙命令行 hdc/bash/hnpcli】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
蓝香蕉代码 |【鸿蒙命令行 hdc/bash/hnpcli】

鸿蒙开发命令

上次介绍了lycium_plusplus项目,用于C/C++库的开发,同时也简单展示了tree命令在迁移到该项目后的适配方式,在框架中,我们频繁用到了cmakemake等编译框架相关的工具链,这些工具链前期也在鸿蒙电脑上完成了适配,考虑了下,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=truesubsystem_name="${subsystem_name}"part_name="${part_name}"}

这里可以看到,hnpcli的源码非常少,依赖也相对简单,bounds_checking_function+cJSON+zlib就是其全部依赖,至此,快速完成hnpcli的可能性极大的提高了,同时也看出,hnpcli主要是用过json进行配置解析,然后进行归档打包的一个工具,并不会非常神秘

首先进行工程改造,我们的编译框架主要使用CMake、Make等编译框架,不太适合完成复刻一次OpenHarmony的GN编译框架(这是一样令人头大的事情,我不愿意为此付出时间)

  1. 一比一将GN框架修改为CMake框架:由于两个框架间有极大的逻辑相似性,因此改造起来相对轻松
  • ohos_executable == add_executable
  • target_link_libraries == external_deps
  • include_directories == include_dirs
  • defines == add_definitions

因此改造后如下:

cmake_minimum_required(VERSION3.10) project(hnpcli) set(CMAKE_C_STANDARD17) 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 )
  1. 有了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中指定链接库

  2. 增加hnp.json

  3. 执行编译

    build.shhnpcli

    小插曲 depends=("cJson" "libboundscheck" "zlib_static")

    为了编译hnpcli,我依赖的几个库居然不是无法编译,就是不存在,strcpy_s这类安全库函数在win上可以很方便使用,但在鸿蒙中并没有纳入标准库,不得不在框架中引入了libboundscheck,zlib又存在编译问题,cJson居然没有在官方适配清单中看到,只好造一次车轮了

  • libboundscheck适配起来超级简单,原有的库已经包含了动态库的Makefile,我又想使用静态库的方式让命令更加稳定,因此仅仅是增加了静态库的Makefile参数,很方便的编译成功
  • zlib同样使用静态库的方式,同样参考OpenHarmony/third_party_zlibBUILD.gn重写了CMakeLists.txt(这里比较傻的是,由于前面适配的惯性,导致我忽略了源代码仓中天然包含了configure和Makefile的情况,不过也无伤大雅)
  • cJson没什么好说的,代码仓天然有CMakeLists.txt文件(智商已恢复),直接交叉编译

这几个库也都上传到了社区,合入lycium_plusplus,大家需要可以自行选用

至此,hnpcli的适配工作也完成了,在鸿蒙电脑上尝试,也没有什么问题

hdcbash

这两个命令其实没有什么特殊的,与hnpcli处理逻辑大同小异

  • hdc需要额外适配libusbopenssl,这里我选了openssl 3.6的版本,如果需要openssl 1_1_1f的,要注意接口不兼容哦
  • bash适配起来更加容易,bash作为最底层的工具,无依赖是其关键要求,这里仍有个小插曲,bash3.6中仍在使用过期的getwd不安全接口,在muslc中未定义该方法,因此在muslc_gext项目中我们替代实现了他,因此编译过程也是非常顺利

muslc_gext

这个项目本意是把一些大家遇到的在鸿蒙适配过程中不兼容的glibc库接口进行再实现,降低适配难度,避免大家都因同一个接口反复折腾,大家有遇到相关的接口也可以一起共享交流muslc_gext

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/1 13:51:20

基于Dify的时间管理建议生成系统设计

基于Dify的时间管理建议生成系统设计 在知识工作者日均面临超过100条任务提醒的今天,时间管理早已不再是简单的“列清单”或“设闹钟”。真正棘手的问题是:当多个高优先级任务同时逼近截止时间,而个人又存在拖延倾向时,系统能否像…

作者头像 李华
网站建设 2026/7/29 9:54:09

47、深入探索 SharePoint 2010 业务连接服务

深入探索 SharePoint 2010 业务连接服务 在当今数字化办公环境中,企业数据分散在不同系统和数据库中是常见的情况,这给数据整合和利用带来了挑战。SharePoint 2010 的业务连接服务(Business Connectivity Services,简称 BCS)为解决这一问题提供了有效的途径。它能够将各种…

作者头像 李华
网站建设 2026/7/26 16:12:34

51、SharePoint 搜索功能全解析

SharePoint 搜索功能全解析 在当今数字化办公环境中,高效的搜索功能对于快速获取信息至关重要。SharePoint 提供了强大而灵活的搜索能力,下面将详细介绍其搜索的相关概念、操作及配置方法。 1. 搜索基础概念 查询(Query) :从索引文件中检索数据时,需运行搜索查询。通…

作者头像 李华
网站建设 2026/8/6 4:00:18

23、系统模型:用户界面流与显示 - 动作 - 响应模型解析

系统模型:用户界面流与显示 - 动作 - 响应模型解析 在软件开发中,用户界面(UI)的设计和规划至关重要,它直接影响着软件的可用性和用户体验。本文将深入探讨用户界面流(UI Flow)和显示 - 动作 - 响应(DAR)模型,包括常见错误、相关模型以及如何创建这些模型。 一、用…

作者头像 李华
网站建设 2026/7/31 13:21:53

24、软件系统建模:DAR 模型与决策表的深度解析

软件系统建模:DAR 模型与决策表的深度解析 在软件开发中,准确地捕捉和表达用户界面(UI)需求以及处理复杂的决策逻辑是至关重要的。本文将深入探讨两种有效的系统建模方法:显示 - 动作 - 响应(DAR)模型和决策表,介绍它们的原理、应用场景、优缺点以及使用时的注意事项。…

作者头像 李华
网站建设 2026/8/8 3:12:18

25、决策表与决策树:复杂决策的建模利器

决策表与决策树:复杂决策的建模利器 1. 决策表的创建流程 决策表是一种强大的工具,可用于处理复杂的决策场景,使决策过程更加有序和完整。创建决策表一般遵循以下流程: graph LRA[识别条件] --> B[识别选择]B --> C[根据选择标记结果]C --> D[简化表格]D --&g…

作者头像 李华