OpenHarmony-3.0 編譯構(gòu)建流程
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
OpenHarmony-2.0 編譯構(gòu)建流程
早就打算研究下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腳本來調(diào)用,現(xiàn)在是通過gn和ninja來調(diào)用。主要文件在build\ohos\images這個文件夾下。沒有修改的部分就不說了,有需要的可以看我之前的帖子 這篇主要說下不一樣的地方,看OH3.0是如何將編譯好的文件打包成鏡像的。
一、增加編譯參數(shù)
3.0之后在build\build_scripts\build_common.sh 增加了 build_cmd+=" build_target=images",這句的意思約等于在執(zhí)行默認編譯命令 ./build.sh --product-name Hi3516DV300 會有個默認的參數(shù) --build-target images,具體流程是這樣的:
- build\build_scripts\build_common.sh => build\core\gn\BUILD.gn => build\ohos\images\BUILD.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,應(yīng)該也是內(nèi)置的目標(biāo)類型。查看官方手冊是這么說明的
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 執(zhí)行 action_with_pydeps,要生成幾個img文件,就執(zhí)行幾次action_with_pydeps。
- image_list = [
 - "system",
 - "vendor",
 - "userdata",
 - "updater",
 - ]
 - foreach(_image_name, image_list) {... ...}
 
二、調(diào)用python腳本
既然知道了img鏡像是由 build\ohos\images\build_image.py 來創(chuàng)建的,那就來分析下這個python腳本。
- if os.path.exists(args.output_image_path):
 - os.remove(args.output_image_path) # 刪除之前生成的鏡像文件夾
 - if args.image_name == 'userdata':
 - _prepare_userdata(args.input_path) # 準(zhǔn)備好 userdata.img 需要的文件
 - if os.path.isdir(args.input_path):
 - _make_image(args)
 - _dep_files = []
 - for _root, _, _files in os.walk(args.input_path):
 - for _file in _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):
 - if args.image_name == 'system':
 - _prepare_root(args.input_path) # 準(zhǔn)備好 system.img 需要的文件
 - elif args.image_name == 'updater':
 - _prepare_updater(args.input_path) # 準(zhǔn)備好 updater.img 需要的文件
 - image_type = "raw"
 - if args.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"
 - if args.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) # 而真正制作鏡像使用的下面的函數(shù)
 - ===================================================================
 - # build\ohos\images\mkimage\mkimages.py
 - def mk_images(args):
 - ... ...
 - if "system.img" in device:
 - src_dir = build_rootdir(src_dir)
 - mkfs_tools, mk_configs = load_config(config_file)
 - mk_configs = src_dir + " " + device + " " + mk_configs
 - res = run_cmd(mkfs_tools + " " + mk_configs) # 制作鏡像命令使用的是mkfs_tools
 - ===================================================================
 - if "ext4" in mk_configs:
 - fs_type = "ext4"
 - mkfs_tools = "mkextimage.py" # 而mkfs_tools根據(jù)文件系統(tǒng)類型,分別調(diào)用對應(yīng)的python腳本
 - elif "f2fs" in mk_configs:
 - mkfs_tools = "mkf2fsimage.py"
 - fs_type = "f2fs"
 - ===================================================================
 - # build\ohos\images\mkimage\mkextimage.py # 制作ext4文件系統(tǒng)
 - def build_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:制作文件系統(tǒng)
 - ===================================================================
 - def build_run_e2fsdroid(args):
 - ... ...
 - e2fsdroid_cmd += ("e2fsdroid" + e2fsdroid_opts + " -f " +
 - args.src_dir + " -a " + args.mount_point +
 - " " + args.device)
 - res = run_cmd(e2fsdroid_cmd) # e2fsdroid:制作鏡像文件
 
無論前面執(zhí)行了什么操作,最終都是為了執(zhí)行mke2fs、e2fsdroid。
關(guān)于這兩個命令:
mke2fs:Linux下的命令,用于建立ext文件系統(tǒng)。
e2fsdroid:來自三方庫,third_party\e2fsprogs。詳情可以參考 http://e2fsprogs.sourceforge.net
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
















 
 
 












 
 
 
 