• 1
  • 2
  • 3
  • 4

首页 / 行业

剖析OpenHarmony3.0编译构建流程

2021-12-07 10:54:00

剖析OpenHarmony3.0编译构建流程

早就打算研究下 OH3.0 的编译框架了,最近一直在搞移植,总算有点进展了,抽个空来分析下 3.0 的编译框架。

大体看了下和 2.0 的差别不是特别大:《OpenHarmony 2.0 Canary编译构建流程》。

OHOS3.0 的打包镜像脚本由原来 2.0 的 buildadapteruild_image.sh,全部修改替换为 buildohosimagesuild_image.py,将打包 image 镜像的部分制作成 build_target。

以前是通过 shell 脚本来调用,现在是通过 gn 和 ninja 来调用。主要文件在 buildohosimages 这个文件夹下。

没有修改的部分就不说了,有需要的可以看我之前的帖子 这篇主要说下不一样的地方,看 OH3.0 是如何将编译好的文件打包成镜像的。

增加编译参数

3.0 之后在 builduild_scriptsuild_common.sh 增加了 build_cmd+=" build_target=images"。

这句的意思约等于在执行默认编译命令 ./build.sh --product-name Hi3516DV300 会有个默认的参数 --build-target images。

具体流程是这样的:

builduild_scriptsuild_common.sh→buildcoregnBUILD.gn→buildohosimagesBUILD.gn
action_with_pydeps("${_platform}_${_image_name}_image"){script="//build/ohos/images/build_image.py"depfile="$target_gen_dir/$target_name.d"deps=["//build/ohos/packages:${_platform}_install_modules"]image_config_file="//build/ohos/images/mkimage/${_image_name}_image_conf.txt"output_image_file="$current_platform_dir/images/${_image_name}.img"image_input_path="$current_platform_dir/${_image_name}"if(_image_name=="userdata"){image_input_path="$current_platform_dir/data"}sources=[image_config_file,system_module_info_list,system_modules_list,]outputs=[output_image_file]args=["--depfile",rebase_path(depfile,root_build_dir),"--image-name",_image_name,"--input-path",rebase_path(image_input_path,root_build_dir),"--image-config-file",rebase_path(image_config_file,root_build_dir),"--output-image",rebase_path(output_image_file,root_build_dir),"--build-image-tools-path",rebase_path(build_image_tools_path,root_build_dir),]if(sparse_image){args+=["--sparse-image"]}}

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

输入和文件,将操作读取(或执行)的所有文件列为 inputs:

  • 仅按从属目标列出输入是不够的。它们必须由使用它们的目标直接列出,或者由 depfile 添加。

  • 非系统 Python 导入是输入!对于导入此类模块的脚本,请使用 action_with_pydeps 来确保将所有依赖的 Python 文件捕获为输入。

前面还定义了一个 image_list,然后使用 foreach 执行 action_with_pydeps,要生成几个 img 文件,就执行几次 action_with_pydeps。
image_list=["system","vendor","userdata","updater",]foreach(_image_name,image_list){......}

调用 python 脚本

既然知道了 img 镜像是由 buildohosimagesuild_image.py 来创建的,那就来分析下这个 python 脚本。
ifos.path.exists(args.output_image_path):os.remove(args.output_image_path)#删除之前生成的镜像文件夹ifargs.image_name=='userdata':_prepare_userdata(args.input_path)#准备好userdata.img需要的文件ifos.path.isdir(args.input_path):_make_image(args)_dep_files=[]for_root,_,_filesinos.walk(args.input_path):for_filein_files:_dep_files.append(os.path.join(_root,_file))build_utils.write_depfile(args.depfile,args.output_image_path,_dep_files,add_pydeps=False)===================================================================def_make_image(args):ifargs.image_name=='system':_prepare_root(args.input_path)#准备好system.img需要的文件elifargs.image_name=='updater':_prepare_updater(args.input_path)#准备好updater.img需要的文件image_type="raw"ifargs.sparse_image:image_type="sparse"mk_image_args=[args.input_path,args.image_config_file,args.output_image_path,image_type]env_path="../../build/ohos/images/mkimage"ifargs.build_image_tools_path:env_path='{}:{}'.format(env_path,args.build_image_tools_path)os.environ['PATH']='{}:{}'.format(env_path,os.environ.get('PATH'))mkimages.mk_images(mk_image_args)#而真正制作镜像使用的下面的函数===================================================================#buildohosimagesmkimagemkimages.pydefmk_images(args):......if"system.img"indevice:src_dir=build_rootdir(src_dir)mkfs_tools,mk_configs=load_config(config_file)mk_configs=src_dir+""+device+""+mk_configsres=run_cmd(mkfs_tools+""+mk_configs)#制作镜像命令使用的是mkfs_tools===================================================================if"ext4"inmk_configs:fs_type="ext4"mkfs_tools="mkextimage.py"#而mkfs_tools根据文件系统类型,分别调用对应的python脚本elif"f2fs"inmk_configs:mkfs_tools="mkf2fsimage.py"fs_type="f2fs"===================================================================#buildohosimagesmkimagemkextimage.py#制作ext4文件系统defbuild_run_mke2fs(args):.....blocks=int(int(args.fs_size)/BLOCKSIZE)mke2fs_cmd+=("mke2fs"+str(mke2fs_opts)+"-t"+FS_TYPE+"-b"+str(BLOCKSIZE)+""+args.device+""+str(blocks))res=run_cmd(mke2fs_cmd)# mke2fs:制作文件系统===================================================================defbuild_run_e2fsdroid(args):......e2fsdroid_cmd+=("e2fsdroid"+e2fsdroid_opts+"-f"+args.src_dir+"-a"+args.mount_point+""+args.device)res=run_cmd(e2fsdroid_cmd)# e2fsdroid:制作镜像文件

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

关于这两个命令:

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

  • e2fsdroid:来自三方库,third_partye2fsprogs。

详情可以参考:

http://e2fsprogs.sourceforge.net
编辑:jq

编译框架调用脚本

  • 1
  • 2
  • 3
  • 4

最新内容

手机

相关内容

  • 1
  • 2
  • 3

猜你喜欢