• 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, depfiles):
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, depfiles):
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, install_modules_info_file,
64                 modules_info_file, module_list_file,
65                 post_process_modules_info_files, platform_installed_path,
66                 additional_system_files, depfiles):
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(
76                "read module install info file '{}' error.".format(value))
77        install = module_info.get('install_enable')
78        if not install:
79            continue
80        output_result.append(module_info)
81
82    # get post process modules info
83    post_process_modules = _get_post_process_modules_info(
84        post_process_modules_info_files, depfiles)
85    for _module_info in post_process_modules:
86        install = _module_info.get('install_enable')
87        if not install:
88            continue
89        output_result.append(_module_info)
90
91    for source, system_path in additional_system_files:
92        shutil.copy(source, os.path.join(platform_installed_path, system_path))
93
94    # copy modules
95    for module_info in output_result:
96        if module_info.get('type') == 'none':
97            continue
98        # copy module lib
99        source = module_info.get('source')
100        dests = module_info.get('dest')
101        # check source
102        if not os.path.exists(source):
103            raise Exception("source '{}' doesn't exist.".format(source))
104        depfiles.append(source)
105        for dest in dests:
106            if dest.startswith('/'):
107                dest = dest[1:]
108            dest_list.append(dest)
109            # dest_dir_prefix
110            dest_dir = os.path.join(platform_installed_path,
111                                    os.path.dirname(dest))
112            if not os.path.exists(dest_dir):
113                os.makedirs(dest_dir)
114            shutil.copy(source, os.path.join(platform_installed_path, dest))
115
116        # add symlink
117        if 'symlink' in module_info:
118            symlink_dest = module_info.get('symlink')
119            for dest in dests:
120                symlink_src_file = os.path.basename(dest)
121                for name in symlink_dest:
122                    symlink_dest_dir = os.path.dirname(dest)
123                    symlink_dest_file = os.path.join(platform_installed_path,
124                                                     symlink_dest_dir, name)
125                    if not os.path.exists(symlink_dest_file):
126                        os.symlink(symlink_src_file, symlink_dest_file)
127
128    # write install module info to file
129    write_json_file(install_modules_info_file, modules_info_dict)
130
131    # write all module info
132    write_json_file(modules_info_file, output_result)
133
134    # output module list to file
135    write_file(module_list_file, '\n'.join(dest_list))
136
137
138def main():
139    parser = argparse.ArgumentParser()
140    parser.add_argument('--system-install-info-file', required=True)
141    parser.add_argument('--install-modules-info-file', required=True)
142    parser.add_argument('--modules-info-file', required=True)
143    parser.add_argument('--modules-list-file', required=True)
144    parser.add_argument('--platform-installed-path', required=True)
145    parser.add_argument('--system-dir', required=True)
146    parser.add_argument('--sa-profile-extract-dir', required=True)
147    parser.add_argument('--merged-sa-profile', required=True)
148    parser.add_argument('--depfile', required=True)
149    parser.add_argument('--system-image-zipfile', required=True)
150    parser.add_argument(
151        '--additional-system-files',
152        action='append',
153        help=
154        "additional system files is used for files don't have module infos. use with caution"
155    )
156    parser.add_argument('--post-process-modules-info-files',
157                        nargs='*',
158                        default=[])
159    args = parser.parse_args()
160
161    additional_system_files = []
162    for tuple in args.additional_system_files or []:
163        filepath, system_path = tuple.split(':')
164        additional_system_files.append((filepath, system_path))
165
166    depfiles = []
167    build_utils.extract_all(args.merged_sa_profile,
168                            args.sa_profile_extract_dir,
169                            no_clobber=False)
170    sa_files = build_utils.get_all_files(args.sa_profile_extract_dir)
171
172    system_install_info = read_json_file(args.system_install_info_file)
173    if system_install_info is None:
174        raise Exception("read file '{}' failed.".format(
175            args.system_install_info_file))
176
177    system_install_base_dir = args.system_dir
178    if os.path.exists(system_install_base_dir):
179        shutil.rmtree(system_install_base_dir)
180        print('remove system dir...')
181    os.makedirs(system_install_base_dir)
182
183    vendor_install_base_dir = os.path.join(args.platform_installed_path,
184                                           'vendor')
185    if os.path.exists(vendor_install_base_dir):
186        shutil.rmtree(vendor_install_base_dir)
187        print('remove vendor dir...')
188
189    updater_install_base_dir = os.path.join(args.platform_installed_path,
190                                            'updater')
191    if os.path.exists(updater_install_base_dir):
192        shutil.rmtree(updater_install_base_dir)
193        print('remove updater dir...')
194
195    ramdisk_install_base_dir = os.path.join(args.platform_installed_path,
196                                            'ramdisk')
197    if os.path.exists(ramdisk_install_base_dir):
198        shutil.rmtree(ramdisk_install_base_dir)
199        print('remove ramdisk dir...')
200
201    print('copy modules...')
202    copy_modules(system_install_info, args.install_modules_info_file,
203                 args.modules_info_file, args.modules_list_file,
204                 args.post_process_modules_info_files,
205                 args.platform_installed_path, additional_system_files,
206                 depfiles)
207
208    if os.path.exists(args.system_image_zipfile):
209        os.unlink(args.system_image_zipfile)
210    build_utils.zip_dir(args.system_image_zipfile, args.system_dir)
211    depfiles.extend([item for item in depfiles if item not in sa_files])
212    build_utils.write_depfile(args.depfile, args.install_modules_info_file,
213                              depfiles)
214
215    return 0
216
217
218if __name__ == '__main__':
219    sys.exit(main())
220