移植案例与原理 - build lite源码分析 之 hb命令__main__.py
hb命令可以通过python pip包管理器进行安装,应该是OpenHarmony Build的缩写,在python包名称是ohos-build。hb作为编译构建子系统提供的命令行,用于编译构建产品、芯片厂商组件或者单个组件。本文,我们来学习hb的源码。
1、hb的安装、卸载与简单介绍
在源码根目录下执行下述命令可以进行安装。
python3 -m pip install --user build/lite
执行hb -h有相关帮助信息,有打印信息即表示安装成功:
usage: -c [-h] [-v] {build,set,env,clean,tool} ...OHOS Build System version 0.4.6positional arguments:{build,set,env,clean,tool}build Build source codeset OHOS build settingsenv Show OHOS build envclean Clean outputtool Call the gn command through the hb tooloptional arguments:-h, --help show this help message and exit-v, --version show program's version number and exit
需要注意的是,需要在OpenHarmony的源代码目录下才能执行hb命令,否则会提示:hb_error: Please call hb utilities inside source root directory
。后文源码分析时,会讲述为啥要在源码目录下才能执行该hb。
卸载方法,执行下述命令即可:
python3 -m pip uninstall ohos-build
另外,需要了解的一个比较好用的命令,如下,可以查看安装的python包的信息:
python3 -m pip show ohos-build
执行后,输出如下信息。比较关键的是,可以知道hb命令对应源文件的安装位置在...lib/python3.8/site-packages
。
。hb命令工具的位置可以通过which hb
来查看。
zhushangyuan@DESKTOP-RPE9R4O:~$ python3 -m pip show ohos-build
Name: ohos-build
Version: 0.4.6
Summary: OHOS build command line tool
Home-page: https://gitee.com/openharmony/build_lite
Author: Huawei
Author-email: contact@openharmony.io
License: Apache 2.0
Location: /home/zhushangyuan/.local/lib/python3.8/site-packages
Requires: kconfiglib, prompt-toolkit, PyYAML, requests
Required-by:
在文件夹...lib/python3.8/site-packages/hb
有3个文件,__init__.py
是空文件表示python模块,__main__.py
是执行入口文件,__entry__.py
事实上并没有使用到。这3个文件和目录build/lite/hb
下的文件是一模一样的。
zhushangyuan@DESKTOP-RPE9R4O:~$ ll /home/zhushangyuan/.local/lib/python3.8/site-packages/hb/
total 20
drwxr-xr-x 3 zhushangyuan zhushangyuan 4096 Oct 25 20:36 ./
drwx------ 33 zhushangyuan zhushangyuan 4096 Oct 25 20:36 ../
-rw-r--r-- 1 zhushangyuan zhushangyuan 3629 Oct 25 20:56 __entry__.py
-rw-r--r-- 1 zhushangyuan zhushangyuan 0 Oct 25 20:36 __init__.py
-rw-r--r-- 1 zhushangyuan zhushangyuan 2204 Oct 25 20:36 __main__.py
2、hb源码分析
通过which hb
来查看hb命令工具的位置,我的环境上,位置为~/.local/bin/hb
,该文件是通过pip安装的,其实是个python文件。我们来查看其文件内容。⑴处导入的main函数来自...lib/python3.8/site-packages/hb/__main__.py
。⑵处sys.argv[0]指的是执行的程序名称,这里等于hb
,该语句表示以-script.pyw
或者.exe
结尾的部分去除,例如,假设sys.argv[0]为test-script.pyw,则替换后的sys.argv[0]为test。使用pip安装的包通常都是这样的写法。
zhushangyuan@DESKTOP-RPE9R4O:~/openharmony$ cat ~/.local/bin/hb#!/usr/bin/python3# -*- coding: utf-8 -*-import reimport sys
⑴ from hb.__main__ import mainif __name__ == '__main__':
⑵ sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])sys.exit(main())
接下来,我们来分析下源文件...lib/python3.8/site-packages/hb/__main__.py
。
zhushangyuan@DESKTOP-RPE9R4O:~/openharmony$ cat /home/zhushangyuan/.local/lib/python3.8/site-packages/hb/__main__.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-#
# 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 os
import sysVERSION = "0.4.6"
# execv execution fragment
EXECV_FRAGMENT = """
import sys
import importlibsys.path.append(sys.argv.pop())
entry = importlib.import_module("__entry__")
sys.exit(entry.main())
"""def find_top():cur_dir = os.getcwd()while cur_dir != "/":hb_internal = os.path.join(cur_dir, 'build/lite/hb_internal')if os.path.exists(hb_internal):return cur_dircur_dir = os.path.dirname(cur_dir)raise Exception("Please call hb utilities inside source root directory")def search(findir, target):for root, dirs, files in os.walk(findir):if target in files:return rootdef main():try:topdir = find_top()except Exception as ex:return print("hb_error: Please call hb utilities inside source root directory")python_base_dir = os.path.join(topdir, 'prebuilts/python')if os.path.exists(python_base_dir):python_dir = search(python_base_dir, 'python3')python_executable = os.path.join(python_dir, 'python3')lite_dir = os.path.join(topdir, 'build/lite')hb_dir = search(lite_dir, '__entry__.py')param_list = ["python3", "-c", EXECV_FRAGMENT]for arg in sys.argv[1:]:param_list.append(arg)param_list.append(hb_dir)os.environ['PATH'] = python_dir + ":" + os.getenv('PATH')os.execv(python_executable, param_list)else:print("please execute build/prebuilts_download.sh")if __name__ == "__main__":sys.exit(main())
2.1、hb/main.py 动态执行python代码片段EXECV_FRAGMENT
python -c
命令可以直接在命令行中调用python代码, 实际上-c
就是command
的意思,就是python -c
可以在命令行中执行python代码, 跟把代码放置在.py
文件中,然后运行这个文件是一样的效果。
__main__.py
文件中会动态执行python代码片段如下,解释下⑴处的代码。当我们导入一个模块时:import XXX,默认情况下python解释器会搜索当前目录、已安装的内置模块和第三方模块,如果都搜索不到,则会报错。
我们的搜索路径存放在sys模块中的path中,sys.path是当前路径的一个列表。[即默认路径可以通过sys.path来打印查看]。当我们要添加自己的引用模块搜索目录时,可以通过list的append方法。sys.argv.pop()表示参数列表中的最后一项,指的是openharmony\build\lite\hb\
目录,下文会详细解释。
⑵处动态导入模块对象,"entry"指的是openharmony\build\lite\hb\__entry__.py
。所以,我们只使用到了openharmony\build\lite\hb\__entry__.py
,而不是使用python3.8/site-packages/hb/__entry__.py.py
。
EXECV_FRAGMENT = """import sysimport importlib⑴ sys.path.append(sys.argv.pop())
⑵ entry = importlib.import_module("__entry__")sys.exit(entry.main())"""
2.2、hb/main.py find_top()函数
find_top()函数用于获取OpenHarmony源代码根目录。⑴处先获取当前工作目录,hb命令在哪个目录下执行,就是当前的工作目录。⑵处开始while循环,结束条件是遍历到系统根目录或者return返回。⑶处判断是否存在目录’build/lite/hb_internal’,如果存在,即可获得OpenHarmony源码根目录。如果不存在,则执行⑷获取上一级目录,继续循环。遍历的目录不存在’build/lite/hb_internal’目录,则抛出异常。从这些源码可知,hb不能在非OpenHarmony源代码目录下执行,但又可以在OpenHarmony源码目录下的任何一个目录执行。
def find_top():
⑴ cur_dir = os.getcwd()
⑵ while cur_dir != "/":hb_internal = os.path.join(cur_dir, 'build/lite/hb_internal')
⑶ if os.path.exists(hb_internal):return cur_dir
⑷ cur_dir = os.path.dirname(cur_dir)raise Exception("Please call hb utilities inside source root directory")
2.3、hb/main.py search()函数
search()函数从指定的目录下查询是否存在指定的文件,如果存在,则返回包含指定文件的目录路径。代码如下,这代码也容易被挑战。对于不存在指定文件的情况下,就没有return语句,这样代码不规范。
def search(findir, target):for root, dirs, files in os.walk(findir):if target in files:return root
2.4、hb/main.py main()函数
接下来,我们来看下main()函数。首先调用find_top()函数获得OpenHarmony源码根目录。⑴处判断是否存在文件’prebuilts/python’,如果不存在则打印,告知开发者需要"please execute build/prebuilts_download.sh"来完成环境准备。⑵处开始,获取4个变量的值,如下表:
变量 | 值 | 说明 |
---|---|---|
python_dir | openharmony/prebuilts/python/linux-x86/3.9.2/bin | 包含python3执行文件的目录 |
python_executable | openharmony/prebuilts/python/linux-x86/3.9.2/bin/python3 | python3执行文件路径 |
lite_dir | openharmony/build/lite | build lite目录 |
hb_dir | openharmony/build/lite/hb | entry.py所在的目录 |
⑶处封装要参数列表,要动态执行的脚本EXECV_FRAGMENT,已经在前文解释。⑷处把命令行执行hb命令时传入的参数,添加到param_list变量,⑸处最后添加的参数是__entry__.py所在的目录。在解释动态执行python代码片段EXECV_FRAGMENT时,提到的sys.argv.pop()
就是刚刚添加的这个目录。接下来,⑹处的代码设置环境变量,然后调用函数os.execv来执行。后文再详细分析__entry__.py。
def main():try:topdir = find_top()except Exception as ex:return print("hb_error: Please call hb utilities inside source root directory")python_base_dir = os.path.join(topdir, 'prebuilts/python')
⑴ if os.path.exists(python_base_dir):
⑵ python_dir = search(python_base_dir, 'python3')python_executable = os.path.join(python_dir, 'python3')lite_dir = os.path.join(topdir, 'build/lite')hb_dir = search(lite_dir, '__entry__.py')
⑶ param_list = ["python3", "-c", EXECV_FRAGMENT]
⑷ for arg in sys.argv[1:]:param_list.append(arg)
⑸ param_list.append(hb_dir)
⑹ os.environ['PATH'] = python_dir + ":" + os.getenv('PATH')os.execv(python_executable, param_list)else:print("please execute build/prebuilts_download.sh")
4、小结
本文介绍了build lite 轻量级编译构建系统hb命令的源码,主要分析了__main__.py文件。
如果大家想更加深入的学习 OpenHarmony(鸿蒙南向) 开发的全栈内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:
OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy
《OpenHarmony源码解析》:https://qr18.cn/CgxrRy
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
系统架构分析:https://qr18.cn/CgxrRy
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……
OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy
OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy
写在最后
- 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:
https://qr21.cn/FV7h05
相关文章:

移植案例与原理 - build lite源码分析 之 hb命令__main__.py
hb命令可以通过python pip包管理器进行安装,应该是OpenHarmony Build的缩写,在python包名称是ohos-build。hb作为编译构建子系统提供的命令行,用于编译构建产品、芯片厂商组件或者单个组件。本文,我们来学习hb的源码。 1、hb的安…...

Leo赠书活动-26期 不同数据库背后的数据存储方案
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 赠书活动专栏 ✨特色专栏:…...

在Windows10中使用Vim
服务器没有图形界面,但是numpy包又需要调用图形界面接口,这样就导致了错误,搞得我只好先回windows开发。看来当年 Ubuntu桌面版也不算是多此一举啊。 这么多ide我还是喜欢vim,因为它真的太简单了。咱们这个老年机启动的也非常快&…...

【Python机器学习实战】 | 基于PCA主成分分析技术读入空气质量监测数据进行数据预处理并计算空气质量综合评测结果
🎩 欢迎来到技术探索的奇幻世界👨💻 📜 个人主页:一伦明悦-CSDN博客 ✍🏻 作者简介: C软件开发、Python机器学习爱好者 🗣️ 互动与支持:💬评论 &…...

学习java第一百零八天
Spring的AOP理解: OOP面向对象,允许开发者定义纵向的关系,但并不适用于定义横向的关系,会导致大量代码的重复,而不利于各个模块的重用。 AOP,一般称为面向切面,作为面向对象的一种补充ÿ…...

Linux通配符总结
Linux通配符总结 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 在Linux系统中,通配符是一种用于匹配文件名或路径名的特殊字符。通过使用通配符&a…...

ffmpeg的安装教程
1.官网下载ffmpeg 进入Download FFmpeg网址,点击下载windows版ffmpeg(点击左下第一个绿色的行) 在release builds第一个绿框里面选择一个版本下载。 2.配置 下载完成后解压该压缩包单击进入ffmpeg\bin,会出现如下界面࿱…...

禅道身份认证绕过漏洞(QVD-2024-15263)复现
禅道项目管理系统在开源版、企业版、旗舰版的部分版本中都存在此安全漏洞。攻击者可利用该漏洞创建任意账号实现未授权登录。 1.漏洞级别 高危 2.漏洞搜索 fofa: title"禅道"3.影响范围 v16.x < 禅道 < v18.12 (开源版) v6.x <…...

深入分析 Android BroadcastReceiver (六)
文章目录 深入分析 Android BroadcastReceiver (六)1. 广播机制的高级优化策略1.1 使用 Sticky Broadcast(粘性广播)示例:粘性广播(过时,不推荐) 1.2 使用 LiveData 和 ViewModel 进行组件通信示例…...

mysql 查询的一般思路
能用单表优先用单表,即便是需要用group by、order by、limit等,效率一般也比多表高 不能用单表时优先用连接,连接是SQL中非常强大的用法,小表驱动大表建立合适索引合理运用连接条件,基本上连接可以解决绝大部分问题。…...

【Web APIs】DOM 文档对象模型 ⑤ ( 获取特殊元素 | 获取 html 元素 | 获取 body 元素 )
文章目录 一、获取特殊元素1、获取 html 元素2、获取 body 元素3、完整代码示例 本博客相关参考文档 : WebAPIs 参考文档 : https://developer.mozilla.org/zh-CN/docs/Web/APIgetElementById 函数参考文档 : https://developer.mozilla.org/zh-CN/docs/Web/API/Document/getE…...

Android11 以Window的视角来看FallbackHome的启动
在WMS中,使用WindowState代表着一个Window并维护着一个Window的"层级树",每个Window需要按照"层级"的规则进行排列。对于FallbackHome,其Window是挂载在home task上,而home task挂载在DefaultTaskDisplayArea…...

9 RestClient客户端操作文档
1. match_all GetMapping("matchAll")public void matchAll() throws IOException {//1. 准备requestSearchRequest request new SearchRequest("hotel");//2. 组织DSL参数request.source().query(QueryBuilders.matchAllQuery());SearchResponse respon…...

『Z-Weekly Feed 08』加密资产观 | FHE应用前景 | OPAL协议
一位机构投资者的加密资产观 作者:Hongbo 01 💡TL;DR 在加密投资领域如何找到真正的“价值”:Crypto 作为一种新兴资产,应该找到一种区别于传统公司股票资产的估值方法,本文重点阐述了加密货币作为新的资产类型与传统资…...

酒店预定系统
酒店预定系统本身设计过程中会遇到售卖系统两个常见问题,第一个同一个房间同一日期被多个订单预定,或者预定和库存数据不一致,这些都会涉及到金钱,需要在系统涉及是被重点考虑。 问题1:同一个房间同一个日期被多个订单预定 酒店…...

Redis的实战常用一、验证码登录(解决session共享问题)(思路、意识)
一、基于session实现登录功能 第一步:发送验证码: 用户在提交手机号后,会校验手机号是否合法: 如果不合法,则要求用户重新输入手机号如果手机号合法,后台此时生成对应的验证码,同时将验证码进行…...

基于Spring Boot的智能分析平台
项目介绍: 智能分析平台实现了用户导入需要分析的原始数据集后,利用AI自动生成可视化图表和分析结论,改善了传统BI系统需要用户具备相关数据分析技能的问题。该项目使用到的技术是SSMSpring Boot、redis、rabbitMq、mysql等。在项目中&#…...

HTML(13)——显示模式
目录 显示模式 块级元素 行内元素 行内块元素 转换显示模式 显示模式:标签的显示方式 作用:布局网页时,根据标签的显示模式选择合适的标签摆放内容 显示模式 块级元素 独占一行宽度默认为父级的100%添加宽高属性生效 行内元素 …...

【Spring】Spring Boot 快速入门
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…...

Go自定义数据的序列化流程
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

贪心算法练习题(2024/6/18)
什么是贪心 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 贪心算法一般分为如下四步: 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解 1分发饼干 假设你是一位很棒的家长,…...

4.1 四个子空间的正交性
一、四个子空间的正交性 如果两个向量的点积为零,则两个向量正交: v ⋅ w v T w 0 \boldsymbol v\cdot\boldsymbol w\boldsymbol v^T\boldsymbol w0 v⋅wvTw0。本章着眼于正交子空间、正交基和正交矩阵。两个子空间的中的向量,一组基中的向…...

RabbitMQ实践——使用WebFlux响应式方式实时返回队列中消息
大纲 Pom.xml监听队列实时返回消息测试完整代码工程代码 在之前的案例中,我们在管理后台收发消息都是通过短连接的形式。本文我们将探索对队列中消息的实时读取,并通过流式数据返回给客户端。 webflux是反应式Web框架,客户端可以通过一个长连…...

SpringBoot前后端传递数据时常用的JSON格式数据是什么?【讲解JSON概念、语法、以及Java对象互转】
SpringBoot前后端传递数据时常用的JSON格式数据是什么? JSON概念JSON语法JSON的两种结构:JSON字符串和Java对象互转:objectMapper.writeValueAsString(person);objectMapper.readValue(jsonStr,Person.class); 在SpringMVC框架中,…...

mysql学习——SQL中的DQL和DCL
SQL中的DQL和DCL DQL基本查询条件查询聚合函数分组查询排序查询分页查询 DCL管理用户权限控制 学习黑马MySQL课程,记录笔记,用于复习。 DQL DQL英文全称是Data Query Language(数据查询语言),数据查询语言,用来查询数据库中表的记…...

windows系统上nginx搭建文件共享
1、下载windows版nginx 下载地址 2、配置nginx 编辑nginx.conf配置文件 在http模块下添加这个参数 underscores_in_headers on;#修改location内容,共享哪个文件夹,就写哪个文件夹,最后一定要跟上/,否则无法访问 location / {…...

星闪指向遥控,做家电交互的破壁人
“面壁者罗辑,我是你的破壁人。” 科幻小说《三体》中,当人类的基础科学被三体人封锁,变得停步不前,人类启动了自救的面壁计划,通过一次又一次破壁,找到战胜三体人的办法。 现实中,有一点已经成…...

SpringBoot使用AutoConfigure实现依赖库自动导入配置
我们知道导入配置有两种,一种是Value,一种是ConfigurationProperties,将对应的类标记为Component即可导入。但是被注解标识的类创建Bean有一个前提,只对启动类所在的包路径下的所有带有Component等注解的类才会创建Bean。如果我们…...

QT中利用动画弄一个侧边栏窗口,以及贴条效果
1、效果 2、关键代码 void Widget::on_sliderBtn_clicked() {m_sliderWidget->show();QPropertyAnimation* animation = new QPropertyAnimation(m...

win10免安装配置MySQL8.4.0
注:此教程基于win10 22H2 版本 1、下载最新版本MySQL压缩包 下载链接:MySQL官网下载地址 点击第二行的 ZIP Archive 后面的Download(当前时间2024-06-19最新版本是8.4.0) 2、解压并添加配置文件 下载完毕后,解压缩…...