Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def _android_impl(module_ctx):
name = "androidsdk_{}".format(platform)
hermetic_android_sdk_platform_repository(
name = name,
shared_root = "@androidsdk//:.sdk-root",
platform = platform,
**kwargs
)
Expand Down
12 changes: 12 additions & 0 deletions ndk/BUILD.androidndk.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ exports_files([
"sources/android/native_app_glue/android_native_app_glue.h",
])

# A single source file whose physical parent is the complete downloaded NDK.
filegroup(
name = "ndk_root",
srcs = ["source.properties"],
)

# glob does not cross the clang and sysroot package boundaries.
filegroup(
name = "all_files",
srcs = glob(["**/*"]) + ["//{clang_directory}:all_files"],
)

cc_library(
name = "cpufeatures",
srcs = glob(["sources/android/cpufeatures/*.c"]),
Expand Down
16 changes: 16 additions & 0 deletions ndk/BUILD.ndkredirect.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ load("//:target_systems.bzl", "CPU_CONSTRAINT", "TARGET_SYSTEM_NAMES")

package(default_visibility = ["//visibility:public"])

# Select the installation for the consumer's platform. Local path exporters
# should request these labels in the host configuration.
[
alias(
name = name,
actual = select({
"@hermetic_android_toolchains//:platform_{}".format(platform): "@androidndk_{}//:{}".format(platform, name)
for platform in ANDROID_PLATFORMS
}),
)
for name in [
"all_files",
"ndk_root",
]
]

[
toolchain(
name = "toolchain_{}_{}".format(platform_name, target_system_name),
Expand Down
6 changes: 5 additions & 1 deletion ndk/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ def _hermetic_android_ndk_platform_repository_impl(rctx):

rctx.file("ndk/.keep", "")
rctx.symlink(rctx.path("sources"), "ndk/sources")
rctx.symlink(Label("//ndk:BUILD.androidndk.bazel"), "BUILD.bazel")
rctx.template(
"BUILD.bazel",
Label("//ndk:BUILD.androidndk.bazel"),
{"{clang_directory}": _PLATFORMS[rctx.attr.platform]["clang_directory"]},
)
rctx.template(
"target_systems.bzl",
rctx.attr._template_target_systems,
Expand Down
6 changes: 6 additions & 0 deletions sdk/BUILD.androidsdk.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ load("@rules_shell//shell:sh_binary.bzl", "sh_binary")

package(default_visibility = ["//visibility:public"])

# Resolve this file's physical parent to obtain a standard Android SDK layout.
filegroup(
name = "sdk_root",
srcs = ["sdk/.root"],
)

%{platform_rules}

%{platform_aliases}
Expand Down
1 change: 1 addition & 0 deletions sdk/BUILD.sdkredirect.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
package(default_visibility = ["//visibility:public"])

exports_files([
".sdk-root",
"platforms/android-%{api_level}/android.jar",
"platforms/android-%{api_level}/core-for-system-modules.jar",
"platforms/android-%{api_level}/framework.aidl",
Expand Down
65 changes: 65 additions & 0 deletions sdk/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,7 @@ def _platform_redirect_aliases(rctx, sdk):
_platform_redirect_alias(rctx, sdk, "build_tools_libs"),
_platform_redirect_alias(rctx, sdk, "dexdump"),
_platform_redirect_alias(rctx, sdk, "files"),
_platform_redirect_alias(rctx, sdk, "sdk_root"),
_platform_redirect_alias(rctx, sdk, "main_dex_classes"),
_platform_redirect_alias(rctx, sdk, "zipalign"),
_platform_redirect_alias(rctx, sdk, "zipalign_binary"),
Expand Down Expand Up @@ -820,6 +821,20 @@ def _write_runner_scripts(rctx, sdk):
executable = True,
)

def _write_sdk_layout(rctx, emulator):
# Gradle and other SDK consumers expect build-tools/<version>, without the
# extra host-platform directory used by the Bazel tool labels.
platform = rctx.attr.platform
shared_root = rctx.path(rctx.attr.shared_root).dirname
rctx.file("sdk/.root", "")
rctx.symlink(shared_root.get_child("platforms"), "sdk/platforms")
rctx.symlink(rctx.path("build-tools/{}".format(platform)), "sdk/build-tools")
rctx.symlink(rctx.path("platform-tools/{}".format(platform)), "sdk/platform-tools")
if emulator:
rctx.symlink(rctx.path("emulator"), "sdk/emulator")
if rctx.attr.system_images:
rctx.symlink(shared_root.get_child("system-images"), "sdk/system-images")

def _hermetic_android_sdk_platform_repository_impl(rctx):
if not rctx.attr.version:
fail("hermetic_android_sdk_platform_repository requires version.")
Expand All @@ -832,6 +847,7 @@ def _hermetic_android_sdk_platform_repository_impl(rctx):
_download_sdk_platform_tools(rctx, sdk)
_download_emulator(rctx, emulator)
_write_runner_scripts(rctx, sdk)
_write_sdk_layout(rctx, emulator)

rctx.template(
"BUILD.bazel",
Expand Down Expand Up @@ -864,6 +880,7 @@ hermetic_android_sdk_platform_repository = repository_rule(
"platforms_url": attr.string(),
"system_images": attr.string_list(),
"platform": attr.string(mandatory = True, values = sorted(ANDROID_PLATFORMS.keys())),
"shared_root": attr.label(mandatory = True, allow_single_file = True),
"version": attr.string(mandatory = True),
"_versions_json": attr.label(
default = Label("//sdk:versions.json"),
Expand All @@ -873,6 +890,52 @@ hermetic_android_sdk_platform_repository = repository_rule(
environ = [ANDROID_SDK_LICENSE_ENV],
)

def _xml_escape(value):
return value.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;").replace("'", "&apos;")

def _write_platform_package_metadata(rctx, sdk):
directory = "platforms/android-{}".format(sdk["api_level"])
if rctx.path(directory + "/package.xml").exists:
return
properties = {}
for line in rctx.read(directory + "/source.properties").splitlines():
key, separator, value = line.partition("=")
if separator:
properties[key.strip()] = value.strip()
revision = properties["Pkg.Revision"].split(".")
revision_xml = "".join([
"<{0}>{1}</{0}>".format(part, int(value))
for part, value in zip(["major", "minor", "micro"], revision)
])
details = ["<api-level>{}</api-level>".format(_xml_escape(properties["AndroidVersion.ApiLevel"]))]
if properties.get("AndroidVersion.CodeName"):
details.append("<codename>{}</codename>".format(_xml_escape(properties["AndroidVersion.CodeName"])))
if properties.get("AndroidVersion.ExtensionLevel"):
details.append("<extension-level>{}</extension-level>".format(int(properties["AndroidVersion.ExtensionLevel"])))
details.extend([
"<base-extension>{}</base-extension>".format(properties.get("AndroidVersion.IsBaseSdk", "true")),
'<layoutlib api="{}"/>'.format(int(properties.get("Layoutlib.Api", "0"))),
])

# SDK Manager normally writes this after extraction. AGP's legacy parser
# cannot discover platforms whose source.properties API level is decimal.
rctx.file(directory + "/package.xml", """<?xml version="1.0" encoding="UTF-8"?>
<repository xmlns="http://schemas.android.com/repository/android/common/02"
xmlns:sdk="http://schemas.android.com/sdk/android/repo/repository2/03"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<localPackage xmlns="" path="{path}" obsolete="false">
<type-details xsi:type="sdk:platformDetailsType">{details}</type-details>
<revision>{revision}</revision>
<display-name>{description}</display-name>
</localPackage>
</repository>
""".format(
path = _xml_escape(directory.replace("/", ";")),
details = "".join(details),
revision = revision_xml,
description = _xml_escape(properties["Pkg.Desc"]),
))

def _hermetic_android_sdk_repository_impl(rctx):
if not rctx.attr.version:
fail("hermetic_android_sdk_repository requires version.")
Expand All @@ -893,6 +956,8 @@ def _hermetic_android_sdk_repository_impl(rctx):
strip_prefix = sdk["platforms_strip_prefix"],
)

_write_platform_package_metadata(rctx, sdk)
rctx.file(".sdk-root", "")
rctx.symlink(Label("@rules_android//rules/android_sdk_repository:helper.bzl"), "helper.bzl")
rctx.template(
"BUILD.bazel",
Expand Down
3 changes: 3 additions & 0 deletions tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ _SDK_PLATFORM_SPECIFIC_TARGETS = [
"build_tools_libs",
"dexdump",
"files",
"sdk_root",
"platform-tools/adb",
"zipalign",
"zipalign_binary",
Expand All @@ -86,6 +87,8 @@ _SDK_HUB_TARGETS = [
build_test(
name = "valid_labels_build_test",
targets = [
"@androidndk//:ndk_root",
"@androidndk//:all_files",
"@androidsdk//:emulator_images_android_24_arm",
"@androidsdk//:emulator_images_android_28_arm64-v8a",
"@androidsdk//:emulator_images_android_28_arm64-v8a_qemu2_extra",
Expand Down
Loading