xref: /aosp_15_r20/external/angle/build/config/siso/android.star (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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