社区编辑申请
注册/登录
OpenHarmony-3.0 编译构建流程
开发 前端
早就打算研究下OH3.0的编译框架了,最近一直在搞移植,总算有点进展了,抽个空来分析下3.0的编译框架。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言

OpenHarmony-2.0 编译构建流程

早就打算研究下OH3.0的编译框架了,最近一直在搞移植,总算有点进展了,抽个空来分析下3.0的编译框架。大体看了下和2.0的差别不是特别大,OHOS3.0的打包镜像脚本由原来2.0的build\adapter\build_image.sh 全部修改替换为 build\ohos\images\build_image.py 将打包image镜像的部分制作成build_target,以前是通过shell脚本来调用,现在是通过gn和ninja来调用。主要文件在build\ohos\images这个文件夹下。没有修改的部分就不说了,有需要的可以看我之前的帖子 这篇主要说下不一样的地方,看OH3.0是如何将编译好的文件打包成镜像的。

一、增加编译参数

3.0之后在build\build_scripts\build_common.sh 增加了 build_cmd+=" build_target=images",这句的意思约等于在执行默认编译命令 ./build.sh --product-name Hi3516DV300 会有个默认的参数 --build-target images,具体流程是这样的:

  1. build\build_scripts\build_common.sh => build\core\gn\BUILD.gn => build\ohos\images\BUILD.gn 
  2.  
  3. action_with_pydeps("${_platform}_${_image_name}_image") { 
  4.     script = "//build/ohos/images/build_image.py" 
  5.     depfile = "$target_gen_dir/$target_name.d" 
  6.     deps = [ "//build/ohos/packages:${_platform}_install_modules" ] 
  7.  
  8.     image_config_file = 
  9.     "//build/ohos/images/mkimage/${_image_name}_image_conf.txt" 
  10.     output_image_file = "$current_platform_dir/images/${_image_name}.img" 
  11.  
  12.     image_input_path = "$current_platform_dir/${_image_name}" 
  13.     if (_image_name == "userdata") { 
  14.         image_input_path = "$current_platform_dir/data" 
  15.     } 
  16.  
  17.     sources = [ 
  18.         image_config_file, 
  19.         system_module_info_list, 
  20.         system_modules_list, 
  21.     ] 
  22.     outputs = [ output_image_file ] 
  23.     args = [ 
  24.         "--depfile"
  25.         rebase_path(depfile, root_build_dir), 
  26.         "--image-name"
  27.         _image_name, 
  28.         "--input-path"
  29.         rebase_path(image_input_path, root_build_dir), 
  30.         "--image-config-file"
  31.         rebase_path(image_config_file, root_build_dir), 
  32.         "--output-image"
  33.         rebase_path(output_image_file, root_build_dir), 
  34.         "--build-image-tools-path"
  35.         rebase_path(build_image_tools_path, root_build_dir), 
  36.     ] 
  37.     if (sparse_image) { 
  38.         args += [ "--sparse-image" ] 
  39.     } 

通常情况下,gn会使用 action 运行一个脚本来生成一个文件,但是这里使用的是 action_with_pydeps,应该也是内置的目标类型。查看官方手册是这么说明的

Inputs and Depfiles

List all files read (or executed) by an action as inputs.

  • It is not enough to have inputs listed by dependent targets. They must be listed directly by targets that use them, or added by a depfile.
  • Non-system Python imports are inputs! For scripts that import such modules, use action_with_pydeps to ensure all dependent Python files are captured as inputs.

前面还定义了一个image_list,然后使用 foreach 执行 action_with_pydeps,要生成几个img文件,就执行几次action_with_pydeps。

  1. image_list = [ 
  2.   "system"
  3.   "vendor"
  4.   "userdata"
  5.   "updater"
  6. foreach(_image_name, image_list) {... ...} 

二、调用python脚本

既然知道了img镜像是由 build\ohos\images\build_image.py 来创建的,那就来分析下这个python脚本。

  1. if os.path.exists(args.output_image_path): 
  2.         os.remove(args.output_image_path)           # 删除之前生成的镜像文件夹 
  3.     if args.image_name == 'userdata'
  4.         _prepare_userdata(args.input_path)          # 准备好 userdata.img 需要的文件 
  5.     if os.path.isdir(args.input_path): 
  6.         _make_image(args) 
  7.         _dep_files = [] 
  8.         for _root, _, _files in os.walk(args.input_path): 
  9.             for _file in _files: 
  10.                 _dep_files.append(os.path.join(_root, _file)) 
  11.         build_utils.write_depfile(args.depfile, 
  12.                                   args.output_image_path, 
  13.                                   _dep_files, 
  14.                                   add_pydeps=False
  15. =================================================================== 
  16. def _make_image(args): 
  17.     if args.image_name == 'system'
  18.         _prepare_root(args.input_path)              # 准备好 system.img 需要的文件 
  19.     elif args.image_name == 'updater'
  20.         _prepare_updater(args.input_path)           # 准备好 updater.img 需要的文件 
  21.     image_type = "raw" 
  22.     if args.sparse_image: 
  23.         image_type = "sparse" 
  24.     mk_image_args = [ 
  25.         args.input_path, args.image_config_file, args.output_image_path, 
  26.         image_type 
  27.     ] 
  28.     env_path = "../../build/ohos/images/mkimage" 
  29.     if args.build_image_tools_path: 
  30.         env_path = '{}:{}'.format(env_path, args.build_image_tools_path) 
  31.     os.environ['PATH'] = '{}:{}'.format(env_path, os.environ.get('PATH')) 
  32.     mkimages.mk_images(mk_image_args)           # 而真正制作镜像使用的下面的函数 
  33. =================================================================== 
  34. # build\ohos\images\mkimage\mkimages.py 
  35. def mk_images(args): 
  36.     ... ... 
  37.     if "system.img" in device: 
  38.         src_dir = build_rootdir(src_dir) 
  39.     mkfs_tools, mk_configs = load_config(config_file) 
  40.     mk_configs = src_dir + " " + device + " " + mk_configs 
  41.  
  42.     res = run_cmd(mkfs_tools + " " + mk_configs)    # 制作镜像命令使用的是mkfs_tools 
  43. =================================================================== 
  44.     if "ext4" in mk_configs: 
  45.         fs_type = "ext4" 
  46.         mkfs_tools = "mkextimage.py"                # 而mkfs_tools根据文件系统类型,分别调用对应的python脚本 
  47.     elif "f2fs" in mk_configs: 
  48.         mkfs_tools = "mkf2fsimage.py" 
  49.         fs_type = "f2fs" 
  50. =================================================================== 
  51. # build\ohos\images\mkimage\mkextimage.py # 制作ext4文件系统 
  52. def build_run_mke2fs(args): 
  53.     .. ... 
  54.     blocks = int(int(args.fs_size) / BLOCKSIZE) 
  55.     mke2fs_cmd += ("mke2fs " + str(mke2fs_opts) + " -t " + FS_TYPE + " -b " 
  56.                    + str(BLOCKSIZE) + " " + args.device + " " + str(blocks)) 
  57.     res = run_cmd(mke2fs_cmd)       # mke2fs:制作文件系统 
  58. =================================================================== 
  59. def build_run_e2fsdroid(args): 
  60.     ... ... 
  61.     e2fsdroid_cmd += ("e2fsdroid" + e2fsdroid_opts + " -f " + 
  62.                       args.src_dir + " -a " + args.mount_point + 
  63.                       " " + args.device) 
  64.     res = run_cmd(e2fsdroid_cmd)    # e2fsdroid:制作镜像文件   

无论前面执行了什么操作,最终都是为了执行mke2fs、e2fsdroid。

关于这两个命令:

mke2fs:Linux下的命令,用于建立ext文件系统。

e2fsdroid:来自三方库,third_party\e2fsprogs。详情可以参考 http://e2fsprogs.sourceforge.net

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-06-10 14:37:24

鸿蒙操作系统

2022-05-11 15:08:52

驱动开发系统移植

2022-05-27 15:04:53

鸿蒙操作系统

2022-07-27 14:30:15

分布式数据鸿蒙

2022-05-07 16:13:59

DevEcoTool鸿蒙

2022-04-11 13:57:38

HarmonyRelease操作系统

2022-07-19 20:04:31

NAPI模块鸿蒙

2022-04-25 09:10:50

RK3568鸿蒙

2022-02-25 14:42:09

OpenHarmon环境搭建鸿蒙

2022-04-12 11:35:43

IDE工具OHOS应用鸿蒙

2022-02-28 14:54:48

openHarmon鸿蒙操作系统

2022-04-15 14:31:02

鸿蒙操作系统

2021-12-31 10:00:30

2022-03-04 15:43:36

文件管理模块Harmony鸿蒙

2022-02-21 14:49:26

OpenHarmon操作系统鸿蒙

2021-06-28 09:38:50

2022-04-18 10:37:01

鸿蒙操作系统开发工具

2022-02-08 15:15:26

2022-07-29 14:29:24

设备开发鸿蒙

2022-01-24 18:43:20

同话题下的热门内容

字节的前端监控 SDK 是怎样设计的TestOps完全手册:工作流、生命周期、团队和流程使用Python快速搭建接口自动化测试脚本实战总结不要在 Python 中使用循环,这些方法其实更棒!哪种编程语言最适合开发网页抓取工具?从 Islands Architecture 看前端有多卷反应式JavaScript:前端架构的演变什么是WebAssembly?

编辑推荐

太厉害了,终于有人能把TCP/IP协议讲的明明白白了!牛人5次面试腾讯不成功的经验HBase原理–所有Region切分的细节都在这里了Javascript如何监听页面刷新和关闭事件如何搭建一个HTTPS服务端
我收藏的内容
点赞
收藏

51CTO技术栈公众号