15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ciimport sys
175f9996aaSopenharmony_ciimport os
185f9996aaSopenharmony_ciimport shutil
195f9996aaSopenharmony_ciimport argparse
205f9996aaSopenharmony_ciimport json
215f9996aaSopenharmony_cifrom mkimage import mkimages
225f9996aaSopenharmony_ci
235f9996aaSopenharmony_cisys.path.append(
245f9996aaSopenharmony_ci    os.path.dirname(os.path.dirname(os.path.dirname(
255f9996aaSopenharmony_ci        os.path.abspath(__file__)))))
265f9996aaSopenharmony_cifrom scripts.util import build_utils
275f9996aaSopenharmony_cifrom build_scripts.build import find_top  # noqa: E402
285f9996aaSopenharmony_ci
295f9996aaSopenharmony_ci
305f9996aaSopenharmony_cidef _prepare_userdata(userdata_path: str):
315f9996aaSopenharmony_ci    if os.path.exists(userdata_path):
325f9996aaSopenharmony_ci        shutil.rmtree(userdata_path)
335f9996aaSopenharmony_ci    os.makedirs(userdata_path, exist_ok=True)
345f9996aaSopenharmony_ci
355f9996aaSopenharmony_ci
365f9996aaSopenharmony_cidef _prepare_root(system_path: str, target_cpu: str):
375f9996aaSopenharmony_ci    root_dir = os.path.join(os.path.dirname(system_path), 'root')
385f9996aaSopenharmony_ci    if os.path.exists(root_dir):
395f9996aaSopenharmony_ci        shutil.rmtree(root_dir)
405f9996aaSopenharmony_ci    os.makedirs(root_dir, exist_ok=True)
415f9996aaSopenharmony_ci    _dir_list = [
425f9996aaSopenharmony_ci        'config', 'dev', 'proc', 'sys', 'updater', 'system', 'vendor', 'data', 'chip_ckm',
435f9996aaSopenharmony_ci        'storage', 'mnt', 'tmp', 'sys_prod', 'chip_prod', 'module_update', 'eng_system', 'eng_chipset'
445f9996aaSopenharmony_ci    ]
455f9996aaSopenharmony_ci    for _dir_name in _dir_list:
465f9996aaSopenharmony_ci        os.makedirs(os.path.join(root_dir, _dir_name), exist_ok=True)
475f9996aaSopenharmony_ci    os.symlink('/system/bin', os.path.join(root_dir, 'bin'))
485f9996aaSopenharmony_ci    os.symlink('/system/bin/init', os.path.join(root_dir, 'init'))
495f9996aaSopenharmony_ci    os.symlink('/system/etc', os.path.join(root_dir, 'etc'))
505f9996aaSopenharmony_ci    os.symlink('/vendor', os.path.join(root_dir, 'chipset'))
515f9996aaSopenharmony_ci    if target_cpu == 'arm64' or target_cpu == 'riscv64':
525f9996aaSopenharmony_ci        os.symlink('/system/lib64', os.path.join(root_dir, 'lib64'))
535f9996aaSopenharmony_ci    os.symlink('/system/lib', os.path.join(root_dir, 'lib'))
545f9996aaSopenharmony_ci
555f9996aaSopenharmony_ci
565f9996aaSopenharmony_cidef _prepare_updater(updater_path: str, target_cpu: str):
575f9996aaSopenharmony_ci    _dir_list = ['dev', 'proc', 'sys', 'system', 'tmp', 'lib', 'lib64', 'vendor']
585f9996aaSopenharmony_ci    for _dir_name in _dir_list:
595f9996aaSopenharmony_ci        _path = os.path.join(updater_path, _dir_name)
605f9996aaSopenharmony_ci        if os.path.exists(_path):
615f9996aaSopenharmony_ci            continue
625f9996aaSopenharmony_ci        os.makedirs(_path, exist_ok=True)
635f9996aaSopenharmony_ci    if not os.path.exists(os.path.join(updater_path, 'init')):
645f9996aaSopenharmony_ci        os.symlink('bin/init', os.path.join(updater_path, 'init'))
655f9996aaSopenharmony_ci    if not os.path.exists(os.path.join(updater_path, 'system/bin')):
665f9996aaSopenharmony_ci        os.symlink('/bin', os.path.join(updater_path, 'system/bin'))
675f9996aaSopenharmony_ci    if not os.path.exists(os.path.join(updater_path, 'system/lib')):
685f9996aaSopenharmony_ci        os.symlink('/lib', os.path.join(updater_path, 'system/lib'))
695f9996aaSopenharmony_ci    if target_cpu == 'arm64':
705f9996aaSopenharmony_ci        if not os.path.exists(os.path.join(updater_path, 'system/lib64')):
715f9996aaSopenharmony_ci            os.symlink('/lib64', os.path.join(updater_path, 'system/lib64'))
725f9996aaSopenharmony_ci        if not os.path.exists(os.path.join(updater_path, 'vendor/lib64')):
735f9996aaSopenharmony_ci            os.symlink('/lib64', os.path.join(updater_path, 'vendor/lib64'))
745f9996aaSopenharmony_ci    else:
755f9996aaSopenharmony_ci        if not os.path.exists(os.path.join(updater_path, 'vendor/lib')):
765f9996aaSopenharmony_ci            os.symlink('/lib', os.path.join(updater_path, 'vendor/lib'))
775f9996aaSopenharmony_ci    if not os.path.exists(os.path.join(updater_path, 'system/etc')):
785f9996aaSopenharmony_ci        os.symlink('/etc', os.path.join(updater_path, 'system/etc'))
795f9996aaSopenharmony_ci
805f9996aaSopenharmony_ci
815f9996aaSopenharmony_cidef _prepare_ramdisk(ramdisk_path: str):
825f9996aaSopenharmony_ci    _dir_list = ['bin', 'dev', 'etc', 'lib', 'proc', 'sys', 'system', 'usr', 'mnt', 'storage']
835f9996aaSopenharmony_ci    for _dir_name in _dir_list:
845f9996aaSopenharmony_ci        _path = os.path.join(ramdisk_path, _dir_name)
855f9996aaSopenharmony_ci        if os.path.exists(_path):
865f9996aaSopenharmony_ci            continue
875f9996aaSopenharmony_ci        os.makedirs(_path, exist_ok=True)
885f9996aaSopenharmony_ci    if not os.path.exists(os.path.join(ramdisk_path, 'init')):
895f9996aaSopenharmony_ci        os.symlink('bin/init_early', os.path.join(ramdisk_path, 'init'))
905f9996aaSopenharmony_ci
915f9996aaSopenharmony_ci
925f9996aaSopenharmony_cidef _prepare_eng_ststem(eng_system_path: str, build_variant: str):
935f9996aaSopenharmony_ci    if os.path.exists(eng_system_path):
945f9996aaSopenharmony_ci        shutil.rmtree(eng_system_path)
955f9996aaSopenharmony_ci    os.makedirs(eng_system_path, exist_ok=True)
965f9996aaSopenharmony_ci    if build_variant == "user":
975f9996aaSopenharmony_ci        return
985f9996aaSopenharmony_ci    _dir_list_first = ['etc', 'bin']
995f9996aaSopenharmony_ci    for _dir_name in _dir_list_first:
1005f9996aaSopenharmony_ci        _path = os.path.join(eng_system_path, _dir_name)
1015f9996aaSopenharmony_ci        if os.path.exists(_path):
1025f9996aaSopenharmony_ci            shutil.rmtree(_path)
1035f9996aaSopenharmony_ci        os.makedirs(_path, exist_ok=True)
1045f9996aaSopenharmony_ci    _dir_list_second = ['param', 'init', 'selinux']
1055f9996aaSopenharmony_ci    for _dir_name in _dir_list_second:
1065f9996aaSopenharmony_ci        _path = os.path.join(eng_system_path, 'etc', _dir_name)
1075f9996aaSopenharmony_ci        if os.path.exists(_path):
1085f9996aaSopenharmony_ci            shutil.rmtree(_path)
1095f9996aaSopenharmony_ci        os.makedirs(_path, exist_ok=True)
1105f9996aaSopenharmony_ci    _target_policy_path = os.path.join(eng_system_path, 'etc', 'selinux', 'targeted', 'policy')
1115f9996aaSopenharmony_ci    if os.path.exists(_target_policy_path):
1125f9996aaSopenharmony_ci        shutil.rmtree(_target_policy_path)
1135f9996aaSopenharmony_ci    os.makedirs(_target_policy_path, exist_ok=True)
1145f9996aaSopenharmony_ci    root_path = find_top()
1155f9996aaSopenharmony_ci    copy_eng_system_config = os.path.join(root_path, "build/ohos/images/mkimage/root_image.json")
1165f9996aaSopenharmony_ci    with open(copy_eng_system_config, 'rb') as input_f:
1175f9996aaSopenharmony_ci        default_build_args = json.load(input_f)
1185f9996aaSopenharmony_ci    for arg in default_build_args.values():
1195f9996aaSopenharmony_ci        sources_file = arg.get('source_file')
1205f9996aaSopenharmony_ci        dest_file = arg.get('dest_file')
1215f9996aaSopenharmony_ci        if(os.path.exists(dest_file)):
1225f9996aaSopenharmony_ci            os.remove(dest_file)
1235f9996aaSopenharmony_ci        if(os.path.exists(sources_file)):
1245f9996aaSopenharmony_ci            shutil.copy(sources_file, dest_file)
1255f9996aaSopenharmony_ci
1265f9996aaSopenharmony_ci
1275f9996aaSopenharmony_cidef _make_image(args):
1285f9996aaSopenharmony_ci    if args.image_name == 'system':
1295f9996aaSopenharmony_ci        _prepare_root(args.input_path, args.target_cpu)
1305f9996aaSopenharmony_ci    elif args.image_name == 'updater':
1315f9996aaSopenharmony_ci        _prepare_updater(args.input_path, args.target_cpu)
1325f9996aaSopenharmony_ci    elif args.image_name == 'updater_ramdisk':
1335f9996aaSopenharmony_ci        _prepare_updater(args.input_path, args.target_cpu)
1345f9996aaSopenharmony_ci    elif args.image_name == 'ramdisk':
1355f9996aaSopenharmony_ci        _prepare_ramdisk(args.input_path)
1365f9996aaSopenharmony_ci    image_type = "raw"
1375f9996aaSopenharmony_ci    if args.sparse_image:
1385f9996aaSopenharmony_ci        image_type = "sparse"
1395f9996aaSopenharmony_ci    config_file = args.image_config_file
1405f9996aaSopenharmony_ci    if (os.path.exists(args.device_image_config_file)):
1415f9996aaSopenharmony_ci        config_file = args.device_image_config_file
1425f9996aaSopenharmony_ci    mk_image_args = [
1435f9996aaSopenharmony_ci        args.input_path, config_file, args.output_image_path,
1445f9996aaSopenharmony_ci        image_type
1455f9996aaSopenharmony_ci    ]
1465f9996aaSopenharmony_ci    if args.build_image_tools_path:
1475f9996aaSopenharmony_ci        env_path = ':'.join(args.build_image_tools_path)
1485f9996aaSopenharmony_ci        os.environ['PATH'] = '{}:{}'.format(env_path, os.environ.get('PATH'))
1495f9996aaSopenharmony_ci    mkimages.mk_images(mk_image_args)
1505f9996aaSopenharmony_ci
1515f9996aaSopenharmony_ci
1525f9996aaSopenharmony_cidef main(argv):
1535f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
1545f9996aaSopenharmony_ci    parser.add_argument('--depfile', required=True)
1555f9996aaSopenharmony_ci    parser.add_argument('--image-name', required=True)
1565f9996aaSopenharmony_ci    parser.add_argument('--build-variant', required=True)
1575f9996aaSopenharmony_ci    parser.add_argument('--image-config-file', required=True)
1585f9996aaSopenharmony_ci    parser.add_argument('--device-image-config-file', required=True)
1595f9996aaSopenharmony_ci    parser.add_argument('--input-path', required=True)
1605f9996aaSopenharmony_ci    parser.add_argument('--output-image-path', required=True)
1615f9996aaSopenharmony_ci    parser.add_argument('--sparse-image',
1625f9996aaSopenharmony_ci                        dest="sparse_image",
1635f9996aaSopenharmony_ci                        action='store_true')
1645f9996aaSopenharmony_ci    parser.set_defaults(sparse_image=False)
1655f9996aaSopenharmony_ci    parser.add_argument('--build-image-tools-path', nargs='*', required=False)
1665f9996aaSopenharmony_ci    parser.add_argument('--target-cpu', required=False)
1675f9996aaSopenharmony_ci    args = parser.parse_args(argv)
1685f9996aaSopenharmony_ci
1695f9996aaSopenharmony_ci    if os.path.exists(args.output_image_path):
1705f9996aaSopenharmony_ci        os.remove(args.output_image_path)
1715f9996aaSopenharmony_ci    if args.image_name == 'userdata':
1725f9996aaSopenharmony_ci        _prepare_userdata(args.input_path)
1735f9996aaSopenharmony_ci    elif args.image_name == 'eng_system':
1745f9996aaSopenharmony_ci        _prepare_eng_ststem(args.input_path, args.build_variant)
1755f9996aaSopenharmony_ci    if os.path.isdir(args.input_path):
1765f9996aaSopenharmony_ci        _make_image(args)
1775f9996aaSopenharmony_ci        _dep_files = []
1785f9996aaSopenharmony_ci        for _root, _, _files in os.walk(args.input_path):
1795f9996aaSopenharmony_ci            for _file in _files:
1805f9996aaSopenharmony_ci                _dep_files.append(os.path.join(_root, _file))
1815f9996aaSopenharmony_ci        if (os.path.exists(args.device_image_config_file)):
1825f9996aaSopenharmony_ci            _dep_files.append(args.device_image_config_file)
1835f9996aaSopenharmony_ci        build_utils.write_depfile(args.depfile,
1845f9996aaSopenharmony_ci                                  args.output_image_path,
1855f9996aaSopenharmony_ci                                  _dep_files,
1865f9996aaSopenharmony_ci                                  add_pydeps=False)
1875f9996aaSopenharmony_ci    return 0
1885f9996aaSopenharmony_ci
1895f9996aaSopenharmony_ci
1905f9996aaSopenharmony_ciif __name__ == '__main__':
1915f9996aaSopenharmony_ci    sys.exit(main(sys.argv[1:]))
192