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