1# -*- bazel-starlark -*- 2# Copyright 2023 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""Siso configuration for Android builds.""" 6 7load("@builtin//encoding.star", "json") 8load("@builtin//lib/gn.star", "gn") 9load("@builtin//struct.star", "module") 10load("./config.star", "config") 11 12def __enabled(ctx): 13 if "args.gn" in ctx.metadata: 14 gn_args = gn.args(ctx) 15 if gn_args.get("target_os") == '"android"': 16 return True 17 return False 18 19def __filegroups(ctx): 20 return {} 21 22def __step_config(ctx, step_config): 23 remote_run = True # Turn this to False when you do file access trace. 24 step_config["rules"].extend([ 25 # See also https://chromium.googlesource.com/chromium/src/build/+/HEAD/android/docs/java_toolchain.md 26 { 27 "name": "android/write_build_config", 28 "command_prefix": "python3 ../../build/android/gyp/write_build_config.py", 29 "handler": "android_write_build_config", 30 "remote": remote_run, 31 "canonicalize_dir": True, 32 "timeout": "2m", 33 }, 34 { 35 "name": "android/ijar", 36 "command_prefix": "python3 ../../build/android/gyp/ijar.py", 37 "remote": remote_run, 38 "canonicalize_dir": True, 39 "timeout": "2m", 40 }, 41 { 42 "name": "android/turbine", 43 "command_prefix": "python3 ../../build/android/gyp/turbine.py", 44 "handler": "android_turbine", 45 "remote": remote_run, 46 "platform_ref": "large", 47 "canonicalize_dir": True, 48 "timeout": "2m", 49 }, 50 { 51 "name": "android/compile_resources", 52 "command_prefix": "python3 ../../build/android/gyp/compile_resources.py", 53 "handler": "android_compile_resources", 54 "exclude_input_patterns": [ 55 "*.a", 56 "*.cc", 57 "*.h", 58 "*.inc", 59 "*.info", 60 "*.o", 61 "*.pak", 62 "*.sql", 63 ], 64 "remote": remote_run, 65 "canonicalize_dir": True, 66 "timeout": "5m", 67 }, 68 { 69 "name": "android/compile_java", 70 "command_prefix": "python3 ../../build/android/gyp/compile_java.py", 71 "handler": "android_compile_java", 72 "exclude_input_patterns": [ 73 "*.a", 74 "*.cc", 75 "*.h", 76 "*.inc", 77 "*.info", 78 "*.o", 79 "*.pak", 80 "*.sql", 81 ], 82 # Don't include files under --generated-dir. 83 # This is probably optimization for local incrmental builds. 84 # However, this is harmful for remote build cache hits. 85 "ignore_extra_input_pattern": ".*srcjars.*\\.java", 86 "ignore_extra_output_pattern": ".*srcjars.*\\.java", 87 "remote": remote_run, 88 "platform_ref": "large", 89 "canonicalize_dir": True, 90 "timeout": "2m", 91 }, 92 { 93 "name": "android/compile_kt", 94 "command_prefix": "python3 ../../build/android/gyp/compile_kt.py", 95 "handler": "android_compile_java", 96 "exclude_input_patterns": [ 97 "*.a", 98 "*.cc", 99 "*.h", 100 "*.inc", 101 "*.info", 102 "*.o", 103 "*.pak", 104 "*.sql", 105 ], 106 # Don't include files under --generated-dir. 107 # This is probably optimization for local incrmental builds. 108 # However, this is harmful for remote build cache hits. 109 "ignore_extra_input_pattern": ".*srcjars.*\\.java", 110 "ignore_extra_output_pattern": ".*srcjars.*\\.java", 111 "remote": remote_run, 112 "platform_ref": "large", 113 "canonicalize_dir": True, 114 "timeout": "2m", 115 }, 116 { 117 "name": "android/dex", 118 "command_prefix": "python3 ../../build/android/gyp/dex.py", 119 "handler": "android_dex", 120 # TODO(crbug.com/40270798): include only required jar, dex files in GN config. 121 "indirect_inputs": { 122 "includes": ["*.dex", "*.ijar.jar", "*.turbine.jar"], 123 }, 124 "exclude_input_patterns": [ 125 "*.a", 126 "*.cc", 127 "*.h", 128 "*.inc", 129 "*.info", 130 "*.o", 131 "*.pak", 132 "*.sql", 133 ], 134 # *.dex files are intermediate files used in incremental builds. 135 # Fo remote actions, let's ignore them, assuming remote cache hits compensate. 136 "ignore_extra_input_pattern": ".*\\.dex", 137 "ignore_extra_output_pattern": ".*\\.dex", 138 "remote": remote_run, 139 "platform_ref": "large", 140 "canonicalize_dir": True, 141 "timeout": "2m", 142 }, 143 { 144 "name": "android/filter_zip", 145 "command_prefix": "python3 ../../build/android/gyp/filter_zip.py", 146 "remote": remote_run, 147 "canonicalize_dir": True, 148 "timeout": "2m", 149 }, 150 { 151 "name": "android/generate_resource_allowlist", 152 "command_prefix": "python3 ../../tools/resources/generate_resource_allowlist.py", 153 "indirect_inputs": { 154 "includes": ["*.o", "*.a"], 155 }, 156 # When remote linking without bytes enabled, .o, .a files don't 157 # exist on the local file system. 158 # This step also should run remortely to avoid downloading them. 159 "remote": config.get(ctx, "remote-link"), 160 "platform_ref": "large", 161 "canonicalize_dir": True, 162 "timeout": "2m", 163 }, 164 { 165 "name": "android/proguard", 166 "command_prefix": "python3 ../../build/android/gyp/proguard.py", 167 "handler": "android_proguard", 168 "exclude_input_patterns": [ 169 "*.a", 170 "*.cc", 171 "*.h", 172 "*.inc", 173 "*.info", 174 "*.o", 175 "*.pak", 176 "*.sql", 177 ], 178 "canonicalize_dir": True, 179 "remote": remote_run, 180 "platform_ref": "large", 181 "timeout": "10m", 182 }, 183 ]) 184 return step_config 185 186def __filearg(ctx, arg): 187 fn = "" 188 if arg.startswith("@FileArg("): 189 f = arg.removeprefix("@FileArg(").removesuffix(")").split(":") 190 fn = f[0].removesuffix("[]") # [] suffix controls expand list? 191 v = json.decode(str(ctx.fs.read(ctx.fs.canonpath(fn)))) 192 for k in f[1:]: 193 v = v[k] 194 arg = v 195 if type(arg) == "string": 196 if arg.startswith("["): 197 return fn, json.decode(arg) 198 return fn, [arg] 199 return fn, arg 200 201def __android_compile_resources_handler(ctx, cmd): 202 # Script: 203 # https://crsrc.org/c/build/android/gyp/compile_resources.py 204 # GN Config: 205 # https://crsrc.org/c/build/config/android/internal_rules.gni;l=2163;drc=1b15af251f8a255e44f2e3e3e7990e67e87dcc3b 206 # https://crsrc.org/c/build/config/android/system_image.gni;l=58;drc=39debde76e509774287a655285d8556a9b8dc634 207 # Sample args: 208 # --aapt2-path ../../third_party/android_build_tools/aapt2/cipd/aapt2 209 # --android-manifest gen/chrome/android/trichrome_library_system_stub_apk__manifest.xml 210 # --arsc-package-name=org.chromium.trichromelibrary 211 # --arsc-path obj/chrome/android/trichrome_library_system_stub_apk.ap_ 212 # --debuggable 213 # --dependencies-res-zip-overlays=@FileArg\(gen/chrome/android/webapk/shell_apk/maps_go_webapk.build_config.json:deps_info:dependency_zip_overlays\) 214 # --dependencies-res-zips=@FileArg\(gen/chrome/android/webapk/shell_apk/maps_go_webapk.build_config.json:deps_info:dependency_zips\) 215 # --depfile gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources.d 216 # --emit-ids-out=gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources.resource_ids 217 # --extra-res-packages=@FileArg\(gen/chrome/android/webapk/shell_apk/maps_go_webapk.build_config.json:deps_info:extra_package_names\) 218 # --include-resources(=)../../third_party/android_sdk/public/platforms/android-34/android.jar 219 # --info-path obj/chrome/android/webapk/shell_apk/maps_go_webapk.ap_.info 220 # --min-sdk-version=24 221 # --proguard-file obj/chrome/android/webapk/shell_apk/maps_go_webapk/maps_go_webapk.resources.proguard.txt 222 # --r-text-out gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources_R.txt 223 # --rename-manifest-package=org.chromium.trichromelibrary 224 # --srcjar-out gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources.srcjar 225 # --target-sdk-version=33 226 # --version-code 1 227 # --version-name Developer\ Build 228 # --webp-cache-dir=obj/android-webp-cache 229 inputs = [] 230 for i, arg in enumerate(cmd.args): 231 for k in ["--dependencies-res-zips=", "--dependencies-res-zip-overlays=", "--extra-res-packages="]: 232 if arg.startswith(k): 233 arg = arg.removeprefix(k) 234 _, v = __filearg(ctx, arg) 235 for f in v: 236 f = ctx.fs.canonpath(f) 237 inputs.append(f) 238 if k == "--dependencies-res-zips=" and ctx.fs.exists(f + ".info"): 239 inputs.append(f + ".info") 240 241 ctx.actions.fix( 242 inputs = cmd.inputs + inputs, 243 ) 244 245def __android_compile_java_handler(ctx, cmd): 246 # Script: 247 # https://crsrc.org/c/build/android/gyp/compile_java.py 248 # GN Config: 249 # https://crsrc.org/c/build/config/android/internal_rules.gni;l=2995;drc=775b3a9ebccd468c79592dad43ef46632d3a411f 250 # Sample args: 251 # --depfile=gen/chrome/android/chrome_test_java__compile_java.d 252 # --generated-dir=gen/chrome/android/chrome_test_java/generated_java 253 # --jar-path=obj/chrome/android/chrome_test_java.javac.jar 254 # --java-srcjars=\[\"gen/chrome/browser/tos_dialog_behavior_generated_enum.srcjar\",\ \"gen/chrome/android/chrome_test_java__assetres.srcjar\",\ \"gen/chrome/android/chrome_test_java.generated.srcjar\"\] 255 # --target-name //chrome/android:chrome_test_java__compile_java 256 # --classpath=@FileArg\(gen/chrome/android/chrome_test_java.build_config.json:android:sdk_interface_jars\) 257 # --header-jar obj/chrome/android/chrome_test_java.turbine.jar 258 # --classpath=\[\"obj/chrome/android/chrome_test_java.turbine.jar\"\] 259 # --classpath=@FileArg\(gen/chrome/android/chrome_test_java.build_config.json:deps_info:javac_full_interface_classpath\) 260 # --kotlin-jar-path=obj/chrome/browser/tabmodel/internal/java.kotlinc.jar 261 # --chromium-code=1 262 # --warnings-as-errors 263 # --jar-info-exclude-globs=\[\"\*/R.class\",\ \"\*/R\\\$\*.class\",\ \"\*/Manifest.class\",\ \"\*/Manifest\\\$\*.class\",\ \"\*/\*GEN_JNI.class\"\] 264 # --enable-errorprone 265 # @gen/chrome/android/chrome_test_java.sources 266 267 out = cmd.outputs[0] 268 outputs = [ 269 out + ".md5.stamp", 270 ] 271 272 inputs = [] 273 for i, arg in enumerate(cmd.args): 274 for k in ["--classpath=", "--bootclasspath=", "--processorpath="]: 275 if arg.startswith(k): 276 arg = arg.removeprefix(k) 277 fn, v = __filearg(ctx, arg) 278 if fn: 279 inputs.append(ctx.fs.canonpath(fn)) 280 for f in v: 281 f, _, _ = f.partition(":") 282 inputs.append(ctx.fs.canonpath(f)) 283 284 ctx.actions.fix( 285 inputs = cmd.inputs + inputs, 286 outputs = cmd.outputs + outputs, 287 ) 288 289def __android_dex_handler(ctx, cmd): 290 out = cmd.outputs[0] 291 inputs = [] 292 293 # Add __dex.desugardeps to the outputs. 294 outputs = [ 295 out + ".md5.stamp", 296 ] 297 for i, arg in enumerate(cmd.args): 298 if arg == "--desugar-dependencies": 299 outputs.append(ctx.fs.canonpath(cmd.args[i + 1])) 300 for k in ["--class-inputs=", "--bootclasspath=", "--classpath=", "--class-inputs-filearg=", "--dex-inputs-filearg="]: 301 if arg.startswith(k): 302 arg = arg.removeprefix(k) 303 _, v = __filearg(ctx, arg) 304 for f in v: 305 f, _, _ = f.partition(":") 306 f = ctx.fs.canonpath(f) 307 inputs.append(f) 308 309 # TODO: dex.py takes --incremental-dir to reuse the .dex produced in a previous build. 310 # Should remote dex action also take this? 311 ctx.actions.fix( 312 inputs = cmd.inputs + inputs, 313 outputs = cmd.outputs + outputs, 314 ) 315 316def __android_proguard_handler(ctx, cmd): 317 inputs = [] 318 outputs = [] 319 for i, arg in enumerate(cmd.args): 320 for k in ["--proguard-configs=", "--input-paths="]: 321 if arg.startswith(k): 322 arg = arg.removeprefix(k) 323 fn, v = __filearg(ctx, arg) 324 if fn: 325 inputs.append(ctx.fs.canonpath(fn)) 326 for f in v: 327 f, _, _ = f.partition(":") 328 inputs.append(ctx.fs.canonpath(f)) 329 break 330 if arg in ["--sdk-jars", "--sdk-extension-jars"]: 331 fn, v = __filearg(ctx, cmd.args[i + 1]) 332 if fn: 333 inputs.append(ctx.fs.canonpath(fn)) 334 for f in v: 335 f, _, _ = f.partition(":") 336 inputs.append(ctx.fs.canonpath(f)) 337 continue 338 if arg.startswith("--dex-dest="): 339 arg = arg.removeprefix("--dex-dest=") 340 fn, v = __filearg(ctx, arg) 341 if fn: 342 inputs.append(ctx.fs.canonpath(fn)) 343 for f in v: 344 f, _, _ = f.partition(":") 345 outputs.append(ctx.fs.canonpath(f)) 346 continue 347 348 ctx.actions.fix( 349 inputs = cmd.inputs + inputs, 350 outputs = cmd.outputs + outputs, 351 ) 352 353def __android_turbine_handler(ctx, cmd): 354 inputs = [] 355 for i, arg in enumerate(cmd.args): 356 for k in ["--classpath=", "--processorpath="]: 357 if arg.startswith(k): 358 arg = arg.removeprefix(k) 359 _, v = __filearg(ctx, arg) 360 for f in v: 361 f, _, _ = f.partition(":") 362 inputs.append(ctx.fs.canonpath(f)) 363 364 ctx.actions.fix( 365 inputs = cmd.inputs + inputs, 366 ) 367 368def __deps_configs(ctx, f, seen, inputs): 369 if f in seen: 370 return 371 seen[f] = True 372 inputs.append(f) 373 v = json.decode(str(ctx.fs.read(f))) 374 for f in v["deps_info"]["deps_configs"]: 375 f = ctx.fs.canonpath(f) 376 __deps_configs(ctx, f, seen, inputs) 377 if "public_deps_configs" in v["deps_info"]: 378 for f in v["deps_info"]["public_deps_configs"]: 379 f = ctx.fs.canonpath(f) 380 __deps_configs(ctx, f, seen, inputs) 381 382def __android_write_build_config_handler(ctx, cmd): 383 # Script: 384 # https://crsrc.org/c/build/android/gyp/write_build_config.py 385 # GN Config: 386 # https://crsrc.org/c/build/config/android/internal_rules.gni;l=122;drc=99e4f79301e108ea3d27ec84320f430490382587 387 # Sample args: 388 # --type=java_library 389 # --depfile gen/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm_java__build_config_crbug_908819.d 390 # --deps-configs=\[\"gen/third_party/kotlin_stdlib/kotlin_stdlib_java.build_config.json\"\] 391 # --public-deps-configs=\[\] 392 # --build-config gen/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm_java.build_config.json 393 # --gn-target //third_party/android_deps:org_jetbrains_kotlinx_kotlinx_metadata_jvm_java 394 # --non-chromium-code 395 # --host-jar-path lib.java/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm.jar 396 # --unprocessed-jar-path ../../third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/kotlinx-metadata-jvm-0.1.0.jar 397 # --interface-jar-path obj/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm.ijar.jar 398 # --is-prebuilt 399 # --bundled-srcjars=\[\] 400 inputs = [] 401 seen = {} 402 for i, arg in enumerate(cmd.args): 403 if arg in ["--shared-libraries-runtime-deps", "--secondary-abi-shared-libraries-runtime-deps"]: 404 inputs.append(ctx.fs.canonpath(cmd.args[i + 1])) 405 continue 406 if arg == "--tested-apk-config": 407 f = ctx.fs.canonpath(cmd.args[i + 1]) 408 __deps_configs(ctx, f, seen, inputs) 409 continue 410 for k in ["--deps-configs=", "--public-deps-configs=", "--annotation-processor-configs="]: 411 if arg.startswith(k): 412 arg = arg.removeprefix(k) 413 v = json.decode(arg) 414 for f in v: 415 f = ctx.fs.canonpath(f) 416 __deps_configs(ctx, f, seen, inputs) 417 418 ctx.actions.fix(inputs = cmd.inputs + inputs) 419 420__handlers = { 421 "android_compile_java": __android_compile_java_handler, 422 "android_compile_resources": __android_compile_resources_handler, 423 "android_dex": __android_dex_handler, 424 "android_proguard": __android_proguard_handler, 425 "android_turbine": __android_turbine_handler, 426 "android_write_build_config": __android_write_build_config_handler, 427} 428 429android = module( 430 "android", 431 enabled = __enabled, 432 step_config = __step_config, 433 filegroups = __filegroups, 434 handlers = __handlers, 435) 436