• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2021 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import sys
17import argparse
18import os
19import shutil
20
21sys.path.append(
22    os.path.dirname(os.path.dirname(os.path.dirname(
23        os.path.abspath(__file__)))))
24from scripts.util.file_utils import read_json_file, write_json_file, write_file  # noqa: E402
25from scripts.util import build_utils  # noqa: E402
26
27
28def _get_modules_info(system_install_info: dict, depfiles: list):
29    modules_info_dict = {}
30    for subsystem_info in system_install_info:
31        part_name = subsystem_info.get('part_name')
32        part_info_file = subsystem_info.get('part_info_file')
33
34        # read subsystem module info
35        part_install_info = read_json_file(part_info_file)
36        if part_install_info is None:
37            raise Exception(
38                "read part '{}' installed modules info failed.".format(
39                    part_name))
40        depfiles.append(part_info_file)
41
42        for info in part_install_info:
43            module_def = info.get('module_def')
44            module_info_file = info.get('module_info_file')
45            depfiles.append(module_info_file)
46            if module_def not in modules_info_dict:
47                modules_info_dict[module_def] = module_info_file
48    return modules_info_dict
49
50
51def _get_post_process_modules_info(post_process_modules_info_files: list, depfiles: list):
52    modules_info_list = []
53    for _modules_info_file in post_process_modules_info_files:
54        _modules_info = read_json_file(_modules_info_file)
55        if _modules_info is None:
56            raise Exception("read _modules_info_file '{}' failed.".format(
57                _modules_info_file))
58        modules_info_list.extend(_modules_info)
59        depfiles.append(_modules_info_file)
60    return modules_info_list
61
62
63def copy_modules(system_install_info: dict, install_modules_info_file: str,
64                 modules_info_file: str, module_list_file: str,
65                 post_process_modules_info_files: list, platform_installed_path: str,
66                 host_toolchain, additional_system_files: dict, depfiles: list):
67    output_result = []
68    dest_list = []
69    symlink_dest = []
70
71    modules_info_dict = _get_modules_info(system_install_info, depfiles)
72    for value in modules_info_dict.values():
73        module_info = read_json_file(value)
74        if not module_info:
75            raise Exception("read module install info file '{}' error.".format(value))
76        install = module_info.get('install_enable')
77        if not install:
78            continue
79        output_result.append(module_info)
80
81    # get post process modules info
82    post_process_modules = _get_post_process_modules_info(
83        post_process_modules_info_files, depfiles)
84    for _module_info in post_process_modules:
85        install = _module_info.get('install_enable')
86        if not install:
87            continue
88        output_result.append(_module_info)
89
90    for source, system_path in additional_system_files:
91        shutil.copy(source, os.path.join(platform_installed_path, system_path))
92
93    # copy modules
94    for module_info in output_result:
95        if module_info.get('type') == 'none':
96            continue
97        # copy module lib
98        label = module_info.get('label')
99        if label and host_toolchain in label:
100            continue
101        source = module_info.get('source')
102        dests = module_info.get('dest')
103        # check source
104        if not os.path.exists(source):
105            raise Exception("source '{}' doesn't exist.".format(source))
106        depfiles.append(source)
107        for dest in dests:
108            if dest.startswith('/'):
109                dest = dest[1:]
110            dest_list.append(dest)
111            # dest_dir_prefix
112            if os.path.isfile(source):
113                dest_dir = os.path.join(platform_installed_path,
114                                        os.path.dirname(dest))
115            elif os.path.isdir(source):
116                dest_dir = os.path.join(platform_installed_path, dest)
117            if not os.path.exists(dest_dir):
118                os.makedirs(dest_dir, exist_ok=True)
119            if os.path.isdir(source):
120                is_hvigor_hap = False
121                for filename in os.listdir(source):
122                    if filename.endswith('.hap') or filename.endswith('.hsp'):
123                        is_hvigor_hap = True
124                        shutil.copy2(os.path.join(source, filename),
125                                     os.path.join(platform_installed_path, dest, filename))
126                if not is_hvigor_hap:
127                    shutil.copytree(source, os.path.join(platform_installed_path, dest), dirs_exist_ok=True)
128            else:
129                shutil.copy2(source, os.path.join(platform_installed_path, dest))
130
131        # add symlink
132        if 'symlink' in module_info:
133            symlink_dest = module_info.get('symlink')
134            for dest in dests:
135                symlink_src_file = os.path.basename(dest)
136                for name in symlink_dest:
137                    symlink_dest_dir = os.path.dirname(dest)
138                    symlink_dest_file = os.path.join(platform_installed_path,
139                                                     symlink_dest_dir, name)
140                    if not os.path.exists(symlink_dest_file):
141                        os.symlink(symlink_src_file, symlink_dest_file)
142
143    # write install module info to file
144    write_json_file(install_modules_info_file, modules_info_dict)
145
146    # write all module info
147    write_json_file(modules_info_file, output_result)
148
149    # output module list to file
150    write_file(module_list_file, '\n'.join(dest_list))
151
152
153def main():
154    parser = argparse.ArgumentParser()
155    parser.add_argument('--system-install-info-file', required=True)
156    parser.add_argument('--install-modules-info-file', required=True)
157    parser.add_argument('--modules-info-file', required=True)
158    parser.add_argument('--modules-list-file', required=True)
159    parser.add_argument('--platform-installed-path', required=True)
160    parser.add_argument('--system-dir', required=True)
161    parser.add_argument('--sa-profile-extract-dir', required=True)
162    parser.add_argument('--merged-sa-profile', required=True)
163    parser.add_argument('--depfile', required=True)
164    parser.add_argument('--system-image-zipfile', required=True)
165    parser.add_argument('--host-toolchain', required=True)
166    parser.add_argument(
167        '--additional-system-files',
168        action='append',
169        help="additional system files is used for files don't have module infos. \
170                use with caution"
171    )
172    parser.add_argument('--post-process-modules-info-files',
173                        nargs='*',
174                        default=[])
175    args = parser.parse_args()
176
177    additional_system_files = []
178    for tuple in args.additional_system_files or []:
179        filepath, system_path = tuple.split(':')
180        additional_system_files.append((filepath, system_path))
181
182    depfiles = []
183    build_utils.extract_all(args.merged_sa_profile,
184                            args.sa_profile_extract_dir,
185                            no_clobber=False)
186    sa_files = build_utils.get_all_files(args.sa_profile_extract_dir)
187
188    system_install_info = read_json_file(args.system_install_info_file)
189    if system_install_info is None:
190        raise Exception("read file '{}' failed.".format(
191            args.system_install_info_file))
192
193    system_install_base_dir = args.system_dir
194    if os.path.exists(system_install_base_dir):
195        shutil.rmtree(system_install_base_dir)
196        print('remove system dir...')
197    os.makedirs(system_install_base_dir, exist_ok=True)
198
199    vendor_install_base_dir = os.path.join(args.platform_installed_path,
200                                           'vendor')
201    if os.path.exists(vendor_install_base_dir):
202        shutil.rmtree(vendor_install_base_dir)
203        print('remove vendor dir...')
204
205    eng_system_install_base_dir = os.path.join(args.platform_installed_path,
206                                           'eng_system')
207    if os.path.exists(eng_system_install_base_dir):
208        shutil.rmtree(eng_system_install_base_dir)
209        print('remove eng_system dir...')
210
211    eng_chipset_install_base_dir = os.path.join(args.platform_installed_path,
212                                           'eng_chipset')
213    if os.path.exists(eng_chipset_install_base_dir):
214        shutil.rmtree(eng_chipset_install_base_dir)
215        print('remove eng_chipset dir...')
216
217    sys_prod_install_base_dir = os.path.join(args.platform_installed_path,
218                                           'sys_prod')
219    if os.path.exists(sys_prod_install_base_dir):
220        shutil.rmtree(sys_prod_install_base_dir)
221        print('remove sys_prod dir...')
222
223    chip_prod_install_base_dir = os.path.join(args.platform_installed_path,
224                                           'chip_prod')
225    if os.path.exists(chip_prod_install_base_dir):
226        shutil.rmtree(chip_prod_install_base_dir)
227        print('remove chip_prod dir...')
228
229    updater_install_base_dir = os.path.join(args.platform_installed_path,
230                                            'updater')
231    if os.path.exists(updater_install_base_dir):
232        shutil.rmtree(updater_install_base_dir)
233        print('remove updater dir...')
234
235    updater_vendor_install_base_dir = os.path.join(args.platform_installed_path,
236                                            'updater_vendor')
237    if os.path.exists(updater_vendor_install_base_dir):
238        shutil.rmtree(updater_vendor_install_base_dir)
239        print('remove updater dir...')
240
241    ramdisk_install_base_dir = os.path.join(args.platform_installed_path,
242                                            'ramdisk')
243    if os.path.exists(ramdisk_install_base_dir):
244        shutil.rmtree(ramdisk_install_base_dir)
245        print('remove ramdisk dir...')
246
247    print('copy modules...')
248    copy_modules(system_install_info, args.install_modules_info_file,
249                 args.modules_info_file, args.modules_list_file,
250                 args.post_process_modules_info_files,
251                 args.platform_installed_path, args.host_toolchain,
252                 additional_system_files, depfiles)
253
254    if os.path.exists(args.system_image_zipfile):
255        os.unlink(args.system_image_zipfile)
256    build_utils.zip_dir(args.system_image_zipfile, args.system_dir)
257    depfiles.extend([item for item in depfiles if item not in sa_files])
258    build_utils.write_depfile(args.depfile, args.install_modules_info_file,
259                              depfiles)
260    return 0
261
262
263if __name__ == '__main__':
264    sys.exit(main())
265