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 argparse 175f9996aaSopenharmony_ciimport sys 185f9996aaSopenharmony_ciimport os 195f9996aaSopenharmony_ciimport pathlib 205f9996aaSopenharmony_ciimport re 215f9996aaSopenharmony_cifrom convert_permissions import convert_permissions 225f9996aaSopenharmony_ci 235f9996aaSopenharmony_cisys.path.append( 245f9996aaSopenharmony_ci os.path.dirname( 255f9996aaSopenharmony_ci os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 265f9996aaSopenharmony_cifrom scripts.util.file_utils import write_file, read_json_file, \ 275f9996aaSopenharmony_ci write_json_file # noqa: E402 285f9996aaSopenharmony_cifrom scripts.util import build_utils # noqa: E402 295f9996aaSopenharmony_ci 305f9996aaSopenharmony_ci# Import jinja2 from third_party/jinja2 315f9996aaSopenharmony_cisys.path.insert(1, os.path.join(os.path.abspath( 325f9996aaSopenharmony_ci os.path.join(os.path.dirname(__file__), 335f9996aaSopenharmony_ci '..', '..', '..')), 'third_party')) 345f9996aaSopenharmony_cifrom jinja2 import Template # noqa: E402 # pylint: disable=F0401 355f9996aaSopenharmony_ci 365f9996aaSopenharmony_ciKEYS = ['target_os', 'install_dir', 'module_label', 'build_only'] 375f9996aaSopenharmony_ci 385f9996aaSopenharmony_ci 395f9996aaSopenharmony_ciclass SdkTargets: 405f9996aaSopenharmony_ci 415f9996aaSopenharmony_ci def __init__(self, os_type): 425f9996aaSopenharmony_ci self.os_type = os_type 435f9996aaSopenharmony_ci self.targets = [] 445f9996aaSopenharmony_ci 455f9996aaSopenharmony_ci def add_target(self, target): 465f9996aaSopenharmony_ci if target not in self.targets: 475f9996aaSopenharmony_ci self.targets.append(target) 485f9996aaSopenharmony_ci 495f9996aaSopenharmony_ci def get_targets(self): 505f9996aaSopenharmony_ci return self.targets 515f9996aaSopenharmony_ci 525f9996aaSopenharmony_ci 535f9996aaSopenharmony_cidef check_keys(keys): 545f9996aaSopenharmony_ci for key in keys: 555f9996aaSopenharmony_ci if key not in KEYS: 565f9996aaSopenharmony_ci raise Exception( 575f9996aaSopenharmony_ci 'Error: failed to parse ohos sdk description file, missing {}.' 585f9996aaSopenharmony_ci .format(key)) 595f9996aaSopenharmony_ci 605f9996aaSopenharmony_ci 615f9996aaSopenharmony_cidef get_sdk_type(path_name: str): 625f9996aaSopenharmony_ci p = pathlib.Path(path_name) 635f9996aaSopenharmony_ci if path_name.startswith('/'): 645f9996aaSopenharmony_ci top_dir = p.parts[1] 655f9996aaSopenharmony_ci else: 665f9996aaSopenharmony_ci top_dir = p.parts[0] 675f9996aaSopenharmony_ci return top_dir 685f9996aaSopenharmony_ci 695f9996aaSopenharmony_ci 705f9996aaSopenharmony_cidef add_target(item: dict, target: str, sdk_systems: list): 715f9996aaSopenharmony_ci for _os in sdk_systems: 725f9996aaSopenharmony_ci if _os == 'linux' or _os == 'Linux': 735f9996aaSopenharmony_ci item.get('targets').get('linux').add_target('"%s",' % target) 745f9996aaSopenharmony_ci elif _os == 'windows' or _os == 'Windows': 755f9996aaSopenharmony_ci item.get('targets').get('windows').add_target('"%s",' % target) 765f9996aaSopenharmony_ci elif _os == 'darwin' or _os == 'Darwin': 775f9996aaSopenharmony_ci item.get('targets').get('darwin').add_target('"%s",' % target) 785f9996aaSopenharmony_ci elif _os == 'ohos' or _os == 'Ohos': 795f9996aaSopenharmony_ci item.get('targets').get('ohos').add_target('"%s",' % target) 805f9996aaSopenharmony_ci 815f9996aaSopenharmony_ci 825f9996aaSopenharmony_cidef write_sdk_build_gni(sdk_targets: list, build_only_targets: list, gni: str): 835f9996aaSopenharmony_ci template = Template( 845f9996aaSopenharmony_ci """#Generated code, DONOT modify it. 855f9996aaSopenharmony_ci ohos_sdk_modules = { 865f9996aaSopenharmony_ci {% for item in sdk_targets %} 875f9996aaSopenharmony_ci 885f9996aaSopenharmony_ci {% set sdk_type = item.get('type') %} 895f9996aaSopenharmony_ci {% set targets = item.get('targets') %} 905f9996aaSopenharmony_ci {% set systems = targets.keys() %} 915f9996aaSopenharmony_ci {% set _sdk_type = sdk_type.replace('-', '_') %} 925f9996aaSopenharmony_ci 935f9996aaSopenharmony_ci {{ _sdk_type }} = { 945f9996aaSopenharmony_ci {% for os in systems %} 955f9996aaSopenharmony_ci {{ os }} = [ 965f9996aaSopenharmony_ci {% for t in targets.get(os).get_targets() %} 975f9996aaSopenharmony_ci {{ t }} 985f9996aaSopenharmony_ci {% endfor %} 995f9996aaSopenharmony_ci ] 1005f9996aaSopenharmony_ci {% endfor %} 1015f9996aaSopenharmony_ci } 1025f9996aaSopenharmony_ci {% endfor %} 1035f9996aaSopenharmony_ci 1045f9996aaSopenharmony_ci extras = [ 1055f9996aaSopenharmony_ci {% for t in build_only_targets%} 1065f9996aaSopenharmony_ci "{{ t }}", 1075f9996aaSopenharmony_ci {% endfor %} 1085f9996aaSopenharmony_ci ] 1095f9996aaSopenharmony_ci } 1105f9996aaSopenharmony_ci """, # noqa E501 1115f9996aaSopenharmony_ci trim_blocks=True, 1125f9996aaSopenharmony_ci lstrip_blocks=True) 1135f9996aaSopenharmony_ci 1145f9996aaSopenharmony_ci contents = template.render( 1155f9996aaSopenharmony_ci sdk_targets=sdk_targets, build_only_targets=build_only_targets) 1165f9996aaSopenharmony_ci write_file(gni, contents) 1175f9996aaSopenharmony_ci 1185f9996aaSopenharmony_ci 1195f9996aaSopenharmony_cidef get_build_gn(label: str): 1205f9996aaSopenharmony_ci match = re.search(r"(.*?):(.*?)", label) 1215f9996aaSopenharmony_ci if match: 1225f9996aaSopenharmony_ci gn = '{}/BUILD.gn'.format(match.group(1)) 1235f9996aaSopenharmony_ci if gn.startswith("//"): 1245f9996aaSopenharmony_ci return gn[len("//"):] 1255f9996aaSopenharmony_ci else: 1265f9996aaSopenharmony_ci return gn 1275f9996aaSopenharmony_ci else: 1285f9996aaSopenharmony_ci raise Exception("failed to get BUILD.gn of {}".format(label)) 1295f9996aaSopenharmony_ci 1305f9996aaSopenharmony_ci 1315f9996aaSopenharmony_cidef variant_to_product(variant: dict, options: dict): 1325f9996aaSopenharmony_ci relations = read_json_file(options.variant_to_product) 1335f9996aaSopenharmony_ci if variant in relations.keys(): 1345f9996aaSopenharmony_ci return relations.get(variant) 1355f9996aaSopenharmony_ci else: 1365f9996aaSopenharmony_ci raise Exception('Error: failed to read {} in {}'.format( 1375f9996aaSopenharmony_ci variant, options.variant_to_product)) 1385f9996aaSopenharmony_ci 1395f9996aaSopenharmony_ci 1405f9996aaSopenharmony_cidef expand_platform_targets(options, label: str, install_dir: str): 1415f9996aaSopenharmony_ci base = options.base_platform 1425f9996aaSopenharmony_ci platforms = options.platforms 1435f9996aaSopenharmony_ci variant = list(set(platforms) - set([base])) 1445f9996aaSopenharmony_ci 1455f9996aaSopenharmony_ci if label.find('${base}') != -1: 1465f9996aaSopenharmony_ci return [label.replace('${base}', base)], [install_dir] 1475f9996aaSopenharmony_ci elif label.find('${platforms}') != -1: 1485f9996aaSopenharmony_ci return [label.replace('${platforms}', p) for p in platforms], [ 1495f9996aaSopenharmony_ci install_dir.replace('${platforms}', 1505f9996aaSopenharmony_ci variant_to_product(c, options)) 1515f9996aaSopenharmony_ci for c in platforms 1525f9996aaSopenharmony_ci ] 1535f9996aaSopenharmony_ci elif label.find('${variant}') != -1: 1545f9996aaSopenharmony_ci return [label.replace('${variant}', c) for c in variant], [ 1555f9996aaSopenharmony_ci install_dir.replace('${variant}', variant_to_product(c, options)) 1565f9996aaSopenharmony_ci for c in variant 1575f9996aaSopenharmony_ci ] 1585f9996aaSopenharmony_ci else: 1595f9996aaSopenharmony_ci return [label], [install_dir] 1605f9996aaSopenharmony_ci 1615f9996aaSopenharmony_ci 1625f9996aaSopenharmony_cidef add_sdk_targets(sdk_type, sdk_targets): 1635f9996aaSopenharmony_ci sdk_targets.append({ 1645f9996aaSopenharmony_ci 'type': sdk_type, 1655f9996aaSopenharmony_ci 'targets': { 1665f9996aaSopenharmony_ci 'linux': SdkTargets('linux'), 1675f9996aaSopenharmony_ci 'windows': SdkTargets('windows'), 1685f9996aaSopenharmony_ci 'darwin': SdkTargets('darwin'), 1695f9996aaSopenharmony_ci 'ohos': SdkTargets('ohos') 1705f9996aaSopenharmony_ci } 1715f9996aaSopenharmony_ci }) 1725f9996aaSopenharmony_ci 1735f9996aaSopenharmony_ci 1745f9996aaSopenharmony_cidef parse_description_file(options): 1755f9996aaSopenharmony_ci data = read_json_file(options.sdk_description_file) 1765f9996aaSopenharmony_ci if data is None: 1775f9996aaSopenharmony_ci raise Exception("read file '{}' failed.".format( 1785f9996aaSopenharmony_ci options.sdk_description_file)) 1795f9996aaSopenharmony_ci 1805f9996aaSopenharmony_ci module_install_infos = [] 1815f9996aaSopenharmony_ci sdk_types = [] 1825f9996aaSopenharmony_ci sdk_targets = [] 1835f9996aaSopenharmony_ci build_only_targets = [] 1845f9996aaSopenharmony_ci 1855f9996aaSopenharmony_ci for d in data: 1865f9996aaSopenharmony_ci check_keys(d.keys()) 1875f9996aaSopenharmony_ci 1885f9996aaSopenharmony_ci label = d.get('module_label') 1895f9996aaSopenharmony_ci install_dir = d.get('install_dir') 1905f9996aaSopenharmony_ci build_only = d.get('build_only') 1915f9996aaSopenharmony_ci 1925f9996aaSopenharmony_ci # skip labels that we cannot find. 1935f9996aaSopenharmony_ci rebased_build_gn = build_utils.rebase_path( 1945f9996aaSopenharmony_ci get_build_gn(label), current_base=options.source_root_dir) 1955f9996aaSopenharmony_ci if not os.path.exists(rebased_build_gn): 1965f9996aaSopenharmony_ci continue 1975f9996aaSopenharmony_ci 1985f9996aaSopenharmony_ci if build_only: 1995f9996aaSopenharmony_ci build_only_targets.append(label) 2005f9996aaSopenharmony_ci continue 2015f9996aaSopenharmony_ci 2025f9996aaSopenharmony_ci module_labels, install_dirs = expand_platform_targets( 2035f9996aaSopenharmony_ci options, label, install_dir) 2045f9996aaSopenharmony_ci target_os = d.get('target_os') 2055f9996aaSopenharmony_ci 2065f9996aaSopenharmony_ci sdk_type = get_sdk_type(install_dir) 2075f9996aaSopenharmony_ci 2085f9996aaSopenharmony_ci if sdk_type not in sdk_types: 2095f9996aaSopenharmony_ci add_sdk_targets(sdk_type, sdk_targets) 2105f9996aaSopenharmony_ci sdk_types.append(sdk_type) 2115f9996aaSopenharmony_ci 2125f9996aaSopenharmony_ci for item in sdk_targets: 2135f9996aaSopenharmony_ci if item['type'] == sdk_type: 2145f9996aaSopenharmony_ci for m in module_labels: 2155f9996aaSopenharmony_ci add_target(item, m, target_os) 2165f9996aaSopenharmony_ci 2175f9996aaSopenharmony_ci for label, install_dir in zip(module_labels, install_dirs): 2185f9996aaSopenharmony_ci install_info = { 2195f9996aaSopenharmony_ci 'label': label, 2205f9996aaSopenharmony_ci 'install_dir': install_dir 2215f9996aaSopenharmony_ci } 2225f9996aaSopenharmony_ci module_install_infos.append(install_info) 2235f9996aaSopenharmony_ci 2245f9996aaSopenharmony_ci return { 2255f9996aaSopenharmony_ci "sdk_targets": sdk_targets, 2265f9996aaSopenharmony_ci "install_infos": module_install_infos, 2275f9996aaSopenharmony_ci "sdk_types": sdk_types, 2285f9996aaSopenharmony_ci "build_only_targets": build_only_targets 2295f9996aaSopenharmony_ci } 2305f9996aaSopenharmony_ci 2315f9996aaSopenharmony_ci 2325f9996aaSopenharmony_cidef main(): 2335f9996aaSopenharmony_ci parser = argparse.ArgumentParser() 2345f9996aaSopenharmony_ci parser.add_argument('--sdk-description-file', required=True) 2355f9996aaSopenharmony_ci parser.add_argument('--sdk-install-info-file', required=True) 2365f9996aaSopenharmony_ci parser.add_argument('--sdk-modules-gni', required=True) 2375f9996aaSopenharmony_ci parser.add_argument('--sdk-types-file', required=True) 2385f9996aaSopenharmony_ci parser.add_argument('--base-platform', required=True) 2395f9996aaSopenharmony_ci parser.add_argument('--platforms', action='append', required=True) 2405f9996aaSopenharmony_ci parser.add_argument('--source-root-dir', required=True) 2415f9996aaSopenharmony_ci parser.add_argument('--variant-to-product', required=True) 2425f9996aaSopenharmony_ci parser.add_argument('--node-js', required=True) 2435f9996aaSopenharmony_ci 2445f9996aaSopenharmony_ci options = parser.parse_args() 2455f9996aaSopenharmony_ci 2465f9996aaSopenharmony_ci convert_permissions(options.source_root_dir, options.node_js) 2475f9996aaSopenharmony_ci 2485f9996aaSopenharmony_ci data = parse_description_file(options) 2495f9996aaSopenharmony_ci 2505f9996aaSopenharmony_ci write_sdk_build_gni( 2515f9996aaSopenharmony_ci data.get('sdk_targets'), data.get('build_only_targets'), 2525f9996aaSopenharmony_ci options.sdk_modules_gni) 2535f9996aaSopenharmony_ci write_json_file(options.sdk_install_info_file, data.get('install_infos')) 2545f9996aaSopenharmony_ci with open(options.sdk_types_file, 'w') as f: 2555f9996aaSopenharmony_ci f.write('\n'.join(data.get('sdk_types'))) 2565f9996aaSopenharmony_ci 2575f9996aaSopenharmony_ci 2585f9996aaSopenharmony_ciif __name__ == '__main__': 2595f9996aaSopenharmony_ci sys.exit(main()) 260