blob: 1998448cbd5a263615a3bac36358dc7c2adb5a6a [file] [log] [blame]
Michael Staibffec3522016-03-25 00:24:22 +00001"""Template for the build file used in android_sdk_repository."""
2# Copyright 2016 The Bazel Authors. All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Yun Pengc924cf62018-01-12 09:13:10 -080016def create_config_setting_rule():
vladmos20a042f2018-06-01 04:51:21 -070017 """Create config_setting rule for windows.
Laszlo Csomorfe037f32017-06-28 10:51:26 +020018
vladmos20a042f2018-06-01 04:51:21 -070019 These represent the matching --host_cpu values.
20 """
21 name = "windows"
22 if not native.existing_rule(name):
23 native.config_setting(
24 name = name,
25 values = {"host_cpu": "x64_" + name},
26 )
Laszlo Csomorfe037f32017-06-28 10:51:26 +020027
Alex Humesky9a21e202016-05-06 23:13:39 +000028def create_android_sdk_rules(
vladmos20a042f2018-06-01 04:51:21 -070029 name,
30 build_tools_version,
31 build_tools_directory,
32 api_levels,
33 default_api_level):
34 """Generate android_sdk rules for the API levels in the Android SDK.
Michael Staibffec3522016-03-25 00:24:22 +000035
vladmos20a042f2018-06-01 04:51:21 -070036 Args:
37 name: string, the name of the repository being generated.
38 build_tools_version: string, the version of Android's build tools to use.
39 build_tools_directory: string, the directory name of the build tools in
40 sdk's build-tools directory.
41 api_levels: list of ints, the API levels from which to get android.jar
42 et al. and create android_sdk rules.
43 default_api_level: int, the API level to alias the default sdk to if
44 --android_sdk is not specified on the command line.
45 """
Michael Staibffec3522016-03-25 00:24:22 +000046
vladmos20a042f2018-06-01 04:51:21 -070047 create_config_setting_rule()
Laszlo Csomorfe037f32017-06-28 10:51:26 +020048
vladmos20a042f2018-06-01 04:51:21 -070049 windows_only_files = [
50 "build-tools/%s/aapt.exe" % build_tools_directory,
51 "build-tools/%s/aidl.exe" % build_tools_directory,
52 "build-tools/%s/zipalign.exe" % build_tools_directory,
53 "platform-tools/adb.exe",
54 ] + native.glob(["build-tools/%s/aapt2.exe" % build_tools_directory])
ajmichael95ce5342017-09-26 11:39:52 -040055
vladmos20a042f2018-06-01 04:51:21 -070056 linux_only_files = [
57 "build-tools/%s/aapt" % build_tools_directory,
58 "build-tools/%s/aidl" % build_tools_directory,
59 "build-tools/%s/zipalign" % build_tools_directory,
60 "platform-tools/adb",
61 ] + native.glob(
62 ["extras", "build-tools/%s/aapt2" % build_tools_directory],
63 exclude_directories = 0,
64 )
ajmichael95ce5342017-09-26 11:39:52 -040065
vladmos20a042f2018-06-01 04:51:21 -070066 # This filegroup is used to pass the minimal contents of the SDK to the
67 # Android integration tests. Note that in order to work on Windows, we cannot
68 # include directories and must keep the size small.
69 native.filegroup(
70 name = "files",
71 srcs = [
72 "build-tools/%s/lib/apksigner.jar" % build_tools_directory,
73 "build-tools/%s/lib/dx.jar" % build_tools_directory,
74 "build-tools/%s/mainDexClasses.rules" % build_tools_directory,
75 ] + [
76 "platforms/android-%d/%s" % (api_level, filename)
77 for api_level in api_levels
78 for filename in ["android.jar", "framework.aidl"]
79 ] + select({
80 ":windows": windows_only_files,
81 "//conditions:default": linux_only_files,
Laszlo Csomorfe037f32017-06-28 10:51:26 +020082 }),
Michael Staibffec3522016-03-25 00:24:22 +000083 )
84
vladmos20a042f2018-06-01 04:51:21 -070085 for api_level in api_levels:
86 if api_level >= 23:
87 # Android 23 removed most of org.apache.http from android.jar and moved it
88 # to a separate jar.
89 native.java_import(
90 name = "org_apache_http_legacy-%d" % api_level,
91 jars = ["platforms/android-%d/optional/org.apache.http.legacy.jar" % api_level],
92 )
Adam Michael43b1d202017-01-11 23:37:51 +000093
Googlerdb461d02018-06-21 16:32:38 -070094 if api_level >= 28:
95 # Android 28 removed most of android.test from android.jar and moved it
96 # to separate jars.
97 native.java_import(
98 name = "legacy_test-%d" % api_level,
99 jars = [
100 "platforms/android-%d/optional/android.test.base.jar" % api_level,
101 "platforms/android-%d/optional/android.test.mock.jar" % api_level,
102 "platforms/android-%d/optional/android.test.runner.jar" % api_level,
103 ],
Googler37663e32018-10-08 13:26:56 -0700104 neverlink = 1,
Googlerdb461d02018-06-21 16:32:38 -0700105 )
106
vladmos20a042f2018-06-01 04:51:21 -0700107 native.android_sdk(
108 name = "sdk-%d" % api_level,
109 build_tools_version = build_tools_version,
iirinab2af5ea2019-05-16 05:23:38 -0700110 proguard = "@bazel_tools//tools/jdk:proguard",
vladmos20a042f2018-06-01 04:51:21 -0700111 aapt = select({
112 ":windows": "build-tools/%s/aapt.exe" % build_tools_directory,
113 "//conditions:default": ":aapt_binary",
114 }),
115 aapt2 = select({
116 ":windows": "build-tools/%s/aapt2.exe" % build_tools_directory,
117 "//conditions:default": ":aapt2_binary",
118 }),
119 dx = ":dx_binary",
120 main_dex_list_creator = ":main_dex_list_creator",
121 adb = select({
122 ":windows": "platform-tools/adb.exe",
123 "//conditions:default": "platform-tools/adb",
124 }),
125 framework_aidl = "platforms/android-%d/framework.aidl" % api_level,
126 aidl = select({
127 ":windows": "build-tools/%s/aidl.exe" % build_tools_directory,
128 "//conditions:default": ":aidl_binary",
129 }),
130 android_jar = "platforms/android-%d/android.jar" % api_level,
131 shrinked_android_jar = "platforms/android-%d/android.jar" % api_level,
132 main_dex_classes = "build-tools/%s/mainDexClasses.rules" % build_tools_directory,
133 apksigner = ":apksigner",
134 zipalign = select({
135 ":windows": "build-tools/%s/zipalign.exe" % build_tools_directory,
136 "//conditions:default": ":zipalign_binary",
137 }),
ahumeskya52e65a2019-07-11 14:25:11 -0700138 # See https://github.com/bazelbuild/bazel/issues/8757
139 tags = ["__ANDROID_RULES_MIGRATION__"],
vladmos20a042f2018-06-01 04:51:21 -0700140 )
Michael Staibffec3522016-03-25 00:24:22 +0000141
vladmos20a042f2018-06-01 04:51:21 -0700142 native.alias(
143 name = "org_apache_http_legacy",
144 actual = ":org_apache_http_legacy-%d" % default_api_level,
Philipp Wollermanna5afe952016-06-21 14:58:09 +0000145 )
Michael Staibffec3522016-03-25 00:24:22 +0000146
vladmos20a042f2018-06-01 04:51:21 -0700147 native.alias(
148 name = "sdk",
149 actual = ":sdk-%d" % default_api_level,
150 )
151
152 native.java_binary(
153 name = "apksigner",
154 main_class = "com.android.apksigner.ApkSignerTool",
155 runtime_deps = ["build-tools/%s/lib/apksigner.jar" % build_tools_directory],
156 )
157
158 native.filegroup(
159 name = "build_tools_libs",
160 srcs = native.glob([
161 "build-tools/%s/lib/**" % build_tools_directory,
162 # Build tools version 24.0.0 added a lib64 folder.
163 "build-tools/%s/lib64/**" % build_tools_directory,
164 ]),
165 )
166
167 for tool in ["aapt", "aapt2", "aidl", "zipalign"]:
168 native.genrule(
169 name = tool + "_runner",
170 outs = [tool + "_runner.sh"],
171 srcs = [],
172 cmd = "\n".join([
173 "cat > $@ << 'EOF'",
174 "#!/bin/bash",
175 "set -eu",
176 # The tools under build-tools/VERSION require the libraries under
177 # build-tools/VERSION/lib, so we can't simply depend on them as a
178 # file like we do with aapt.
179 # On Windows however we can use these binaries directly because
180 # there's no runfiles support so Bazel just creates a junction to
181 # {SDK}/build-tools.
182 "SDK=$${0}.runfiles/%s" % name,
183 # If $${SDK} is not a directory, it means that this tool is running
184 # from a runfiles directory, in the case of
185 # android_instrumentation_test. Hence, use the androidsdk
186 # that's already present in the runfiles of the current context.
187 "if [[ ! -d $${SDK} ]] ; then",
188 " SDK=$$(pwd)/../%s" % name,
189 "fi",
190 "exec $${SDK}/build-tools/%s/%s $$*" % (build_tools_directory, tool),
191 "EOF\n",
192 ]),
193 )
194
195 native.sh_binary(
196 name = tool + "_binary",
197 srcs = [tool + "_runner.sh"],
198 data = [
199 ":build_tools_libs",
200 "build-tools/%s/%s" % (build_tools_directory, tool),
201 ],
202 )
203
Philipp Wollermanna5afe952016-06-21 14:58:09 +0000204 native.sh_binary(
vladmos20a042f2018-06-01 04:51:21 -0700205 name = "fail",
206 srcs = select({
207 ":windows": [":generate_fail_cmd"],
208 "//conditions:default": [":generate_fail_sh"],
209 }),
Philipp Wollermanna5afe952016-06-21 14:58:09 +0000210 )
Michael Staibffec3522016-03-25 00:24:22 +0000211
vladmos20a042f2018-06-01 04:51:21 -0700212 native.genrule(
213 name = "generate_fail_sh",
214 executable = 1,
215 outs = ["fail.sh"],
216 cmd = "echo -e '#!/bin/bash\\nexit 1' >> $@; chmod +x $@",
217 )
Michael Staibffec3522016-03-25 00:24:22 +0000218
vladmos20a042f2018-06-01 04:51:21 -0700219 native.genrule(
220 name = "generate_fail_cmd",
221 executable = 1,
222 outs = ["fail.cmd"],
223 cmd = "echo @exit /b 1 > $@",
224 )
Michael Staibffec3522016-03-25 00:24:22 +0000225
vladmos20a042f2018-06-01 04:51:21 -0700226 native.genrule(
227 name = "main_dex_list_creator_source",
228 srcs = [],
229 outs = ["main_dex_list_creator.sh"],
230 cmd = "\n".join([
231 "cat > $@ <<'EOF'",
Michael Staibffec3522016-03-25 00:24:22 +0000232 "#!/bin/bash",
233 "",
234 "MAIN_DEX_LIST=$$1",
235 "STRIPPED_JAR=$$2",
236 "JAR=$$3",
237 "" +
ajmichael441dc762018-02-05 08:33:22 -0800238 "JAVA_BINARY=$$0.runfiles/%s/main_dex_list_creator_java" % name,
Michael Staibffec3522016-03-25 00:24:22 +0000239 "$$JAVA_BINARY $$STRIPPED_JAR $$JAR > $$MAIN_DEX_LIST",
240 "exit $$?",
241 "",
vladmos20a042f2018-06-01 04:51:21 -0700242 "EOF\n",
243 ]),
244 )
Michael Staibffec3522016-03-25 00:24:22 +0000245
vladmos20a042f2018-06-01 04:51:21 -0700246 native.sh_binary(
247 name = "main_dex_list_creator",
248 srcs = ["main_dex_list_creator.sh"],
249 data = [":main_dex_list_creator_java"],
250 )
Michael Staibffec3522016-03-25 00:24:22 +0000251
vladmos20a042f2018-06-01 04:51:21 -0700252 native.java_binary(
253 name = "main_dex_list_creator_java",
254 main_class = "com.android.multidex.ClassReferenceListBuilder",
255 runtime_deps = [":dx_jar_import"],
256 )
Michael Staibffec3522016-03-25 00:24:22 +0000257
vladmos20a042f2018-06-01 04:51:21 -0700258 native.java_binary(
259 name = "dx_binary",
260 main_class = "com.android.dx.command.Main",
261 runtime_deps = [":dx_jar_import"],
262 )
Michael Staibffec3522016-03-25 00:24:22 +0000263
vladmos20a042f2018-06-01 04:51:21 -0700264 native.java_import(
265 name = "dx_jar_import",
266 jars = ["build-tools/%s/lib/dx.jar" % build_tools_directory],
267 )
ajmichael8d876cf2017-04-12 01:34:08 +0000268
269TAGDIR_TO_TAG_MAP = {
Jingwen Chenebfd3bc2019-06-14 13:45:01 -0700270 "google_apis_playstore": "playstore",
ajmichael8d876cf2017-04-12 01:34:08 +0000271 "google_apis": "google",
272 "default": "android",
273 "android-tv": "tv",
274 "android-wear": "wear",
275}
276
ajmichael8d876cf2017-04-12 01:34:08 +0000277ARCHDIR_TO_ARCH_MAP = {
278 "x86": "x86",
279 "armeabi-v7a": "arm",
280}
281
ajmichael8d876cf2017-04-12 01:34:08 +0000282def create_system_images_filegroups(system_image_dirs):
vladmos20a042f2018-06-01 04:51:21 -0700283 """Generate filegroups for the system images in the Android SDK.
Adam Michaelee9a3002017-02-01 18:15:45 +0000284
vladmos20a042f2018-06-01 04:51:21 -0700285 Args:
286 system_image_dirs: list of strings, the directories containing system image
287 files to be used to create android_device rules.
288 """
Adam Michaelee9a3002017-02-01 18:15:45 +0000289
vladmos20a042f2018-06-01 04:51:21 -0700290 # These images will need to be updated as Android releases new system images.
291 # We are intentionally not adding future releases because there is no
292 # guarantee that they will work out of the box. Supported system images should
293 # be added here once they have been confirmed to work with the Bazel Android
294 # testing infrastructure.
295 system_images = [
296 (tag, str(api), arch)
297 for tag in ["android", "google"]
Jingwen Chenebfd3bc2019-06-14 13:45:01 -0700298 for api in [10] + list(range(15, 20)) + list(range(21, 30))
vladmos20a042f2018-06-01 04:51:21 -0700299 for arch in ("x86", "arm")
Jingwen Chenebfd3bc2019-06-14 13:45:01 -0700300 ] + [
301 ("playstore", str(api), "x86")
302 for api in list(range(24, 30))
vladmos20a042f2018-06-01 04:51:21 -0700303 ]
304 tv_images = [
Jingwen Chenebfd3bc2019-06-14 13:45:01 -0700305 ("tv", str(api), "x86")
306 for api in range(21, 30)
307 ] + [
308 ("tv", "21", "arm"),
309 ("tv", "23", "arm"),
vladmos20a042f2018-06-01 04:51:21 -0700310 ]
311 wear_images = [
312 ("wear", str(api), "x86")
Jingwen Chenebfd3bc2019-06-14 13:45:01 -0700313 for api in [23, 25, 26, 28]
vladmos20a042f2018-06-01 04:51:21 -0700314 ] + [
315 ("wear", str(api), "arm")
Jingwen Chenebfd3bc2019-06-14 13:45:01 -0700316 for api in [23, 25]
vladmos20a042f2018-06-01 04:51:21 -0700317 ]
318 supported_system_images = system_images + tv_images + wear_images
ajmichael8d876cf2017-04-12 01:34:08 +0000319
vladmos20a042f2018-06-01 04:51:21 -0700320 installed_system_images_dirs = {}
321 for system_image_dir in system_image_dirs:
322 apidir, tagdir, archdir = system_image_dir.split("/")[1:]
323 if "-" not in apidir:
324 continue
325 api = apidir.split("-")[1] # "android-24" --> "24", "android-O" --> "O"
326 if tagdir not in TAGDIR_TO_TAG_MAP:
327 continue
328 tag = TAGDIR_TO_TAG_MAP[tagdir]
329 if archdir not in ARCHDIR_TO_ARCH_MAP:
330 continue
331 arch = ARCHDIR_TO_ARCH_MAP[archdir]
332 if (tag, api, arch) in supported_system_images:
333 name = "emulator_images_%s_%s_%s" % (tag, api, arch)
334 installed_system_images_dirs[name] = system_image_dir
335 else:
336 # TODO(bazel-team): If the user has an unsupported system image installed,
337 # should we print a warning? This includes all 64-bit system-images.
338 pass
Adam Michaelee9a3002017-02-01 18:15:45 +0000339
vladmos20a042f2018-06-01 04:51:21 -0700340 for (tag, api, arch) in supported_system_images:
341 name = "emulator_images_%s_%s_%s" % (tag, api, arch)
342 if name in installed_system_images_dirs:
343 system_image_dir = installed_system_images_dirs[name]
344
345 # For supported system images that exist in /sdk/system-images/, we
346 # create a filegroup with their contents.
347 native.filegroup(
348 name = name,
349 srcs = native.glob([
350 "%s/**" % system_image_dir,
351 ]),
352 )
353 native.filegroup(
354 name = "%s_qemu2_extra" % name,
355 srcs = native.glob(["%s/kernel-ranchu" % system_image_dir]),
356 )
357 else:
358 # For supported system images that are not installed in the SDK, we
359 # create a "poison pill" genrule to display a helpful error message to
360 # a user who attempts to run a test against an android_device that
361 # they don't have the system image for installed.
362 native.genrule(
363 name = name,
364 outs = [
365 # Necessary so that the build doesn't fail in analysis because
366 # android_device expects a file named source.properties.
367 "poison_pill_for_%s/source.properties" % name,
368 ],
369 cmd = """echo \
ajmichael8d876cf2017-04-12 01:34:08 +0000370 This rule requires that the Android SDK used by Bazel has the \
371 following system image installed: %s. Please install this system \
372 image through the Android SDK Manager and try again. ; \
373 exit 1
374 """ % name,
vladmos20a042f2018-06-01 04:51:21 -0700375 )
376 native.filegroup(
377 name = "%s_qemu2_extra" % name,
378 srcs = [],
379 )