1*c2e18aaaSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*c2e18aaaSAndroid Build Coastguard Worker# 3*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2018 - The Android Open Source Project 4*c2e18aaaSAndroid Build Coastguard Worker# 5*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*c2e18aaaSAndroid Build Coastguard Worker# 9*c2e18aaaSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*c2e18aaaSAndroid Build Coastguard Worker# 11*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License. 16*c2e18aaaSAndroid Build Coastguard Worker 17*c2e18aaaSAndroid Build Coastguard Worker"""module_info_util 18*c2e18aaaSAndroid Build Coastguard Worker 19*c2e18aaaSAndroid Build Coastguard WorkerThis module receives a module path which is relative to its root directory and 20*c2e18aaaSAndroid Build Coastguard Workermakes a command to generate two json files, one for mk files and one for bp 21*c2e18aaaSAndroid Build Coastguard Workerfiles. Then it will load these two json files into two json dictionaries, 22*c2e18aaaSAndroid Build Coastguard Workermerge them into one dictionary and return the merged dictionary to its caller. 23*c2e18aaaSAndroid Build Coastguard Worker 24*c2e18aaaSAndroid Build Coastguard WorkerExample usage: 25*c2e18aaaSAndroid Build Coastguard Workermerged_dict = generate_merged_module_info() 26*c2e18aaaSAndroid Build Coastguard Worker""" 27*c2e18aaaSAndroid Build Coastguard Worker 28*c2e18aaaSAndroid Build Coastguard Workerimport glob 29*c2e18aaaSAndroid Build Coastguard Workerimport logging 30*c2e18aaaSAndroid Build Coastguard Workerimport os 31*c2e18aaaSAndroid Build Coastguard Workerimport sys 32*c2e18aaaSAndroid Build Coastguard Worker 33*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import constant 34*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import common_util 35*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import errors 36*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import project_config 37*c2e18aaaSAndroid Build Coastguard Worker 38*c2e18aaaSAndroid Build Coastguard Workerfrom atest import atest_utils 39*c2e18aaaSAndroid Build Coastguard Worker 40*c2e18aaaSAndroid Build Coastguard Worker_MERGE_NEEDED_ITEMS = [ 41*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_CLASS, 42*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_PATH, 43*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_INSTALLED, 44*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_DEPENDENCIES, 45*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_SRCS, 46*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_SRCJARS, 47*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_CLASSES_JAR, 48*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_TAG, 49*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_COMPATIBILITY, 50*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_AUTO_TEST_CONFIG, 51*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_MODULE_NAME, 52*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_TEST_CONFIG 53*c2e18aaaSAndroid Build Coastguard Worker] 54*c2e18aaaSAndroid Build Coastguard Worker_INTELLIJ_PROJECT_FILE_EXT = '*.iml' 55*c2e18aaaSAndroid Build Coastguard Worker_LAUNCH_PROJECT_QUERY = ( 56*c2e18aaaSAndroid Build Coastguard Worker 'There exists an IntelliJ project file: %s. Do you want ' 57*c2e18aaaSAndroid Build Coastguard Worker 'to launch it (yes/No)?') 58*c2e18aaaSAndroid Build Coastguard Worker_BUILD_BP_JSON_ENV_ON = { 59*c2e18aaaSAndroid Build Coastguard Worker constant.GEN_JAVA_DEPS: 'true', 60*c2e18aaaSAndroid Build Coastguard Worker constant.GEN_CC_DEPS: 'true', 61*c2e18aaaSAndroid Build Coastguard Worker constant.GEN_COMPDB: 'true', 62*c2e18aaaSAndroid Build Coastguard Worker constant.GEN_RUST: 'true' 63*c2e18aaaSAndroid Build Coastguard Worker} 64*c2e18aaaSAndroid Build Coastguard Worker_GEN_JSON_FAILED = ( 65*c2e18aaaSAndroid Build Coastguard Worker 'Generate new {0} failed, AIDEGen will proceed and reuse the old {1}.') 66*c2e18aaaSAndroid Build Coastguard Worker_TARGET = 'nothing' 67*c2e18aaaSAndroid Build Coastguard Worker_LINKFILE_WARNING = ( 68*c2e18aaaSAndroid Build Coastguard Worker 'File {} does not exist and we can not make a symbolic link for it.') 69*c2e18aaaSAndroid Build Coastguard Worker_RUST_PROJECT_JSON = 'out/soong/rust-project.json' 70*c2e18aaaSAndroid Build Coastguard Worker 71*c2e18aaaSAndroid Build Coastguard Worker 72*c2e18aaaSAndroid Build Coastguard Worker# Generators are slightly more inefficient when all the values have to be 73*c2e18aaaSAndroid Build Coastguard Worker# traversed most of the time. 74*c2e18aaaSAndroid Build Coastguard Worker# pylint: disable=use-a-generator 75*c2e18aaaSAndroid Build Coastguard Worker# pylint: disable=dangerous-default-value 76*c2e18aaaSAndroid Build Coastguard Worker@common_util.back_to_cwd 77*c2e18aaaSAndroid Build Coastguard Worker@common_util.time_logged 78*c2e18aaaSAndroid Build Coastguard Workerdef generate_merged_module_info(env_on=_BUILD_BP_JSON_ENV_ON): 79*c2e18aaaSAndroid Build Coastguard Worker """Generate a merged dictionary. 80*c2e18aaaSAndroid Build Coastguard Worker 81*c2e18aaaSAndroid Build Coastguard Worker Linked functions: 82*c2e18aaaSAndroid Build Coastguard Worker _build_bp_info(module_info, project, skip_build) 83*c2e18aaaSAndroid Build Coastguard Worker _get_soong_build_json_dict() 84*c2e18aaaSAndroid Build Coastguard Worker _merge_dict(mk_dict, bp_dict) 85*c2e18aaaSAndroid Build Coastguard Worker 86*c2e18aaaSAndroid Build Coastguard Worker Args: 87*c2e18aaaSAndroid Build Coastguard Worker env_on: A dictionary of environment settings to be turned on, the 88*c2e18aaaSAndroid Build Coastguard Worker default value is _BUILD_BP_JSON_ENV_ON. 89*c2e18aaaSAndroid Build Coastguard Worker 90*c2e18aaaSAndroid Build Coastguard Worker Returns: 91*c2e18aaaSAndroid Build Coastguard Worker A merged dictionary from module-info.json and module_bp_java_deps.json. 92*c2e18aaaSAndroid Build Coastguard Worker """ 93*c2e18aaaSAndroid Build Coastguard Worker config = project_config.ProjectConfig.get_instance() 94*c2e18aaaSAndroid Build Coastguard Worker module_info = config.atest_module_info 95*c2e18aaaSAndroid Build Coastguard Worker projects = config.targets 96*c2e18aaaSAndroid Build Coastguard Worker verbose = True 97*c2e18aaaSAndroid Build Coastguard Worker skip_build = config.is_skip_build 98*c2e18aaaSAndroid Build Coastguard Worker main_project = projects[0] if projects else None 99*c2e18aaaSAndroid Build Coastguard Worker _build_bp_info( 100*c2e18aaaSAndroid Build Coastguard Worker module_info, main_project, skip_build, env_on) 101*c2e18aaaSAndroid Build Coastguard Worker json_path = common_util.get_blueprint_json_path( 102*c2e18aaaSAndroid Build Coastguard Worker constant.BLUEPRINT_JAVA_JSONFILE_NAME) 103*c2e18aaaSAndroid Build Coastguard Worker bp_dict = common_util.get_json_dict(json_path) 104*c2e18aaaSAndroid Build Coastguard Worker return _merge_dict(module_info.name_to_module_info, bp_dict) 105*c2e18aaaSAndroid Build Coastguard Worker 106*c2e18aaaSAndroid Build Coastguard Worker 107*c2e18aaaSAndroid Build Coastguard Workerdef _build_bp_info(module_info, main_project=None, 108*c2e18aaaSAndroid Build Coastguard Worker skip_build=False, env_on=_BUILD_BP_JSON_ENV_ON): 109*c2e18aaaSAndroid Build Coastguard Worker """Make nothing to create module_bp_java_deps.json, module_bp_cc_deps.json. 110*c2e18aaaSAndroid Build Coastguard Worker 111*c2e18aaaSAndroid Build Coastguard Worker Use atest build method to build the target 'nothing' by setting env config 112*c2e18aaaSAndroid Build Coastguard Worker SOONG_COLLECT_JAVA_DEPS to true to trigger the process of collecting 113*c2e18aaaSAndroid Build Coastguard Worker dependencies and generate module_bp_java_deps.json etc. 114*c2e18aaaSAndroid Build Coastguard Worker 115*c2e18aaaSAndroid Build Coastguard Worker Args: 116*c2e18aaaSAndroid Build Coastguard Worker module_info: A ModuleInfo instance contains data of module-info.json. 117*c2e18aaaSAndroid Build Coastguard Worker main_project: A string of the main project name. 118*c2e18aaaSAndroid Build Coastguard Worker skip_build: A boolean, if true, skip building if 119*c2e18aaaSAndroid Build Coastguard Worker get_blueprint_json_path(file_name) file exists, otherwise 120*c2e18aaaSAndroid Build Coastguard Worker build it. 121*c2e18aaaSAndroid Build Coastguard Worker env_on: A dictionary of environment settings to be turned on, the 122*c2e18aaaSAndroid Build Coastguard Worker default value is _BUILD_BP_JSON_ENV_ON. 123*c2e18aaaSAndroid Build Coastguard Worker 124*c2e18aaaSAndroid Build Coastguard Worker Build results: 125*c2e18aaaSAndroid Build Coastguard Worker 1. Build successfully return. 126*c2e18aaaSAndroid Build Coastguard Worker 2. Build failed: 127*c2e18aaaSAndroid Build Coastguard Worker 1) There's no project file, raise BuildFailureError. 128*c2e18aaaSAndroid Build Coastguard Worker 2) There exists a project file, ask users if they want to 129*c2e18aaaSAndroid Build Coastguard Worker launch IDE with the old project file. 130*c2e18aaaSAndroid Build Coastguard Worker a) If the answer is yes, return. 131*c2e18aaaSAndroid Build Coastguard Worker b) If the answer is not yes, sys.exit(1) 132*c2e18aaaSAndroid Build Coastguard Worker """ 133*c2e18aaaSAndroid Build Coastguard Worker file_paths = _get_generated_json_files(env_on) 134*c2e18aaaSAndroid Build Coastguard Worker files_exist = all([os.path.isfile(fpath) for fpath in file_paths]) 135*c2e18aaaSAndroid Build Coastguard Worker files = '\n'.join(file_paths) 136*c2e18aaaSAndroid Build Coastguard Worker if skip_build and files_exist: 137*c2e18aaaSAndroid Build Coastguard Worker logging.info('Files:\n%s exist, skipping build.', files) 138*c2e18aaaSAndroid Build Coastguard Worker return 139*c2e18aaaSAndroid Build Coastguard Worker original_file_mtimes = {f: None for f in file_paths} 140*c2e18aaaSAndroid Build Coastguard Worker if files_exist: 141*c2e18aaaSAndroid Build Coastguard Worker original_file_mtimes = {f: os.path.getmtime(f) for f in file_paths} 142*c2e18aaaSAndroid Build Coastguard Worker 143*c2e18aaaSAndroid Build Coastguard Worker logging.warning( 144*c2e18aaaSAndroid Build Coastguard Worker '\nGenerate files:\n %s by atest build method.', files) 145*c2e18aaaSAndroid Build Coastguard Worker atest_utils.update_build_env(env_on) 146*c2e18aaaSAndroid Build Coastguard Worker build_with_on_cmd = atest_utils.build([_TARGET]) 147*c2e18aaaSAndroid Build Coastguard Worker 148*c2e18aaaSAndroid Build Coastguard Worker # For Android Rust projects, we need to create a symbolic link to the file 149*c2e18aaaSAndroid Build Coastguard Worker # out/soong/rust-project.json to launch the rust projects in IDEs. 150*c2e18aaaSAndroid Build Coastguard Worker _generate_rust_project_link() 151*c2e18aaaSAndroid Build Coastguard Worker 152*c2e18aaaSAndroid Build Coastguard Worker if build_with_on_cmd: 153*c2e18aaaSAndroid Build Coastguard Worker logging.info('Generate blueprint json successfully.') 154*c2e18aaaSAndroid Build Coastguard Worker else: 155*c2e18aaaSAndroid Build Coastguard Worker if not all([_is_new_json_file_generated( 156*c2e18aaaSAndroid Build Coastguard Worker f, original_file_mtimes[f]) for f in file_paths]): 157*c2e18aaaSAndroid Build Coastguard Worker if files_exist: 158*c2e18aaaSAndroid Build Coastguard Worker _show_files_reuse_message(file_paths) 159*c2e18aaaSAndroid Build Coastguard Worker else: 160*c2e18aaaSAndroid Build Coastguard Worker _show_build_failed_message(module_info, main_project) 161*c2e18aaaSAndroid Build Coastguard Worker 162*c2e18aaaSAndroid Build Coastguard Worker 163*c2e18aaaSAndroid Build Coastguard Workerdef _get_generated_json_files(env_on=_BUILD_BP_JSON_ENV_ON): 164*c2e18aaaSAndroid Build Coastguard Worker """Gets the absolute paths of the files which is going to be generated. 165*c2e18aaaSAndroid Build Coastguard Worker 166*c2e18aaaSAndroid Build Coastguard Worker Determine the files which will be generated by the environment on dictionary 167*c2e18aaaSAndroid Build Coastguard Worker and the default blueprint json files' dictionary. 168*c2e18aaaSAndroid Build Coastguard Worker The generation of json files depends on env_on. If the env_on looks like, 169*c2e18aaaSAndroid Build Coastguard Worker _BUILD_BP_JSON_ENV_ON = { 170*c2e18aaaSAndroid Build Coastguard Worker 'SOONG_COLLECT_JAVA_DEPS': 'true', 171*c2e18aaaSAndroid Build Coastguard Worker 'SOONG_COLLECT_CC_DEPS': 'true', 172*c2e18aaaSAndroid Build Coastguard Worker 'SOONG_GEN_COMPDB': 'true', 173*c2e18aaaSAndroid Build Coastguard Worker 'SOONG_GEN_RUST_PROJECT': 'true' 174*c2e18aaaSAndroid Build Coastguard Worker } 175*c2e18aaaSAndroid Build Coastguard Worker We want to generate 4 files: module_bp_java_deps.json, 176*c2e18aaaSAndroid Build Coastguard Worker module_bp_cc_deps.json, compile_commands.json and rust-project.json. And in 177*c2e18aaaSAndroid Build Coastguard Worker get_blueprint_json_files_relative_dict function, there are 4 json files 178*c2e18aaaSAndroid Build Coastguard Worker by default and return a result list of the absolute paths of the existent 179*c2e18aaaSAndroid Build Coastguard Worker files. 180*c2e18aaaSAndroid Build Coastguard Worker 181*c2e18aaaSAndroid Build Coastguard Worker Args: 182*c2e18aaaSAndroid Build Coastguard Worker env_on: A dictionary of environment settings to be turned on, the 183*c2e18aaaSAndroid Build Coastguard Worker default value is _BUILD_BP_JSON_ENV_ON. 184*c2e18aaaSAndroid Build Coastguard Worker 185*c2e18aaaSAndroid Build Coastguard Worker Returns: 186*c2e18aaaSAndroid Build Coastguard Worker A list of the absolute paths of the files which is going to be 187*c2e18aaaSAndroid Build Coastguard Worker generated. 188*c2e18aaaSAndroid Build Coastguard Worker """ 189*c2e18aaaSAndroid Build Coastguard Worker json_files_dict = common_util.get_blueprint_json_files_relative_dict() 190*c2e18aaaSAndroid Build Coastguard Worker file_paths = [] 191*c2e18aaaSAndroid Build Coastguard Worker for key in env_on: 192*c2e18aaaSAndroid Build Coastguard Worker if not env_on[key] == 'true' or key not in json_files_dict: 193*c2e18aaaSAndroid Build Coastguard Worker continue 194*c2e18aaaSAndroid Build Coastguard Worker file_paths.append(json_files_dict[key]) 195*c2e18aaaSAndroid Build Coastguard Worker return file_paths 196*c2e18aaaSAndroid Build Coastguard Worker 197*c2e18aaaSAndroid Build Coastguard Worker 198*c2e18aaaSAndroid Build Coastguard Workerdef _show_files_reuse_message(file_paths): 199*c2e18aaaSAndroid Build Coastguard Worker """Shows the message of build failure but files existing and reusing them. 200*c2e18aaaSAndroid Build Coastguard Worker 201*c2e18aaaSAndroid Build Coastguard Worker Args: 202*c2e18aaaSAndroid Build Coastguard Worker file_paths: A list of absolute file paths to be checked. 203*c2e18aaaSAndroid Build Coastguard Worker """ 204*c2e18aaaSAndroid Build Coastguard Worker failed_or_file = ' or '.join(file_paths) 205*c2e18aaaSAndroid Build Coastguard Worker failed_and_file = ' and '.join(file_paths) 206*c2e18aaaSAndroid Build Coastguard Worker message = _GEN_JSON_FAILED.format(failed_or_file, failed_and_file) 207*c2e18aaaSAndroid Build Coastguard Worker print(constant.WARN_MSG.format( 208*c2e18aaaSAndroid Build Coastguard Worker common_util.COLORED_INFO('Warning:'), message)) 209*c2e18aaaSAndroid Build Coastguard Worker 210*c2e18aaaSAndroid Build Coastguard Worker 211*c2e18aaaSAndroid Build Coastguard Workerdef _show_build_failed_message(module_info, main_project=None): 212*c2e18aaaSAndroid Build Coastguard Worker """Show build failed message. 213*c2e18aaaSAndroid Build Coastguard Worker 214*c2e18aaaSAndroid Build Coastguard Worker Args: 215*c2e18aaaSAndroid Build Coastguard Worker module_info: A ModuleInfo instance contains data of module-info.json. 216*c2e18aaaSAndroid Build Coastguard Worker main_project: A string of the main project name. 217*c2e18aaaSAndroid Build Coastguard Worker """ 218*c2e18aaaSAndroid Build Coastguard Worker if main_project: 219*c2e18aaaSAndroid Build Coastguard Worker _, main_project_path = common_util.get_related_paths( 220*c2e18aaaSAndroid Build Coastguard Worker module_info, main_project) 221*c2e18aaaSAndroid Build Coastguard Worker _build_failed_handle(main_project_path) 222*c2e18aaaSAndroid Build Coastguard Worker 223*c2e18aaaSAndroid Build Coastguard Worker 224*c2e18aaaSAndroid Build Coastguard Workerdef _is_new_json_file_generated(json_path, original_file_mtime): 225*c2e18aaaSAndroid Build Coastguard Worker """Check the new file is generated or not. 226*c2e18aaaSAndroid Build Coastguard Worker 227*c2e18aaaSAndroid Build Coastguard Worker Args: 228*c2e18aaaSAndroid Build Coastguard Worker json_path: The path of the json file being to check. 229*c2e18aaaSAndroid Build Coastguard Worker original_file_mtime: the original file modified time. 230*c2e18aaaSAndroid Build Coastguard Worker 231*c2e18aaaSAndroid Build Coastguard Worker Returns: 232*c2e18aaaSAndroid Build Coastguard Worker A boolean, True if the json_path file is new generated, otherwise False. 233*c2e18aaaSAndroid Build Coastguard Worker """ 234*c2e18aaaSAndroid Build Coastguard Worker if not os.path.isfile(json_path): 235*c2e18aaaSAndroid Build Coastguard Worker return False 236*c2e18aaaSAndroid Build Coastguard Worker return original_file_mtime != os.path.getmtime(json_path) 237*c2e18aaaSAndroid Build Coastguard Worker 238*c2e18aaaSAndroid Build Coastguard Worker 239*c2e18aaaSAndroid Build Coastguard Workerdef _build_failed_handle(main_project_path): 240*c2e18aaaSAndroid Build Coastguard Worker """Handle build failures. 241*c2e18aaaSAndroid Build Coastguard Worker 242*c2e18aaaSAndroid Build Coastguard Worker Args: 243*c2e18aaaSAndroid Build Coastguard Worker main_project_path: The main project directory. 244*c2e18aaaSAndroid Build Coastguard Worker 245*c2e18aaaSAndroid Build Coastguard Worker Handle results: 246*c2e18aaaSAndroid Build Coastguard Worker 1) There's no project file, raise BuildFailureError. 247*c2e18aaaSAndroid Build Coastguard Worker 2) There exists a project file, ask users if they want to 248*c2e18aaaSAndroid Build Coastguard Worker launch IDE with the old project file. 249*c2e18aaaSAndroid Build Coastguard Worker a) If the answer is yes, return. 250*c2e18aaaSAndroid Build Coastguard Worker b) If the answer is not yes, sys.exit(1) 251*c2e18aaaSAndroid Build Coastguard Worker """ 252*c2e18aaaSAndroid Build Coastguard Worker project_file = glob.glob( 253*c2e18aaaSAndroid Build Coastguard Worker os.path.join(main_project_path, _INTELLIJ_PROJECT_FILE_EXT)) 254*c2e18aaaSAndroid Build Coastguard Worker if project_file: 255*c2e18aaaSAndroid Build Coastguard Worker query = _LAUNCH_PROJECT_QUERY % project_file[0] 256*c2e18aaaSAndroid Build Coastguard Worker input_data = input(query) 257*c2e18aaaSAndroid Build Coastguard Worker if not input_data.lower() in ['yes', 'y']: 258*c2e18aaaSAndroid Build Coastguard Worker sys.exit(1) 259*c2e18aaaSAndroid Build Coastguard Worker else: 260*c2e18aaaSAndroid Build Coastguard Worker raise errors.BuildFailureError( 261*c2e18aaaSAndroid Build Coastguard Worker 'Failed to generate %s.' % common_util.get_blueprint_json_path( 262*c2e18aaaSAndroid Build Coastguard Worker constant.BLUEPRINT_JAVA_JSONFILE_NAME)) 263*c2e18aaaSAndroid Build Coastguard Worker 264*c2e18aaaSAndroid Build Coastguard Worker 265*c2e18aaaSAndroid Build Coastguard Workerdef _merge_module_keys(m_dict, b_dict): 266*c2e18aaaSAndroid Build Coastguard Worker """Merge a module's dictionary into another module's dictionary. 267*c2e18aaaSAndroid Build Coastguard Worker 268*c2e18aaaSAndroid Build Coastguard Worker Merge b_dict module data into m_dict. 269*c2e18aaaSAndroid Build Coastguard Worker 270*c2e18aaaSAndroid Build Coastguard Worker Args: 271*c2e18aaaSAndroid Build Coastguard Worker m_dict: The module dictionary is going to merge b_dict into. 272*c2e18aaaSAndroid Build Coastguard Worker b_dict: Soong build system module dictionary. 273*c2e18aaaSAndroid Build Coastguard Worker """ 274*c2e18aaaSAndroid Build Coastguard Worker for key, b_modules in b_dict.items(): 275*c2e18aaaSAndroid Build Coastguard Worker m_dict[key] = sorted(list(set(m_dict.get(key, []) + b_modules))) 276*c2e18aaaSAndroid Build Coastguard Worker 277*c2e18aaaSAndroid Build Coastguard Worker 278*c2e18aaaSAndroid Build Coastguard Workerdef _copy_needed_items_from(mk_dict): 279*c2e18aaaSAndroid Build Coastguard Worker """Shallow copy needed items from Make build system module info dictionary. 280*c2e18aaaSAndroid Build Coastguard Worker 281*c2e18aaaSAndroid Build Coastguard Worker Args: 282*c2e18aaaSAndroid Build Coastguard Worker mk_dict: Make build system dictionary is going to be copied. 283*c2e18aaaSAndroid Build Coastguard Worker 284*c2e18aaaSAndroid Build Coastguard Worker Returns: 285*c2e18aaaSAndroid Build Coastguard Worker A merged dictionary. 286*c2e18aaaSAndroid Build Coastguard Worker """ 287*c2e18aaaSAndroid Build Coastguard Worker merged_dict = {} 288*c2e18aaaSAndroid Build Coastguard Worker for module in mk_dict.keys(): 289*c2e18aaaSAndroid Build Coastguard Worker merged_dict[module] = {} 290*c2e18aaaSAndroid Build Coastguard Worker for key in mk_dict[module].keys(): 291*c2e18aaaSAndroid Build Coastguard Worker if key in _MERGE_NEEDED_ITEMS and mk_dict[module][key] != []: 292*c2e18aaaSAndroid Build Coastguard Worker merged_dict[module][key] = mk_dict[module][key] 293*c2e18aaaSAndroid Build Coastguard Worker return merged_dict 294*c2e18aaaSAndroid Build Coastguard Worker 295*c2e18aaaSAndroid Build Coastguard Worker 296*c2e18aaaSAndroid Build Coastguard Workerdef _merge_dict(mk_dict, bp_dict): 297*c2e18aaaSAndroid Build Coastguard Worker """Merge two dictionaries. 298*c2e18aaaSAndroid Build Coastguard Worker 299*c2e18aaaSAndroid Build Coastguard Worker Linked function: 300*c2e18aaaSAndroid Build Coastguard Worker _merge_module_keys(m_dict, b_dict) 301*c2e18aaaSAndroid Build Coastguard Worker 302*c2e18aaaSAndroid Build Coastguard Worker Args: 303*c2e18aaaSAndroid Build Coastguard Worker mk_dict: Make build system module info dictionary. 304*c2e18aaaSAndroid Build Coastguard Worker bp_dict: Soong build system module info dictionary. 305*c2e18aaaSAndroid Build Coastguard Worker 306*c2e18aaaSAndroid Build Coastguard Worker Returns: 307*c2e18aaaSAndroid Build Coastguard Worker A merged dictionary. 308*c2e18aaaSAndroid Build Coastguard Worker """ 309*c2e18aaaSAndroid Build Coastguard Worker merged_dict = _copy_needed_items_from(mk_dict) 310*c2e18aaaSAndroid Build Coastguard Worker for module in bp_dict.keys(): 311*c2e18aaaSAndroid Build Coastguard Worker if module not in merged_dict: 312*c2e18aaaSAndroid Build Coastguard Worker merged_dict[module] = {} 313*c2e18aaaSAndroid Build Coastguard Worker _merge_module_keys(merged_dict[module], bp_dict[module]) 314*c2e18aaaSAndroid Build Coastguard Worker return merged_dict 315*c2e18aaaSAndroid Build Coastguard Worker 316*c2e18aaaSAndroid Build Coastguard Worker 317*c2e18aaaSAndroid Build Coastguard Workerdef _generate_rust_project_link(): 318*c2e18aaaSAndroid Build Coastguard Worker """Generates out/soong/rust-project.json symbolic link in Android root.""" 319*c2e18aaaSAndroid Build Coastguard Worker root_dir = common_util.get_android_root_dir() 320*c2e18aaaSAndroid Build Coastguard Worker rust_project = os.path.join( 321*c2e18aaaSAndroid Build Coastguard Worker root_dir, common_util.get_blueprint_json_path( 322*c2e18aaaSAndroid Build Coastguard Worker constant.RUST_PROJECT_JSON)) 323*c2e18aaaSAndroid Build Coastguard Worker if not os.path.isfile(rust_project): 324*c2e18aaaSAndroid Build Coastguard Worker message = _LINKFILE_WARNING.format(_RUST_PROJECT_JSON) 325*c2e18aaaSAndroid Build Coastguard Worker print(constant.WARN_MSG.format( 326*c2e18aaaSAndroid Build Coastguard Worker common_util.COLORED_INFO('Warning:'), message)) 327*c2e18aaaSAndroid Build Coastguard Worker return 328*c2e18aaaSAndroid Build Coastguard Worker link_rust = os.path.join(root_dir, constant.RUST_PROJECT_JSON) 329*c2e18aaaSAndroid Build Coastguard Worker if os.path.islink(link_rust): 330*c2e18aaaSAndroid Build Coastguard Worker os.remove(link_rust) 331*c2e18aaaSAndroid Build Coastguard Worker os.symlink(rust_project, link_rust) 332