1*6777b538SAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*6777b538SAndroid Build Coastguard Worker# 3*6777b538SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*6777b538SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*6777b538SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*6777b538SAndroid Build Coastguard Worker# 7*6777b538SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*6777b538SAndroid Build Coastguard Worker# 9*6777b538SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*6777b538SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*6777b538SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*6777b538SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*6777b538SAndroid Build Coastguard Worker# limitations under the License. 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker# A collection of utilities for extracting build rule information from GN 16*6777b538SAndroid Build Coastguard Worker# projects. 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Workerimport copy 19*6777b538SAndroid Build Coastguard Workerimport json 20*6777b538SAndroid Build Coastguard Workerimport logging as log 21*6777b538SAndroid Build Coastguard Workerimport os 22*6777b538SAndroid Build Coastguard Workerimport re 23*6777b538SAndroid Build Coastguard Workerimport collections 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard WorkerLINKER_UNIT_TYPES = ('executable', 'shared_library', 'static_library', 'source_set') 26*6777b538SAndroid Build Coastguard Worker# This is a list of java files that should not be collected 27*6777b538SAndroid Build Coastguard Worker# as they don't exist right now downstream (eg: apihelpers, cronetEngineBuilderTest). 28*6777b538SAndroid Build Coastguard Worker# This is temporary solution until they are up-streamed. 29*6777b538SAndroid Build Coastguard WorkerJAVA_FILES_TO_IGNORE = ( 30*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/ByteArrayCronetCallback.java", 31*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/ContentTypeParametersParser.java", 32*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/CronetRequestCompletionListener.java", 33*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/CronetResponse.java", 34*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/ImplicitFlowControlCallback.java", 35*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/InMemoryTransformCronetCallback.java", 36*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/JsonCronetCallback.java", 37*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/RedirectHandler.java", 38*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/RedirectHandlers.java", 39*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/StringCronetCallback.java", 40*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/api/src/org/chromium/net/apihelpers/UrlRequestCallbacks.java", 41*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/test/javatests/src/org/chromium/net/CronetEngineBuilderTest.java", 42*6777b538SAndroid Build Coastguard Worker # Api helpers does not exist downstream, hence the tests shouldn't be collected. 43*6777b538SAndroid Build Coastguard Worker "//components/cronet/android/test/javatests/src/org/chromium/net/apihelpers/ContentTypeParametersParserTest.java", 44*6777b538SAndroid Build Coastguard Worker # androidx-multidex is disabled on unbundled branches. 45*6777b538SAndroid Build Coastguard Worker "//base/test/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java", 46*6777b538SAndroid Build Coastguard Worker # This file is not used in aosp and depends on newer accessibility_test_framework. 47*6777b538SAndroid Build Coastguard Worker "//base/test/android/javatests/src/org/chromium/base/test/BaseActivityTestRule.java", 48*6777b538SAndroid Build Coastguard Worker) 49*6777b538SAndroid Build Coastguard WorkerRESPONSE_FILE = '{{response_file_name}}' 50*6777b538SAndroid Build Coastguard WorkerTESTING_SUFFIX = "__testing" 51*6777b538SAndroid Build Coastguard WorkerAIDL_INCLUDE_DIRS_REGEX = r'--includes=\[(.*)\]' 52*6777b538SAndroid Build Coastguard WorkerAIDL_IMPORT_DIRS_REGEX = r'--imports=\[(.*)\]' 53*6777b538SAndroid Build Coastguard WorkerPROTO_IMPORT_DIRS_REGEX = r'--import-dir=(.*)' 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Workerdef repo_root(): 56*6777b538SAndroid Build Coastguard Worker """Returns an absolute path to the repository root.""" 57*6777b538SAndroid Build Coastguard Worker return os.path.join( 58*6777b538SAndroid Build Coastguard Worker os.path.realpath(os.path.dirname(__file__)), os.path.pardir) 59*6777b538SAndroid Build Coastguard Worker 60*6777b538SAndroid Build Coastguard Workerdef _get_build_path_from_label(target_name: str) -> str: 61*6777b538SAndroid Build Coastguard Worker """Returns the path to the BUILD file for which this target was declared.""" 62*6777b538SAndroid Build Coastguard Worker return target_name[2:].split(":")[0] 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Workerdef _clean_string(str): 65*6777b538SAndroid Build Coastguard Worker return str.replace('\\', '').replace('../../', '').replace('"', '').strip() 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Workerdef _clean_aidl_import(orig_str): 68*6777b538SAndroid Build Coastguard Worker str = _clean_string(orig_str) 69*6777b538SAndroid Build Coastguard Worker src_idx = str.find("src/") 70*6777b538SAndroid Build Coastguard Worker if src_idx == -1: 71*6777b538SAndroid Build Coastguard Worker raise ValueError(f"Unable to clean aidl import {orig_str}") 72*6777b538SAndroid Build Coastguard Worker return str[:src_idx + len("src")] 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Workerdef _extract_includes_from_aidl_args(args): 75*6777b538SAndroid Build Coastguard Worker ret = [] 76*6777b538SAndroid Build Coastguard Worker for arg in args: 77*6777b538SAndroid Build Coastguard Worker is_match = re.match(AIDL_INCLUDE_DIRS_REGEX, arg) 78*6777b538SAndroid Build Coastguard Worker if is_match: 79*6777b538SAndroid Build Coastguard Worker local_includes = is_match.group(1).split(",") 80*6777b538SAndroid Build Coastguard Worker ret += [_clean_string(local_include) for local_include in local_includes] 81*6777b538SAndroid Build Coastguard Worker # Treat imports like include for aidl by removing the package suffix. 82*6777b538SAndroid Build Coastguard Worker is_match = re.match(AIDL_IMPORT_DIRS_REGEX, arg) 83*6777b538SAndroid Build Coastguard Worker if is_match: 84*6777b538SAndroid Build Coastguard Worker local_imports = is_match.group(1).split(",") 85*6777b538SAndroid Build Coastguard Worker # Skip "third_party/android_sdk/public/platforms/android-34/framework.aidl" because Soong 86*6777b538SAndroid Build Coastguard Worker # already links against the AIDL framework implicitly. 87*6777b538SAndroid Build Coastguard Worker ret += [_clean_aidl_import(local_import) for local_import in local_imports 88*6777b538SAndroid Build Coastguard Worker if "framework.aidl" not in local_import] 89*6777b538SAndroid Build Coastguard Worker return ret 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Workerdef contains_aidl(sources): 92*6777b538SAndroid Build Coastguard Worker return any([src.endswith(".aidl") for src in sources]) 93*6777b538SAndroid Build Coastguard Worker 94*6777b538SAndroid Build Coastguard Workerdef _get_jni_registration_deps(gn_target_name, gn_desc): 95*6777b538SAndroid Build Coastguard Worker # the dependencies are stored within another target with the same name 96*6777b538SAndroid Build Coastguard Worker # and a __java_sources suffix, see 97*6777b538SAndroid Build Coastguard Worker # https://source.chromium.org/chromium/chromium/src/+/main:third_party/jni_zero/jni_zero.gni;l=117;drc=78e8e27142ed3fddf04fbcd122507517a87cb9ad 98*6777b538SAndroid Build Coastguard Worker # for the auto-generated target name. 99*6777b538SAndroid Build Coastguard Worker jni_registration_java_target = f'{gn_target_name}__java_sources' 100*6777b538SAndroid Build Coastguard Worker if jni_registration_java_target in gn_desc.keys(): 101*6777b538SAndroid Build Coastguard Worker return gn_desc[jni_registration_java_target]["deps"] 102*6777b538SAndroid Build Coastguard Worker return set() 103*6777b538SAndroid Build Coastguard Worker 104*6777b538SAndroid Build Coastguard Workerdef label_to_path(label): 105*6777b538SAndroid Build Coastguard Worker """Turn a GN output label (e.g., //some_dir/file.cc) into a path.""" 106*6777b538SAndroid Build Coastguard Worker assert label.startswith('//') 107*6777b538SAndroid Build Coastguard Worker return label[2:] or "" 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Workerdef label_without_toolchain(label): 110*6777b538SAndroid Build Coastguard Worker """Strips the toolchain from a GN label. 111*6777b538SAndroid Build Coastguard Worker 112*6777b538SAndroid Build Coastguard Worker Return a GN label (e.g //buildtools:protobuf(//gn/standalone/toolchain: 113*6777b538SAndroid Build Coastguard Worker gcc_like_host) without the parenthesised toolchain part. 114*6777b538SAndroid Build Coastguard Worker """ 115*6777b538SAndroid Build Coastguard Worker return label.split('(')[0] 116*6777b538SAndroid Build Coastguard Worker 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Workerdef _is_java_source(src): 119*6777b538SAndroid Build Coastguard Worker return os.path.splitext(src)[1] == '.java' and not src.startswith("//out/") 120*6777b538SAndroid Build Coastguard Worker 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Workerclass GnParser(object): 123*6777b538SAndroid Build Coastguard Worker """A parser with some cleverness for GN json desc files 124*6777b538SAndroid Build Coastguard Worker 125*6777b538SAndroid Build Coastguard Worker The main goals of this parser are: 126*6777b538SAndroid Build Coastguard Worker 1) Deal with the fact that other build systems don't have an equivalent 127*6777b538SAndroid Build Coastguard Worker notion to GN's source_set. Conversely to Bazel's and Soong's filegroups, 128*6777b538SAndroid Build Coastguard Worker GN source_sets expect that dependencies, cflags and other source_set 129*6777b538SAndroid Build Coastguard Worker properties propagate up to the linker unit (static_library, executable or 130*6777b538SAndroid Build Coastguard Worker shared_library). This parser simulates the same behavior: when a 131*6777b538SAndroid Build Coastguard Worker source_set is encountered, some of its variables (cflags and such) are 132*6777b538SAndroid Build Coastguard Worker copied up to the dependent targets. This is to allow gen_xxx to create 133*6777b538SAndroid Build Coastguard Worker one filegroup for each source_set and then squash all the other flags 134*6777b538SAndroid Build Coastguard Worker onto the linker unit. 135*6777b538SAndroid Build Coastguard Worker 2) Detect and special-case protobuf targets, figuring out the protoc-plugin 136*6777b538SAndroid Build Coastguard Worker being used. 137*6777b538SAndroid Build Coastguard Worker """ 138*6777b538SAndroid Build Coastguard Worker 139*6777b538SAndroid Build Coastguard Worker class Target(object): 140*6777b538SAndroid Build Coastguard Worker """Reperesents A GN target. 141*6777b538SAndroid Build Coastguard Worker 142*6777b538SAndroid Build Coastguard Worker Maked properties are propagated up the dependency chain when a 143*6777b538SAndroid Build Coastguard Worker source_set dependency is encountered. 144*6777b538SAndroid Build Coastguard Worker """ 145*6777b538SAndroid Build Coastguard Worker class Arch(): 146*6777b538SAndroid Build Coastguard Worker """Architecture-dependent properties 147*6777b538SAndroid Build Coastguard Worker """ 148*6777b538SAndroid Build Coastguard Worker def __init__(self): 149*6777b538SAndroid Build Coastguard Worker self.sources = set() 150*6777b538SAndroid Build Coastguard Worker self.cflags = set() 151*6777b538SAndroid Build Coastguard Worker self.defines = set() 152*6777b538SAndroid Build Coastguard Worker self.include_dirs = set() 153*6777b538SAndroid Build Coastguard Worker self.deps = set() 154*6777b538SAndroid Build Coastguard Worker self.transitive_static_libs_deps = set() 155*6777b538SAndroid Build Coastguard Worker self.ldflags = set() 156*6777b538SAndroid Build Coastguard Worker 157*6777b538SAndroid Build Coastguard Worker # These are valid only for type == 'action' 158*6777b538SAndroid Build Coastguard Worker self.inputs = set() 159*6777b538SAndroid Build Coastguard Worker self.outputs = set() 160*6777b538SAndroid Build Coastguard Worker self.args = [] 161*6777b538SAndroid Build Coastguard Worker self.response_file_contents = '' 162*6777b538SAndroid Build Coastguard Worker self.rust_flags = list() 163*6777b538SAndroid Build Coastguard Worker 164*6777b538SAndroid Build Coastguard Worker def __init__(self, name, type): 165*6777b538SAndroid Build Coastguard Worker self.name = name # e.g. //src/ipc:ipc 166*6777b538SAndroid Build Coastguard Worker 167*6777b538SAndroid Build Coastguard Worker VALID_TYPES = ('static_library', 'shared_library', 'executable', 'group', 168*6777b538SAndroid Build Coastguard Worker 'action', 'source_set', 'proto_library', 'copy', 169*6777b538SAndroid Build Coastguard Worker 'action_foreach', 'generated_file', "rust_library", "rust_proc_macro") 170*6777b538SAndroid Build Coastguard Worker assert (type in VALID_TYPES), f"Unable to parse target {name} with type {type}." 171*6777b538SAndroid Build Coastguard Worker self.type = type 172*6777b538SAndroid Build Coastguard Worker self.testonly = False 173*6777b538SAndroid Build Coastguard Worker self.toolchain = None 174*6777b538SAndroid Build Coastguard Worker 175*6777b538SAndroid Build Coastguard Worker # These are valid only for type == proto_library. 176*6777b538SAndroid Build Coastguard Worker # This is typically: 'proto', 'protozero', 'ipc'. 177*6777b538SAndroid Build Coastguard Worker self.proto_plugin = None 178*6777b538SAndroid Build Coastguard Worker self.proto_paths = set() 179*6777b538SAndroid Build Coastguard Worker self.proto_exports = set() 180*6777b538SAndroid Build Coastguard Worker self.proto_in_dir = "" 181*6777b538SAndroid Build Coastguard Worker 182*6777b538SAndroid Build Coastguard Worker # TODO(primiano): consider whether the public section should be part of 183*6777b538SAndroid Build Coastguard Worker # bubbled-up sources. 184*6777b538SAndroid Build Coastguard Worker self.public_headers = set() # 'public' 185*6777b538SAndroid Build Coastguard Worker 186*6777b538SAndroid Build Coastguard Worker # These are valid only for type == 'action' 187*6777b538SAndroid Build Coastguard Worker self.script = '' 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker # These variables are propagated up when encountering a dependency 190*6777b538SAndroid Build Coastguard Worker # on a source_set target. 191*6777b538SAndroid Build Coastguard Worker self.libs = set() 192*6777b538SAndroid Build Coastguard Worker self.proto_deps = set() 193*6777b538SAndroid Build Coastguard Worker self.rtti = False 194*6777b538SAndroid Build Coastguard Worker 195*6777b538SAndroid Build Coastguard Worker # TODO: come up with a better way to only run this once. 196*6777b538SAndroid Build Coastguard Worker # is_finalized tracks whether finalize() was called on this target. 197*6777b538SAndroid Build Coastguard Worker self.is_finalized = False 198*6777b538SAndroid Build Coastguard Worker # 'common' is a pseudo-architecture used to store common architecture dependent properties (to 199*6777b538SAndroid Build Coastguard Worker # make handling of common vs architecture-specific arguments more consistent). 200*6777b538SAndroid Build Coastguard Worker self.arch = {'common': self.Arch()} 201*6777b538SAndroid Build Coastguard Worker 202*6777b538SAndroid Build Coastguard Worker # This is used to get the name/version of libcronet 203*6777b538SAndroid Build Coastguard Worker self.output_name = None 204*6777b538SAndroid Build Coastguard Worker # Local Includes used for AIDL 205*6777b538SAndroid Build Coastguard Worker self.local_aidl_includes = set() 206*6777b538SAndroid Build Coastguard Worker # Each java_target will contain the transitive java sources found 207*6777b538SAndroid Build Coastguard Worker # in generate_jni type target. 208*6777b538SAndroid Build Coastguard Worker self.transitive_jni_java_sources = set() 209*6777b538SAndroid Build Coastguard Worker # Deps for JNI Registration. Those are not added to deps so that 210*6777b538SAndroid Build Coastguard Worker # the generated module would not depend on those deps. 211*6777b538SAndroid Build Coastguard Worker self.jni_registration_java_deps = set() 212*6777b538SAndroid Build Coastguard Worker # Path to the java jar path. This is used if the java library is 213*6777b538SAndroid Build Coastguard Worker # an import of a JAR like `android_java_prebuilt` targets in GN 214*6777b538SAndroid Build Coastguard Worker self.jar_path = "" 215*6777b538SAndroid Build Coastguard Worker self.sdk_version = "" 216*6777b538SAndroid Build Coastguard Worker self.build_file_path = "" 217*6777b538SAndroid Build Coastguard Worker self.crate_name = None 218*6777b538SAndroid Build Coastguard Worker self.crate_root = None 219*6777b538SAndroid Build Coastguard Worker 220*6777b538SAndroid Build Coastguard Worker # Properties to forward access to common arch. 221*6777b538SAndroid Build Coastguard Worker # TODO: delete these after the transition has been completed. 222*6777b538SAndroid Build Coastguard Worker @property 223*6777b538SAndroid Build Coastguard Worker def sources(self): 224*6777b538SAndroid Build Coastguard Worker return self.arch['common'].sources 225*6777b538SAndroid Build Coastguard Worker 226*6777b538SAndroid Build Coastguard Worker @sources.setter 227*6777b538SAndroid Build Coastguard Worker def sources(self, val): 228*6777b538SAndroid Build Coastguard Worker self.arch['common'].sources = val 229*6777b538SAndroid Build Coastguard Worker 230*6777b538SAndroid Build Coastguard Worker @property 231*6777b538SAndroid Build Coastguard Worker def inputs(self): 232*6777b538SAndroid Build Coastguard Worker return self.arch['common'].inputs 233*6777b538SAndroid Build Coastguard Worker 234*6777b538SAndroid Build Coastguard Worker @inputs.setter 235*6777b538SAndroid Build Coastguard Worker def inputs(self, val): 236*6777b538SAndroid Build Coastguard Worker self.arch['common'].inputs = val 237*6777b538SAndroid Build Coastguard Worker 238*6777b538SAndroid Build Coastguard Worker @property 239*6777b538SAndroid Build Coastguard Worker def outputs(self): 240*6777b538SAndroid Build Coastguard Worker return self.arch['common'].outputs 241*6777b538SAndroid Build Coastguard Worker 242*6777b538SAndroid Build Coastguard Worker @outputs.setter 243*6777b538SAndroid Build Coastguard Worker def outputs(self, val): 244*6777b538SAndroid Build Coastguard Worker self.arch['common'].outputs = val 245*6777b538SAndroid Build Coastguard Worker 246*6777b538SAndroid Build Coastguard Worker @property 247*6777b538SAndroid Build Coastguard Worker def args(self): 248*6777b538SAndroid Build Coastguard Worker return self.arch['common'].args 249*6777b538SAndroid Build Coastguard Worker 250*6777b538SAndroid Build Coastguard Worker @args.setter 251*6777b538SAndroid Build Coastguard Worker def args(self, val): 252*6777b538SAndroid Build Coastguard Worker self.arch['common'].args = val 253*6777b538SAndroid Build Coastguard Worker 254*6777b538SAndroid Build Coastguard Worker @property 255*6777b538SAndroid Build Coastguard Worker def response_file_contents(self): 256*6777b538SAndroid Build Coastguard Worker return self.arch['common'].response_file_contents 257*6777b538SAndroid Build Coastguard Worker 258*6777b538SAndroid Build Coastguard Worker @response_file_contents.setter 259*6777b538SAndroid Build Coastguard Worker def response_file_contents(self, val): 260*6777b538SAndroid Build Coastguard Worker self.arch['common'].response_file_contents = val 261*6777b538SAndroid Build Coastguard Worker 262*6777b538SAndroid Build Coastguard Worker @property 263*6777b538SAndroid Build Coastguard Worker def cflags(self): 264*6777b538SAndroid Build Coastguard Worker return self.arch['common'].cflags 265*6777b538SAndroid Build Coastguard Worker 266*6777b538SAndroid Build Coastguard Worker @property 267*6777b538SAndroid Build Coastguard Worker def defines(self): 268*6777b538SAndroid Build Coastguard Worker return self.arch['common'].defines 269*6777b538SAndroid Build Coastguard Worker 270*6777b538SAndroid Build Coastguard Worker @property 271*6777b538SAndroid Build Coastguard Worker def deps(self): 272*6777b538SAndroid Build Coastguard Worker return self.arch['common'].deps 273*6777b538SAndroid Build Coastguard Worker 274*6777b538SAndroid Build Coastguard Worker @deps.setter 275*6777b538SAndroid Build Coastguard Worker def deps(self, val): 276*6777b538SAndroid Build Coastguard Worker self.arch['common'].deps = val 277*6777b538SAndroid Build Coastguard Worker 278*6777b538SAndroid Build Coastguard Worker @property 279*6777b538SAndroid Build Coastguard Worker def rust_flags(self): 280*6777b538SAndroid Build Coastguard Worker return self.arch['common'].rust_flags 281*6777b538SAndroid Build Coastguard Worker 282*6777b538SAndroid Build Coastguard Worker @rust_flags.setter 283*6777b538SAndroid Build Coastguard Worker def rust_flags(self, val): 284*6777b538SAndroid Build Coastguard Worker self.arch['common'].rust_flags = val 285*6777b538SAndroid Build Coastguard Worker 286*6777b538SAndroid Build Coastguard Worker @property 287*6777b538SAndroid Build Coastguard Worker def include_dirs(self): 288*6777b538SAndroid Build Coastguard Worker return self.arch['common'].include_dirs 289*6777b538SAndroid Build Coastguard Worker 290*6777b538SAndroid Build Coastguard Worker @property 291*6777b538SAndroid Build Coastguard Worker def ldflags(self): 292*6777b538SAndroid Build Coastguard Worker return self.arch['common'].ldflags 293*6777b538SAndroid Build Coastguard Worker 294*6777b538SAndroid Build Coastguard Worker def host_supported(self): 295*6777b538SAndroid Build Coastguard Worker return 'host' in self.arch 296*6777b538SAndroid Build Coastguard Worker 297*6777b538SAndroid Build Coastguard Worker def device_supported(self): 298*6777b538SAndroid Build Coastguard Worker return any([name.startswith('android') for name in self.arch.keys()]) 299*6777b538SAndroid Build Coastguard Worker 300*6777b538SAndroid Build Coastguard Worker def is_linker_unit_type(self): 301*6777b538SAndroid Build Coastguard Worker return self.type in LINKER_UNIT_TYPES 302*6777b538SAndroid Build Coastguard Worker 303*6777b538SAndroid Build Coastguard Worker def __lt__(self, other): 304*6777b538SAndroid Build Coastguard Worker if isinstance(other, self.__class__): 305*6777b538SAndroid Build Coastguard Worker return self.name < other.name 306*6777b538SAndroid Build Coastguard Worker raise TypeError( 307*6777b538SAndroid Build Coastguard Worker '\'<\' not supported between instances of \'%s\' and \'%s\'' % 308*6777b538SAndroid Build Coastguard Worker (type(self).__name__, type(other).__name__)) 309*6777b538SAndroid Build Coastguard Worker 310*6777b538SAndroid Build Coastguard Worker def __repr__(self): 311*6777b538SAndroid Build Coastguard Worker return json.dumps({ 312*6777b538SAndroid Build Coastguard Worker k: (list(sorted(v)) if isinstance(v, set) else v) 313*6777b538SAndroid Build Coastguard Worker for (k, v) in self.__dict__.items() 314*6777b538SAndroid Build Coastguard Worker }, 315*6777b538SAndroid Build Coastguard Worker indent=4, 316*6777b538SAndroid Build Coastguard Worker sort_keys=True) 317*6777b538SAndroid Build Coastguard Worker 318*6777b538SAndroid Build Coastguard Worker def update(self, other, arch): 319*6777b538SAndroid Build Coastguard Worker for key in ('cflags', 'defines', 'deps', 'include_dirs', 'ldflags', 320*6777b538SAndroid Build Coastguard Worker 'proto_deps', 'libs', 'proto_paths'): 321*6777b538SAndroid Build Coastguard Worker getattr(self, key).update(getattr(other, key, [])) 322*6777b538SAndroid Build Coastguard Worker 323*6777b538SAndroid Build Coastguard Worker for key_in_arch in ('cflags', 'defines', 'include_dirs', 'deps', 'ldflags'): 324*6777b538SAndroid Build Coastguard Worker getattr(self.arch[arch], key_in_arch).update(getattr(other.arch[arch], key_in_arch, [])) 325*6777b538SAndroid Build Coastguard Worker 326*6777b538SAndroid Build Coastguard Worker def get_archs(self): 327*6777b538SAndroid Build Coastguard Worker """ Returns a dict of archs without the common arch """ 328*6777b538SAndroid Build Coastguard Worker return {arch: val for arch, val in self.arch.items() if arch != 'common'} 329*6777b538SAndroid Build Coastguard Worker 330*6777b538SAndroid Build Coastguard Worker def _finalize_set_attribute(self, key): 331*6777b538SAndroid Build Coastguard Worker # Target contains the intersection of arch-dependent properties 332*6777b538SAndroid Build Coastguard Worker getattr(self, key).update(set.intersection(*[getattr(arch, key) for arch in 333*6777b538SAndroid Build Coastguard Worker self.get_archs().values()])) 334*6777b538SAndroid Build Coastguard Worker 335*6777b538SAndroid Build Coastguard Worker # Deduplicate arch-dependent properties 336*6777b538SAndroid Build Coastguard Worker for arch in self.get_archs().values(): 337*6777b538SAndroid Build Coastguard Worker getattr(arch, key).difference_update(getattr(self, key)) 338*6777b538SAndroid Build Coastguard Worker 339*6777b538SAndroid Build Coastguard Worker def _finalize_non_set_attribute(self, key): 340*6777b538SAndroid Build Coastguard Worker # Only when all the arch has the same non empty value, move the value to the target common 341*6777b538SAndroid Build Coastguard Worker val = getattr(list(self.get_archs().values())[0], key) 342*6777b538SAndroid Build Coastguard Worker if val and all([val == getattr(arch, key) for arch in self.get_archs().values()]): 343*6777b538SAndroid Build Coastguard Worker setattr(self, key, copy.deepcopy(val)) 344*6777b538SAndroid Build Coastguard Worker 345*6777b538SAndroid Build Coastguard Worker def _finalize_attribute(self, key): 346*6777b538SAndroid Build Coastguard Worker val = getattr(self, key) 347*6777b538SAndroid Build Coastguard Worker if isinstance(val, set): 348*6777b538SAndroid Build Coastguard Worker self._finalize_set_attribute(key) 349*6777b538SAndroid Build Coastguard Worker elif isinstance(val, (list, str)): 350*6777b538SAndroid Build Coastguard Worker self._finalize_non_set_attribute(key) 351*6777b538SAndroid Build Coastguard Worker else: 352*6777b538SAndroid Build Coastguard Worker raise TypeError(f'Unsupported type: {type(val)}') 353*6777b538SAndroid Build Coastguard Worker 354*6777b538SAndroid Build Coastguard Worker def finalize(self): 355*6777b538SAndroid Build Coastguard Worker """Move common properties out of arch-dependent subobjects to Target object. 356*6777b538SAndroid Build Coastguard Worker 357*6777b538SAndroid Build Coastguard Worker TODO: find a better name for this function. 358*6777b538SAndroid Build Coastguard Worker """ 359*6777b538SAndroid Build Coastguard Worker if self.is_finalized: 360*6777b538SAndroid Build Coastguard Worker return 361*6777b538SAndroid Build Coastguard Worker self.is_finalized = True 362*6777b538SAndroid Build Coastguard Worker 363*6777b538SAndroid Build Coastguard Worker if len(self.arch) == 1: 364*6777b538SAndroid Build Coastguard Worker return 365*6777b538SAndroid Build Coastguard Worker 366*6777b538SAndroid Build Coastguard Worker for key in ('sources', 'cflags', 'defines', 'include_dirs', 'deps', 367*6777b538SAndroid Build Coastguard Worker 'inputs', 'outputs', 'args', 'response_file_contents', 'ldflags', 'rust_flags'): 368*6777b538SAndroid Build Coastguard Worker self._finalize_attribute(key) 369*6777b538SAndroid Build Coastguard Worker 370*6777b538SAndroid Build Coastguard Worker def get_target_name(self): 371*6777b538SAndroid Build Coastguard Worker return self.name[self.name.find(":") + 1:] 372*6777b538SAndroid Build Coastguard Worker 373*6777b538SAndroid Build Coastguard Worker 374*6777b538SAndroid Build Coastguard Worker def __init__(self, builtin_deps, build_script_outputs): 375*6777b538SAndroid Build Coastguard Worker self.builtin_deps = builtin_deps 376*6777b538SAndroid Build Coastguard Worker self.build_script_outputs = build_script_outputs 377*6777b538SAndroid Build Coastguard Worker self.all_targets = {} 378*6777b538SAndroid Build Coastguard Worker self.jni_java_sources = set() 379*6777b538SAndroid Build Coastguard Worker 380*6777b538SAndroid Build Coastguard Worker 381*6777b538SAndroid Build Coastguard Worker def _get_response_file_contents(self, action_desc): 382*6777b538SAndroid Build Coastguard Worker # response_file_contents are formatted as: 383*6777b538SAndroid Build Coastguard Worker # ['--flags', '--flag=true && false'] and need to be formatted as: 384*6777b538SAndroid Build Coastguard Worker # '--flags --flag=\"true && false\"' 385*6777b538SAndroid Build Coastguard Worker flags = action_desc.get('response_file_contents', []) 386*6777b538SAndroid Build Coastguard Worker formatted_flags = [] 387*6777b538SAndroid Build Coastguard Worker for flag in flags: 388*6777b538SAndroid Build Coastguard Worker if '=' in flag: 389*6777b538SAndroid Build Coastguard Worker key, val = flag.split('=') 390*6777b538SAndroid Build Coastguard Worker formatted_flags.append('%s=\\"%s\\"' % (key, val)) 391*6777b538SAndroid Build Coastguard Worker else: 392*6777b538SAndroid Build Coastguard Worker formatted_flags.append(flag) 393*6777b538SAndroid Build Coastguard Worker 394*6777b538SAndroid Build Coastguard Worker return ' '.join(formatted_flags) 395*6777b538SAndroid Build Coastguard Worker 396*6777b538SAndroid Build Coastguard Worker def _is_java_group(self, type_, target_name): 397*6777b538SAndroid Build Coastguard Worker # Per https://chromium.googlesource.com/chromium/src/build/+/HEAD/android/docs/java_toolchain.md 398*6777b538SAndroid Build Coastguard Worker # java target names must end in "_java". 399*6777b538SAndroid Build Coastguard Worker # TODO: There are some other possible variations we might need to support. 400*6777b538SAndroid Build Coastguard Worker return type_ == 'group' and target_name.endswith('_java') 401*6777b538SAndroid Build Coastguard Worker 402*6777b538SAndroid Build Coastguard Worker def _get_arch(self, toolchain): 403*6777b538SAndroid Build Coastguard Worker if toolchain == '//build/toolchain/android:android_clang_x86': 404*6777b538SAndroid Build Coastguard Worker return 'android_x86', 'x86' 405*6777b538SAndroid Build Coastguard Worker elif toolchain == '//build/toolchain/android:android_clang_x64': 406*6777b538SAndroid Build Coastguard Worker return 'android_x86_64', 'x64' 407*6777b538SAndroid Build Coastguard Worker elif toolchain == '//build/toolchain/android:android_clang_arm': 408*6777b538SAndroid Build Coastguard Worker return 'android_arm', 'arm' 409*6777b538SAndroid Build Coastguard Worker elif toolchain == '//build/toolchain/android:android_clang_arm64': 410*6777b538SAndroid Build Coastguard Worker return 'android_arm64', 'arm64' 411*6777b538SAndroid Build Coastguard Worker elif toolchain == '//build/toolchain/android:android_clang_riscv64': 412*6777b538SAndroid Build Coastguard Worker return 'android_riscv64', 'riscv64' 413*6777b538SAndroid Build Coastguard Worker else: 414*6777b538SAndroid Build Coastguard Worker return 'host', 'host' 415*6777b538SAndroid Build Coastguard Worker 416*6777b538SAndroid Build Coastguard Worker def get_target(self, gn_target_name): 417*6777b538SAndroid Build Coastguard Worker """Returns a Target object from the fully qualified GN target name. 418*6777b538SAndroid Build Coastguard Worker 419*6777b538SAndroid Build Coastguard Worker get_target() requires that parse_gn_desc() has already been called. 420*6777b538SAndroid Build Coastguard Worker """ 421*6777b538SAndroid Build Coastguard Worker # Run this every time as parse_gn_desc can be called at any time. 422*6777b538SAndroid Build Coastguard Worker for target in self.all_targets.values(): 423*6777b538SAndroid Build Coastguard Worker target.finalize() 424*6777b538SAndroid Build Coastguard Worker 425*6777b538SAndroid Build Coastguard Worker return self.all_targets[label_without_toolchain(gn_target_name)] 426*6777b538SAndroid Build Coastguard Worker 427*6777b538SAndroid Build Coastguard Worker def parse_gn_desc(self, gn_desc, gn_target_name, java_group_name=None, is_test_target=False): 428*6777b538SAndroid Build Coastguard Worker """Parses a gn desc tree and resolves all target dependencies. 429*6777b538SAndroid Build Coastguard Worker 430*6777b538SAndroid Build Coastguard Worker It bubbles up variables from source_set dependencies as described in the 431*6777b538SAndroid Build Coastguard Worker class-level comments. 432*6777b538SAndroid Build Coastguard Worker """ 433*6777b538SAndroid Build Coastguard Worker # Use name without toolchain for targets to support targets built for 434*6777b538SAndroid Build Coastguard Worker # multiple archs. 435*6777b538SAndroid Build Coastguard Worker target_name = label_without_toolchain(gn_target_name) 436*6777b538SAndroid Build Coastguard Worker desc = gn_desc[gn_target_name] 437*6777b538SAndroid Build Coastguard Worker type_ = desc['type'] 438*6777b538SAndroid Build Coastguard Worker arch, chromium_arch = self._get_arch(desc['toolchain']) 439*6777b538SAndroid Build Coastguard Worker metadata = desc.get("metadata", {}) 440*6777b538SAndroid Build Coastguard Worker 441*6777b538SAndroid Build Coastguard Worker if is_test_target: 442*6777b538SAndroid Build Coastguard Worker target_name += TESTING_SUFFIX 443*6777b538SAndroid Build Coastguard Worker 444*6777b538SAndroid Build Coastguard Worker target = self.all_targets.get(target_name) 445*6777b538SAndroid Build Coastguard Worker if target is None: 446*6777b538SAndroid Build Coastguard Worker target = GnParser.Target(target_name, type_) 447*6777b538SAndroid Build Coastguard Worker self.all_targets[target_name] = target 448*6777b538SAndroid Build Coastguard Worker 449*6777b538SAndroid Build Coastguard Worker if arch not in target.arch: 450*6777b538SAndroid Build Coastguard Worker target.arch[arch] = GnParser.Target.Arch() 451*6777b538SAndroid Build Coastguard Worker else: 452*6777b538SAndroid Build Coastguard Worker return target # Target already processed. 453*6777b538SAndroid Build Coastguard Worker 454*6777b538SAndroid Build Coastguard Worker if 'target_type' in metadata.keys() and metadata["target_type"][0] == 'java_library': 455*6777b538SAndroid Build Coastguard Worker target.type = 'java_library' 456*6777b538SAndroid Build Coastguard Worker 457*6777b538SAndroid Build Coastguard Worker if target.name in self.builtin_deps: 458*6777b538SAndroid Build Coastguard Worker # return early, no need to parse any further as the module is a builtin. 459*6777b538SAndroid Build Coastguard Worker return target 460*6777b538SAndroid Build Coastguard Worker 461*6777b538SAndroid Build Coastguard Worker if (target_name.startswith("//build/rust/std") or 462*6777b538SAndroid Build Coastguard Worker desc.get("crate_name", "").endswith("_build_script")): 463*6777b538SAndroid Build Coastguard Worker # We intentionally don't parse build/rust/std as we use AOSP's stdlib. 464*6777b538SAndroid Build Coastguard Worker # Don't parse build_script as we can't execute them in AOSP, we use a different 465*6777b538SAndroid Build Coastguard Worker # source of truth. 466*6777b538SAndroid Build Coastguard Worker return target 467*6777b538SAndroid Build Coastguard Worker 468*6777b538SAndroid Build Coastguard Worker target.testonly = desc.get('testonly', False) 469*6777b538SAndroid Build Coastguard Worker 470*6777b538SAndroid Build Coastguard Worker deps = desc.get("deps", {}) 471*6777b538SAndroid Build Coastguard Worker if desc.get("script", "") == "//tools/protoc_wrapper/protoc_wrapper.py": 472*6777b538SAndroid Build Coastguard Worker target.type = 'proto_library' 473*6777b538SAndroid Build Coastguard Worker target.proto_plugin = "proto" 474*6777b538SAndroid Build Coastguard Worker target.proto_paths.update(self.get_proto_paths(desc)) 475*6777b538SAndroid Build Coastguard Worker target.proto_exports.update(self.get_proto_exports(desc)) 476*6777b538SAndroid Build Coastguard Worker target.proto_in_dir = self.get_proto_in_dir(desc) 477*6777b538SAndroid Build Coastguard Worker target.arch[arch].sources.update(desc.get('sources', [])) 478*6777b538SAndroid Build Coastguard Worker target.arch[arch].inputs.update(desc.get('inputs', [])) 479*6777b538SAndroid Build Coastguard Worker elif target.type == 'source_set': 480*6777b538SAndroid Build Coastguard Worker target.arch[arch].sources.update(source for source in desc.get('sources', []) if not source.startswith("//out")) 481*6777b538SAndroid Build Coastguard Worker elif target.type == "rust_executable": 482*6777b538SAndroid Build Coastguard Worker target.arch[arch].sources.update(source for source in desc.get('sources', []) if not source.startswith("//out")) 483*6777b538SAndroid Build Coastguard Worker elif target.is_linker_unit_type(): 484*6777b538SAndroid Build Coastguard Worker target.arch[arch].sources.update(source for source in desc.get('sources', []) if not source.startswith("//out")) 485*6777b538SAndroid Build Coastguard Worker elif target.type == 'java_library': 486*6777b538SAndroid Build Coastguard Worker sources = set() 487*6777b538SAndroid Build Coastguard Worker for java_source in metadata.get("source_files", []): 488*6777b538SAndroid Build Coastguard Worker if not java_source.startswith("//out") and java_source not in JAVA_FILES_TO_IGNORE: 489*6777b538SAndroid Build Coastguard Worker sources.add(java_source) 490*6777b538SAndroid Build Coastguard Worker target.sources.update(sources) 491*6777b538SAndroid Build Coastguard Worker # Metadata attributes must be list, for jar_path, it is always a list 492*6777b538SAndroid Build Coastguard Worker # of size one, the first element is an empty string if `jar_path` is not 493*6777b538SAndroid Build Coastguard Worker # defined otherwise it is a path. 494*6777b538SAndroid Build Coastguard Worker if metadata.get("jar_path", [""])[0]: 495*6777b538SAndroid Build Coastguard Worker target.jar_path = label_to_path(metadata["jar_path"][0]) 496*6777b538SAndroid Build Coastguard Worker target.sdk_version = metadata.get('sdk_version', ['current'])[0] 497*6777b538SAndroid Build Coastguard Worker deps = metadata.get("all_deps", {}) 498*6777b538SAndroid Build Coastguard Worker log.info('Found Java Target %s', target.name) 499*6777b538SAndroid Build Coastguard Worker elif target.script == "//build/android/gyp/aidl.py": 500*6777b538SAndroid Build Coastguard Worker target.type = "java_library" 501*6777b538SAndroid Build Coastguard Worker target.sources.update(desc.get('sources', {})) 502*6777b538SAndroid Build Coastguard Worker target.local_aidl_includes = _extract_includes_from_aidl_args(desc.get('args', '')) 503*6777b538SAndroid Build Coastguard Worker elif target.type in ['action', 'action_foreach']: 504*6777b538SAndroid Build Coastguard Worker target.arch[arch].inputs.update(desc.get('inputs', [])) 505*6777b538SAndroid Build Coastguard Worker target.arch[arch].sources.update(desc.get('sources', [])) 506*6777b538SAndroid Build Coastguard Worker outs = [re.sub('^//out/.+?/gen/', '', x) for x in desc['outputs']] 507*6777b538SAndroid Build Coastguard Worker target.arch[arch].outputs.update(outs) 508*6777b538SAndroid Build Coastguard Worker # While the arguments might differ, an action should always use the same script for every 509*6777b538SAndroid Build Coastguard Worker # architecture. (gen_android_bp's get_action_sanitizer actually relies on this fact. 510*6777b538SAndroid Build Coastguard Worker target.script = desc['script'] 511*6777b538SAndroid Build Coastguard Worker target.arch[arch].args = desc['args'] 512*6777b538SAndroid Build Coastguard Worker target.arch[arch].response_file_contents = self._get_response_file_contents(desc) 513*6777b538SAndroid Build Coastguard Worker # _get_jni_registration_deps will return the dependencies of a target if 514*6777b538SAndroid Build Coastguard Worker # the target is of type `generate_jni_registration` otherwise it will 515*6777b538SAndroid Build Coastguard Worker # return an empty set. 516*6777b538SAndroid Build Coastguard Worker target.jni_registration_java_deps.update(_get_jni_registration_deps(gn_target_name, gn_desc)) 517*6777b538SAndroid Build Coastguard Worker # JNI java sources are embedded as metadata inside `jni_headers` targets. 518*6777b538SAndroid Build Coastguard Worker # See https://source.chromium.org/chromium/chromium/src/+/main:third_party/jni_zero/jni_zero.gni;l=421;drc=78e8e27142ed3fddf04fbcd122507517a87cb9ad 519*6777b538SAndroid Build Coastguard Worker # for more details 520*6777b538SAndroid Build Coastguard Worker target.transitive_jni_java_sources.update(metadata.get("jni_source_files_abs", set())) 521*6777b538SAndroid Build Coastguard Worker self.jni_java_sources.update(metadata.get("jni_source_files_abs", set())) 522*6777b538SAndroid Build Coastguard Worker elif target.type == 'copy': 523*6777b538SAndroid Build Coastguard Worker # TODO: copy rules are not currently implemented. 524*6777b538SAndroid Build Coastguard Worker pass 525*6777b538SAndroid Build Coastguard Worker elif target.type == 'group': 526*6777b538SAndroid Build Coastguard Worker # Groups are bubbled upward without creating an equivalent GN target. 527*6777b538SAndroid Build Coastguard Worker pass 528*6777b538SAndroid Build Coastguard Worker elif target.type in ["rust_library", "rust_proc_macro"]: 529*6777b538SAndroid Build Coastguard Worker target.arch[arch].sources.update(source for source in desc.get('sources', []) if not source.startswith("//out")) 530*6777b538SAndroid Build Coastguard Worker else: 531*6777b538SAndroid Build Coastguard Worker raise Exception(f"Encountered GN target with unknown type\nCulprit target: {gn_target_name}\ntype: {target.type}") 532*6777b538SAndroid Build Coastguard Worker 533*6777b538SAndroid Build Coastguard Worker # Default for 'public' is //* - all headers in 'sources' are public. 534*6777b538SAndroid Build Coastguard Worker # TODO(primiano): if a 'public' section is specified (even if empty), then 535*6777b538SAndroid Build Coastguard Worker # the rest of 'sources' is considered inaccessible by gn. Consider 536*6777b538SAndroid Build Coastguard Worker # emulating that, so that generated build files don't end up with overly 537*6777b538SAndroid Build Coastguard Worker # accessible headers. 538*6777b538SAndroid Build Coastguard Worker public_headers = [x for x in desc.get('public', []) if x != '*'] 539*6777b538SAndroid Build Coastguard Worker target.public_headers.update(public_headers) 540*6777b538SAndroid Build Coastguard Worker target.build_file_path = _get_build_path_from_label(target_name) 541*6777b538SAndroid Build Coastguard Worker target.arch[arch].cflags.update(desc.get('cflags', []) + desc.get('cflags_cc', [])) 542*6777b538SAndroid Build Coastguard Worker target.libs.update(desc.get('libs', [])) 543*6777b538SAndroid Build Coastguard Worker target.arch[arch].ldflags.update(desc.get('ldflags', [])) 544*6777b538SAndroid Build Coastguard Worker target.arch[arch].defines.update(desc.get('defines', [])) 545*6777b538SAndroid Build Coastguard Worker target.arch[arch].include_dirs.update(desc.get('include_dirs', [])) 546*6777b538SAndroid Build Coastguard Worker target.output_name = desc.get('output_name', None) 547*6777b538SAndroid Build Coastguard Worker target.crate_name = desc.get("crate_name", None) 548*6777b538SAndroid Build Coastguard Worker target.crate_root = desc.get("crate_root", None) 549*6777b538SAndroid Build Coastguard Worker target.arch[arch].rust_flags = desc.get("rustflags", list()) 550*6777b538SAndroid Build Coastguard Worker target.arch[arch].rust_flags.extend( 551*6777b538SAndroid Build Coastguard Worker self.build_script_outputs 552*6777b538SAndroid Build Coastguard Worker .get(label_without_toolchain(gn_target_name), {}) 553*6777b538SAndroid Build Coastguard Worker .get(chromium_arch, list()) 554*6777b538SAndroid Build Coastguard Worker ) 555*6777b538SAndroid Build Coastguard Worker if target.type == "executable" and target.crate_root: 556*6777b538SAndroid Build Coastguard Worker # Find a more decisive way to figure out that this is a rust executable. 557*6777b538SAndroid Build Coastguard Worker # TODO: Add a metadata to the executable from Chromium side. 558*6777b538SAndroid Build Coastguard Worker target.type = "rust_executable" 559*6777b538SAndroid Build Coastguard Worker if "-frtti" in target.arch[arch].cflags: 560*6777b538SAndroid Build Coastguard Worker target.rtti = True 561*6777b538SAndroid Build Coastguard Worker 562*6777b538SAndroid Build Coastguard Worker for gn_dep_name in set(target.jni_registration_java_deps): 563*6777b538SAndroid Build Coastguard Worker dep = self.parse_gn_desc(gn_desc, gn_dep_name, java_group_name, is_test_target) 564*6777b538SAndroid Build Coastguard Worker target.transitive_jni_java_sources.update(dep.transitive_jni_java_sources) 565*6777b538SAndroid Build Coastguard Worker 566*6777b538SAndroid Build Coastguard Worker # Recurse in dependencies. 567*6777b538SAndroid Build Coastguard Worker for gn_dep_name in set(deps): 568*6777b538SAndroid Build Coastguard Worker dep = self.parse_gn_desc(gn_desc, gn_dep_name, java_group_name, is_test_target) 569*6777b538SAndroid Build Coastguard Worker 570*6777b538SAndroid Build Coastguard Worker if dep.type == 'proto_library': 571*6777b538SAndroid Build Coastguard Worker target.proto_deps.add(dep.name) 572*6777b538SAndroid Build Coastguard Worker elif dep.type == 'group': 573*6777b538SAndroid Build Coastguard Worker target.update(dep, arch) # Bubble up groups's cflags/ldflags etc. 574*6777b538SAndroid Build Coastguard Worker target.transitive_jni_java_sources.update(dep.transitive_jni_java_sources) 575*6777b538SAndroid Build Coastguard Worker elif dep.type in ['action', 'action_foreach', 'copy']: 576*6777b538SAndroid Build Coastguard Worker target.arch[arch].deps.add(dep.name) 577*6777b538SAndroid Build Coastguard Worker target.transitive_jni_java_sources.update(dep.transitive_jni_java_sources) 578*6777b538SAndroid Build Coastguard Worker elif dep.is_linker_unit_type(): 579*6777b538SAndroid Build Coastguard Worker target.arch[arch].deps.add(dep.name) 580*6777b538SAndroid Build Coastguard Worker elif dep.type == "rust_executable": 581*6777b538SAndroid Build Coastguard Worker target.arch[arch].deps.add(dep.name) 582*6777b538SAndroid Build Coastguard Worker elif dep.type == 'java_library': 583*6777b538SAndroid Build Coastguard Worker target.deps.add(dep.name) 584*6777b538SAndroid Build Coastguard Worker target.transitive_jni_java_sources.update(dep.transitive_jni_java_sources) 585*6777b538SAndroid Build Coastguard Worker elif dep.type in ['rust_binary', "rust_library", "rust_proc_macro"]: 586*6777b538SAndroid Build Coastguard Worker target.arch[arch].deps.add(dep.name) 587*6777b538SAndroid Build Coastguard Worker if dep.type in ['static_library', 'source_set']: 588*6777b538SAndroid Build Coastguard Worker # Bubble up static_libs and source_set. Necessary, since soong does not propagate 589*6777b538SAndroid Build Coastguard Worker # static_libs up the build tree. 590*6777b538SAndroid Build Coastguard Worker # Source sets are later translated to static_libraries, so it makes sense 591*6777b538SAndroid Build Coastguard Worker # to reuse transitive_static_libs_deps. 592*6777b538SAndroid Build Coastguard Worker target.arch[arch].transitive_static_libs_deps.add(dep.name) 593*6777b538SAndroid Build Coastguard Worker 594*6777b538SAndroid Build Coastguard Worker if arch in dep.arch: 595*6777b538SAndroid Build Coastguard Worker target.arch[arch].transitive_static_libs_deps.update( 596*6777b538SAndroid Build Coastguard Worker dep.arch[arch].transitive_static_libs_deps) 597*6777b538SAndroid Build Coastguard Worker target.arch[arch].deps.update(target.arch[arch].transitive_static_libs_deps) 598*6777b538SAndroid Build Coastguard Worker return target 599*6777b538SAndroid Build Coastguard Worker 600*6777b538SAndroid Build Coastguard Worker def get_proto_exports(self, proto_desc): 601*6777b538SAndroid Build Coastguard Worker # exports in metadata will be available for source_set targets. 602*6777b538SAndroid Build Coastguard Worker metadata = proto_desc.get('metadata', {}) 603*6777b538SAndroid Build Coastguard Worker return metadata.get('exports', []) 604*6777b538SAndroid Build Coastguard Worker 605*6777b538SAndroid Build Coastguard Worker def get_proto_paths(self, proto_desc): 606*6777b538SAndroid Build Coastguard Worker args = proto_desc.get('args') 607*6777b538SAndroid Build Coastguard Worker proto_paths = set() 608*6777b538SAndroid Build Coastguard Worker for arg in args: 609*6777b538SAndroid Build Coastguard Worker is_match = re.match(PROTO_IMPORT_DIRS_REGEX, arg) 610*6777b538SAndroid Build Coastguard Worker if is_match: 611*6777b538SAndroid Build Coastguard Worker proto_paths.add(re.sub('^\.\./\.\./', '', is_match.group(1))) 612*6777b538SAndroid Build Coastguard Worker return proto_paths 613*6777b538SAndroid Build Coastguard Worker 614*6777b538SAndroid Build Coastguard Worker 615*6777b538SAndroid Build Coastguard Worker def get_proto_in_dir(self, proto_desc): 616*6777b538SAndroid Build Coastguard Worker args = proto_desc.get('args') 617*6777b538SAndroid Build Coastguard Worker return re.sub('^\.\./\.\./', '', args[args.index('--proto-in-dir') + 1]) 618