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 "*.h", 56 "*.o", 57 "*.cc", 58 "*.a", 59 "*.info", 60 "*.pak", 61 "*.inc", 62 ], 63 "remote": remote_run, 64 "canonicalize_dir": True, 65 "timeout": "5m", 66 }, 67 { 68 "name": "android/compile_java", 69 "command_prefix": "python3 ../../build/android/gyp/compile_java.py", 70 "handler": "android_compile_java", 71 # Don't include files under --generated-dir. 72 # This is probably optimization for local incrmental builds. 73 # However, this is harmful for remote build cache hits. 74 "ignore_extra_input_pattern": ".*srcjars.*\\.java", 75 "ignore_extra_output_pattern": ".*srcjars.*\\.java", 76 "remote": remote_run, 77 "platform_ref": "large", 78 "canonicalize_dir": True, 79 "timeout": "2m", 80 }, 81 { 82 "name": "android/dex", 83 "command_prefix": "python3 ../../build/android/gyp/dex.py", 84 "handler": "android_dex", 85 # TODO(crbug.com/1452038): include only required jar, dex files in GN config. 86 "indirect_inputs": { 87 "includes": ["*.dex", "*.ijar.jar", "*.turbine.jar"], 88 }, 89 # *.dex files are intermediate files used in incremental builds. 90 # Fo remote actions, let's ignore them, assuming remote cache hits compensate. 91 "ignore_extra_input_pattern": ".*\\.dex", 92 "ignore_extra_output_pattern": ".*\\.dex", 93 "remote": remote_run, 94 "platform_ref": "large", 95 "canonicalize_dir": True, 96 "timeout": "2m", 97 }, 98 { 99 "name": "android/filter_zip", 100 "command_prefix": "python3 ../../build/android/gyp/filter_zip.py", 101 "remote": remote_run, 102 "canonicalize_dir": True, 103 "timeout": "2m", 104 }, 105 ]) 106 return step_config 107 108def __filearg(ctx, arg): 109 fn = "" 110 if arg.startswith("@FileArg("): 111 f = arg.removeprefix("@FileArg(").removesuffix(")").split(":") 112 fn = f[0].removesuffix("[]") # [] suffix controls expand list? 113 v = json.decode(str(ctx.fs.read(ctx.fs.canonpath(fn)))) 114 for k in f[1:]: 115 v = v[k] 116 arg = v 117 if type(arg) == "string": 118 if arg.startswith("["): 119 return fn, json.decode(arg) 120 return fn, [arg] 121 return fn, arg 122 123def __android_compile_resources_handler(ctx, cmd): 124 # Script: 125 # https://crsrc.org/c/build/android/gyp/compile_resources.py 126 # GN Config: 127 # https://crsrc.org/c/build/config/android/internal_rules.gni;l=2163;drc=1b15af251f8a255e44f2e3e3e7990e67e87dcc3b 128 # https://crsrc.org/c/build/config/android/system_image.gni;l=58;drc=39debde76e509774287a655285d8556a9b8dc634 129 # Sample args: 130 # --aapt2-path ../../third_party/android_build_tools/aapt2/aapt2 131 # --android-manifest gen/chrome/android/trichrome_library_system_stub_apk__manifest.xml 132 # --arsc-package-name=org.chromium.trichromelibrary 133 # --arsc-path obj/chrome/android/trichrome_library_system_stub_apk.ap_ 134 # --debuggable 135 # --dependencies-res-zip-overlays=@FileArg\(gen/chrome/android/webapk/shell_apk/maps_go_webapk.build_config.json:deps_info:dependency_zip_overlays\) 136 # --dependencies-res-zips=@FileArg\(gen/chrome/android/webapk/shell_apk/maps_go_webapk.build_config.json:deps_info:dependency_zips\) 137 # --depfile gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources.d 138 # --emit-ids-out=gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources.resource_ids 139 # --extra-res-packages=@FileArg\(gen/chrome/android/webapk/shell_apk/maps_go_webapk.build_config.json:deps_info:extra_package_names\) 140 # --include-resources(=)../../third_party/android_sdk/public/platforms/android-34/android.jar 141 # --info-path obj/chrome/android/webapk/shell_apk/maps_go_webapk.ap_.info 142 # --min-sdk-version=24 143 # --proguard-file obj/chrome/android/webapk/shell_apk/maps_go_webapk/maps_go_webapk.resources.proguard.txt 144 # --r-text-out gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources_R.txt 145 # --rename-manifest-package=org.chromium.trichromelibrary 146 # --srcjar-out gen/chrome/android/webapk/shell_apk/maps_go_webapk__compile_resources.srcjar 147 # --target-sdk-version=33 148 # --version-code 1 149 # --version-name Developer\ Build 150 # --webp-cache-dir=obj/android-webp-cache 151 inputs = [] 152 for i, arg in enumerate(cmd.args): 153 for k in ["--dependencies-res-zips=", "--dependencies-res-zip-overlays=", "--extra-res-packages="]: 154 if arg.startswith(k): 155 arg = arg.removeprefix(k) 156 fn, v = __filearg(ctx, arg) 157 if fn: 158 inputs.append(ctx.fs.canonpath(fn)) 159 for f in v: 160 f = ctx.fs.canonpath(f) 161 inputs.append(f) 162 if k == "--dependencies-res-zips=" and ctx.fs.exists(f + ".info"): 163 inputs.append(f + ".info") 164 165 ctx.actions.fix( 166 inputs = cmd.inputs + inputs, 167 ) 168 169def __android_compile_java_handler(ctx, cmd): 170 # Script: 171 # https://crsrc.org/c/build/android/gyp/compile_java.py 172 # GN Config: 173 # https://crsrc.org/c/build/config/android/internal_rules.gni;l=2995;drc=775b3a9ebccd468c79592dad43ef46632d3a411f 174 # Sample args: 175 # --depfile=gen/chrome/android/chrome_test_java__compile_java.d 176 # --generated-dir=gen/chrome/android/chrome_test_java/generated_java 177 # --jar-path=obj/chrome/android/chrome_test_java.javac.jar 178 # --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\"\] 179 # --target-name //chrome/android:chrome_test_java__compile_java 180 # --classpath=@FileArg\(gen/chrome/android/chrome_test_java.build_config.json:android:sdk_interface_jars\) 181 # --header-jar obj/chrome/android/chrome_test_java.turbine.jar 182 # --classpath=\[\"obj/chrome/android/chrome_test_java.turbine.jar\"\] 183 # --classpath=@FileArg\(gen/chrome/android/chrome_test_java.build_config.json:deps_info:javac_full_interface_classpath\) 184 # --kotlin-jar-path=obj/chrome/browser/tabmodel/internal/java.kotlinc.jar 185 # --chromium-code=1 186 # --warnings-as-errors 187 # --jar-info-exclude-globs=\[\"\*/R.class\",\ \"\*/R\\\$\*.class\",\ \"\*/Manifest.class\",\ \"\*/Manifest\\\$\*.class\",\ \"\*/\*GEN_JNI.class\"\] 188 # --enable-errorprone 189 # @gen/chrome/android/chrome_test_java.sources 190 191 out = cmd.outputs[0] 192 outputs = [ 193 out + ".md5.stamp", 194 ] 195 196 inputs = [] 197 for i, arg in enumerate(cmd.args): 198 # read .sources file. 199 if arg.startswith("@"): 200 sources = str(ctx.fs.read(ctx.fs.canonpath(arg.removeprefix("@")))).splitlines() 201 for source in sources: 202 inputs.append(ctx.fs.canonpath(source)) 203 for k in ["--classpath=", "--bootclasspath=", "--processorpath="]: 204 if arg.startswith(k): 205 arg = arg.removeprefix(k) 206 fn, v = __filearg(ctx, arg) 207 if fn: 208 inputs.append(ctx.fs.canonpath(fn)) 209 for f in v: 210 f, _, _ = f.partition(":") 211 inputs.append(ctx.fs.canonpath(f)) 212 213 ctx.actions.fix( 214 inputs = cmd.inputs + inputs, 215 outputs = cmd.outputs + outputs, 216 ) 217 218def __android_dex_handler(ctx, cmd): 219 out = cmd.outputs[0] 220 inputs = [ 221 out.replace("obj/", "gen/").replace(".dex.jar", ".build_config.json"), 222 ] 223 224 # Add __dex.desugardeps to the outputs. 225 outputs = [ 226 out + ".md5.stamp", 227 ] 228 for i, arg in enumerate(cmd.args): 229 if arg == "--desugar-dependencies": 230 outputs.append(ctx.fs.canonpath(cmd.args[i + 1])) 231 for k in ["--class-inputs=", "--bootclasspath=", "--classpath=", "--class-inputs-filearg=", "--dex-inputs-filearg="]: 232 if arg.startswith(k): 233 arg = arg.removeprefix(k) 234 fn, v = __filearg(ctx, arg) 235 if fn: 236 inputs.append(ctx.fs.canonpath(fn)) 237 for f in v: 238 f, _, _ = f.partition(":") 239 f = ctx.fs.canonpath(f) 240 inputs.append(f) 241 242 # TODO: dex.py takes --incremental-dir to reuse the .dex produced in a previous build. 243 # Should remote dex action also take this? 244 ctx.actions.fix( 245 inputs = cmd.inputs + inputs, 246 outputs = cmd.outputs + outputs, 247 ) 248 249def __android_turbine_handler(ctx, cmd): 250 inputs = [] 251 for i, arg in enumerate(cmd.args): 252 for k in ["--classpath=", "--processorpath="]: 253 if arg.startswith(k): 254 arg = arg.removeprefix(k) 255 fn, v = __filearg(ctx, arg) 256 if fn: 257 inputs.append(ctx.fs.canonpath(fn)) 258 for f in v: 259 f, _, _ = f.partition(":") 260 inputs.append(ctx.fs.canonpath(f)) 261 262 ctx.actions.fix( 263 inputs = cmd.inputs + inputs, 264 ) 265 266def __deps_configs(ctx, f, seen, inputs): 267 if f in seen: 268 return 269 seen[f] = True 270 inputs.append(f) 271 v = json.decode(str(ctx.fs.read(f))) 272 for f in v["deps_info"]["deps_configs"]: 273 f = ctx.fs.canonpath(f) 274 __deps_configs(ctx, f, seen, inputs) 275 if "public_deps_configs" in v["deps_info"]: 276 for f in v["deps_info"]["public_deps_configs"]: 277 f = ctx.fs.canonpath(f) 278 __deps_configs(ctx, f, seen, inputs) 279 280def __android_write_build_config_handler(ctx, cmd): 281 # Script: 282 # https://crsrc.org/c/build/android/gyp/write_build_config.py 283 # GN Config: 284 # https://crsrc.org/c/build/config/android/internal_rules.gni;l=122;drc=99e4f79301e108ea3d27ec84320f430490382587 285 # Sample args: 286 # --type=java_library 287 # --depfile gen/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm_java__build_config_crbug_908819.d 288 # --deps-configs=\[\"gen/third_party/kotlin_stdlib/kotlin_stdlib_java.build_config.json\"\] 289 # --public-deps-configs=\[\] 290 # --build-config gen/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm_java.build_config.json 291 # --gn-target //third_party/android_deps:org_jetbrains_kotlinx_kotlinx_metadata_jvm_java 292 # --non-chromium-code 293 # --host-jar-path lib.java/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm.jar 294 # --unprocessed-jar-path ../../third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/kotlinx-metadata-jvm-0.1.0.jar 295 # --interface-jar-path obj/third_party/android_deps/org_jetbrains_kotlinx_kotlinx_metadata_jvm.ijar.jar 296 # --is-prebuilt 297 # --bundled-srcjars=\[\] 298 inputs = [] 299 seen = {} 300 for i, arg in enumerate(cmd.args): 301 if arg in ["--shared-libraries-runtime-deps", "--secondary-abi-shared-libraries-runtime-deps"]: 302 inputs.append(ctx.fs.canonpath(cmd.args[i + 1])) 303 continue 304 if arg == "--tested-apk-config": 305 f = ctx.fs.canonpath(cmd.args[i + 1]) 306 __deps_configs(ctx, f, seen, inputs) 307 continue 308 for k in ["--deps-configs=", "--public-deps-configs=", "--annotation-processor-configs="]: 309 if arg.startswith(k): 310 arg = arg.removeprefix(k) 311 v = json.decode(arg) 312 for f in v: 313 f = ctx.fs.canonpath(f) 314 __deps_configs(ctx, f, seen, inputs) 315 316 ctx.actions.fix(inputs = cmd.inputs + inputs) 317 318__handlers = { 319 "android_compile_resources": __android_compile_resources_handler, 320 "android_compile_java": __android_compile_java_handler, 321 "android_dex": __android_dex_handler, 322 "android_turbine": __android_turbine_handler, 323 "android_write_build_config": __android_write_build_config_handler, 324} 325 326android = module( 327 "android", 328 enabled = __enabled, 329 step_config = __step_config, 330 filegroups = __filegroups, 331 handlers = __handlers, 332) 333