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