[Build] Migrate Android NDK, android rules and platforms (#36116)

This commit does the following 3 things for Android bazel rules, which depends on each other

1. Update NDK to 26.2.11394342 (and a few other Android things)
2. Use rules_android_ndk instead of builtin `native.android_ndk_repository`
    * `third_party/android/android_configure.bzl` was a workaround for users who don't set `$ANDROID_NDK_HOME` env var. Now with rules_android_ndk, we can declare repo without registering the toolchain. Instead users who need NDK toolchain should use `--extra_toolchains` to manually register the toolchain, as shown in README.md.
3. Migrate to platforms. See https://bazel.build/concepts/platforms
    * Currently we declares android platforms that is needed for binder transport APK. Later gRPC repo can gradually migrate to platforms for other platforms.
    * The value of `crosstool_top` will still be `//external:android/crosstool` (which is the default value), so existings android `config_settings` will still work. We should migrate them to match with `@platforms//os:android` constraint later.

The platforms migration needs Bazel 7.0 to work so we also override bazel version in testing scripts.

Closes #36116

PiperOrigin-RevId: 617244655
pull/36152/head
Ming-Chuan 8 months ago committed by Copybara-Service
parent bb9f4466e1
commit d6bb391449
  1. 26
      BUILD
  2. 31
      WORKSPACE
  3. 25
      examples/android/binder/java/io/grpc/binder/cpp/README.md
  4. 2
      examples/android/binder/java/io/grpc/binder/cpp/exampleclient/BUILD
  5. 2
      examples/android/binder/java/io/grpc/binder/cpp/exampleserver/BUILD
  6. 33
      templates/tools/dockerfile/test/binder_transport_apk/Dockerfile.template
  7. 3
      third_party/android/BUILD
  8. 62
      third_party/android/android_configure.bzl
  9. 6
      third_party/cares/cares.BUILD
  10. 2
      tools/bazelify_tests/dockerimage_current_versions.bzl
  11. 2
      tools/dockerfile/test/binder_transport_apk.current_version
  12. 23
      tools/dockerfile/test/binder_transport_apk/Dockerfile
  13. 14
      tools/internal_ci/linux/grpc_binder_transport_apk_build_in_docker.sh

26
BUILD

@ -65,6 +65,30 @@ bool_flag(
build_setting_default = False,
)
platform(
name = "android_x86_64",
constraint_values = [
"@platforms//os:android",
"@platforms//cpu:x86_64",
],
)
platform(
name = "android_arm64",
constraint_values = [
"@platforms//os:android",
"@platforms//cpu:arm64",
],
)
platform(
name = "android_armv7",
constraint_values = [
"@platforms//os:android",
"@platforms//cpu:armv7",
],
)
config_setting(
name = "grpc_no_rls_flag",
flag_values = {":disable_grpc_rls": "true"},
@ -84,6 +108,8 @@ config_setting(
config_setting(
name = "android",
values = {"crosstool_top": "//external:android/crosstool"},
# TODO: Use constraint_values to detect android after Bazel 7.0 platforms migration is finished
# constraint_values = [ "@platforms//os:android" ],
)
config_setting(

@ -27,19 +27,34 @@ custom_exec_properties(
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "build_bazel_rules_android",
sha256 = "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
strip_prefix = "rules_android-0.1.1",
urls = ["https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"],
name = "platforms",
sha256 = "8150406605389ececb6da07cbcb509d5637a3ab9a24bc69b1101531367d89d74",
urls = ["https://github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz"],
)
load("//third_party/android:android_configure.bzl", "android_configure")
RULES_ANDROID_NDK_COMMIT = "010f4f17dd13a8baaaacc28ba6c8c2c75f54c68b"
android_configure(name = "local_config_android")
RULES_ANDROID_NDK_SHA = "2ab6a97748772f289331d75caaaee0593825935d1d9d982231a437fb8ab5a14d"
load("@local_config_android//:android_configure.bzl", "android_workspace")
http_archive(
name = "rules_android_ndk",
sha256 = RULES_ANDROID_NDK_SHA,
strip_prefix = "rules_android_ndk-%s" % RULES_ANDROID_NDK_COMMIT,
url = "https://github.com/bazelbuild/rules_android_ndk/archive/%s.zip" % RULES_ANDROID_NDK_COMMIT,
)
android_sdk_repository(
name = "androidsdk",
build_tools_version = "34.0.0",
)
load("@rules_android_ndk//:rules.bzl", "android_ndk_repository")
android_ndk_repository(name = "androidndk")
android_workspace()
# Note that we intentionally avoid calling `register_toolchains("@androidndk//:all")`
# here, because the toolchain rule fails when $ANDROID_NDK_HOME is not set.
# Use `--extra_toolchains=@androidndk//:all` to manually register it when building for Android.
# Prevents bazel's '...' expansion from including the following folder.
# This is required because the BUILD file in the following folder

@ -1,20 +1,23 @@
# gRPC-core BinderTransport example apps
WIP.
## Build Instruction
1. Install Android SDK and NDK. Currently we only support SDK version 30.0.3 and
NDK version 21.4.7075529 . Make sure you get these exact versions otherwise
Bazel might complain.
2. Point environment variables to install locations of SDK and NDK
1. Install Android SDK and NDK. Only NDK version >= 25 is supported. We tested against SDK Platform `33` and NDK `26.2.11394342`.
2. Make sure Bazel is at least `7.0`. Use `export OVERRIDE_BAZEL_VERSION=7.1.0` to selected a supported version listed in `bazel/supported_versions.txt` if necessary.
3. Point environment variables to install locations of SDK and NDK
```
export ANDROID_HOME=$HOME/android-sdk
export ANDROID_NDK_HOME=$HOME/android-sdk/ndk/26.2.11394342
```
4. To build a fat APK that supports `x86_64`, `armv7`, and `arm64`:
```
export ANDROID_HOME=$HOME/Android/Sdk/
export ANDROID_NDK_HOME=$HOME/Android/Sdk/ndk/21.4.7075529
bazel build \
--extra_toolchains=@androidndk//:all \
--android_platforms=//:android_x86_64,//:android_armv7,//:android_arm64 \
--copt=-Wno-unknown-warning-option \
//examples/android/binder/java/io/grpc/binder/cpp/exampleserver:app \
//examples/android/binder/java/io/grpc/binder/cpp/exampleclient:app
```
3. `bazel build //examples/android/binder/java/io/grpc/binder/cpp/exampleclient:app`
4. `bazel build //examples/android/binder/java/io/grpc/binder/cpp/exampleserver:app`
5. `adb install
bazel-bin/examples/android/binder/java/io/grpc/binder/cpp/exampleclient/app.apk`
6. `adb install

@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("@build_bazel_rules_android//android:rules.bzl", "android_binary", "android_library")
cc_library(
name = "jni_lib",
srcs = ["native.cc"],

@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("@build_bazel_rules_android//android:rules.bzl", "android_binary", "android_library")
cc_library(
name = "jni_lib",
srcs = ["native.cc"],

@ -19,26 +19,31 @@
#========================
# Java
RUN apt-get install -y openjdk-8-jdk
RUN apt-get install -y openjdk-21-jdk
#========================
# Android SDK/NDK installation
ENV SDK_ROOT=/opt/android-sdk
ENV ANDROID_SDK_VERSION 11076708
ENV ANDROID_NDK_VERSION 26.2.11394342
ENV SDK_ROOT /opt/android-sdk
RUN mkdir -p $SDK_ROOT
RUN wget -O cmd.zip dl.google.com/android/repository/commandlinetools-linux-7302050_latest.zip && \
unzip cmd.zip && rm cmd.zip && \
yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'tools' && \
yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'platform-tools' && \
yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'build-tools;30.0.3' && \
yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'platforms;android-29' && \
yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'ndk-bundle' && \
yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'ndk;21.4.7075529'
RUN cd $SDK_ROOT && \
wget -O cmd.zip https://dl.google.com/android/repository/commandlinetools-linux-${'${ANDROID_SDK_VERSION}'}_latest.zip && \
unzip -q cmd.zip && \
rm cmd.zip
# Set environment variables for Bazel rules
ENV ANDROID_HOME=/opt/android-sdk
ENV ANDROID_NDK_HOME=/opt/android-sdk/ndk/21.4.7075529
RUN yes | $SDK_ROOT/cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT --licenses # accept all licenses
RUN mkdir -p /var/local/jenkins
# This is not required but desirable to reduce the time to download and the chance of download failure.
RUN mkdir -p ~/.android && touch ~/.android/repositories.cfg
RUN $SDK_ROOT/cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT "ndk;$ANDROID_NDK_VERSION" "platforms;android-33" "build-tools;34.0.0"
# Set environment variables for Bazel rules
ENV ANDROID_HOME $SDK_ROOT
ENV ANDROID_NDK_HOME $SDK_ROOT/ndk/$ANDROID_NDK_VERSION
# Define the default command.
CMD ["bash"]

@ -1,3 +0,0 @@
exports_files([
"android_configure.bzl",
])

@ -1,62 +0,0 @@
"""Repository rule for Android SDK and NDK autoconfiguration.
This rule is a no-op unless the required android environment variables are set.
"""
# Based on https://github.com/tensorflow/tensorflow/tree/34c03ed67692eb76cb3399cebca50ea8bcde064c/third_party/android
# Workaround for https://github.com/bazelbuild/bazel/issues/14260
_ANDROID_NDK_HOME = "ANDROID_NDK_HOME"
_ANDROID_SDK_HOME = "ANDROID_HOME"
def _escape_for_windows(path):
"""Properly escape backslashes for Windows.
Ideally, we would do this conditionally, but there is seemingly no way to
determine whether or not this is being called from Windows.
"""
return path.replace("\\", "\\\\")
def _android_autoconf_impl(repository_ctx):
sdk_home = repository_ctx.os.environ.get(_ANDROID_SDK_HOME)
ndk_home = repository_ctx.os.environ.get(_ANDROID_NDK_HOME)
# version 31.0.0 won't work https://stackoverflow.com/a/68036845
sdk_rule = ""
if sdk_home:
sdk_rule = """
native.android_sdk_repository(
name="androidsdk",
path="{}",
build_tools_version="30.0.3",
)
""".format(_escape_for_windows(sdk_home))
# Note that Bazel does not support NDK 22 yet, and Bazel 3.7.1 only
# supports up to API level 29 for NDK 21
ndk_rule = ""
if ndk_home:
ndk_rule = """
native.android_ndk_repository(
name="androidndk",
path="{}",
)
""".format(_escape_for_windows(ndk_home))
if ndk_rule == "" and sdk_rule == "":
sdk_rule = "pass"
repository_ctx.file("BUILD.bazel", "")
repository_ctx.file("android_configure.bzl", """
def android_workspace():
{}
{}
""".format(sdk_rule, ndk_rule))
android_configure = repository_rule(
implementation = _android_autoconf_impl,
environ = [
_ANDROID_NDK_HOME,
_ANDROID_SDK_HOME,
],
)

@ -29,9 +29,9 @@ config_setting(
# This just helps with the build for now.
config_setting(
name = "android",
values = {
"crosstool_top": "//external:android/crosstool",
},
values = {"crosstool_top": "//external:android/crosstool"},
# TODO: Use constraint_values to detect android after Bazel 7.0 platforms migration is finished
# constraint_values = [ "@platforms//os:android" ],
)
# iOS is not officially supported through C++.

@ -90,7 +90,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = {
"tools/dockerfile/test/android_ndk.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/android_ndk@sha256:ab154ecb062af2111d2d3550c4d3da3384201d9893bbd37d49e8160fc34bc137",
"tools/dockerfile/test/bazel.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/bazel@sha256:eb327f8e44f2712f557de1d8918c41c3cba1112c4b39b13104c29211ed8f827a",
"tools/dockerfile/test/bazel_arm64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/bazel_arm64@sha256:6cddc0ecdb42a7db7105b73fc3192edb911702102d1bac671e26d44a17d7aa95",
"tools/dockerfile/test/binder_transport_apk.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/binder_transport_apk@sha256:a680a8b7d645a2c25948ad3f82f6380c8a1e13fcfe74fc3569acb3b0b202851e",
"tools/dockerfile/test/binder_transport_apk.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/binder_transport_apk@sha256:ff64e263dfa5491ee6fddd7f0d7c1a20ba756636655849a3b923c665d78c8ef2",
"tools/dockerfile/test/csharp_debian11_arm64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/csharp_debian11_arm64@sha256:4d4bc5f15e03f3d3d8fd889670ecde2c66a2e4d2dd9db80733c05c1d90c8a248",
"tools/dockerfile/test/csharp_debian11_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/csharp_debian11_x64@sha256:b2e5c47d986312ea0850e2f2e696b45d23ee0aabceea161d31e28559e19ec4a5",
"tools/dockerfile/test/cxx_alpine_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_alpine_x64@sha256:f2019edf9f2afd5042567f11afb1aa78a789fc9acdcce5ee0c14cc11f6830ed7",

@ -1 +1 @@
us-docker.pkg.dev/grpc-testing/testing-images-public/binder_transport_apk:fbe8a32dd2006fab456f2fa0d0e82d3979b7f30b@sha256:a680a8b7d645a2c25948ad3f82f6380c8a1e13fcfe74fc3569acb3b0b202851e
us-docker.pkg.dev/grpc-testing/testing-images-public/binder_transport_apk:611a0d410d3032bc41175599a5f1495a07759c1f@sha256:ff64e263dfa5491ee6fddd7f0d7c1a20ba756636655849a3b923c665d78c8ef2

@ -60,19 +60,28 @@ RUN BAZEL_ARCH_SUFFIX="$(uname -m | sed s/aarch64/arm64/)" \
#========================
# Java
RUN apt-get install -y openjdk-8-jdk
RUN apt-get install -y openjdk-21-jdk
#========================
# Android SDK/NDK installation
ENV SDK_ROOT=/opt/android-sdk
ENV ANDROID_SDK_VERSION 11076708
ENV ANDROID_NDK_VERSION 26.2.11394342
ENV SDK_ROOT /opt/android-sdk
RUN mkdir -p $SDK_ROOT
RUN wget -O cmd.zip dl.google.com/android/repository/commandlinetools-linux-7302050_latest.zip && unzip cmd.zip && rm cmd.zip && yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'tools' && yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'platform-tools' && yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'build-tools;30.0.3' && yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'platforms;android-29' && yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'ndk-bundle' && yes | ./cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT 'ndk;21.4.7075529'
RUN cd $SDK_ROOT && wget -O cmd.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_VERSION}_latest.zip && unzip -q cmd.zip && rm cmd.zip
# Set environment variables for Bazel rules
ENV ANDROID_HOME=/opt/android-sdk
ENV ANDROID_NDK_HOME=/opt/android-sdk/ndk/21.4.7075529
RUN yes | $SDK_ROOT/cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT --licenses # accept all licenses
RUN mkdir -p /var/local/jenkins
# This is not required but desirable to reduce the time to download and the chance of download failure.
RUN mkdir -p ~/.android && touch ~/.android/repositories.cfg
RUN $SDK_ROOT/cmdline-tools/bin/sdkmanager --sdk_root=$SDK_ROOT "ndk;$ANDROID_NDK_VERSION" "platforms;android-33" "build-tools;34.0.0"
# Set environment variables for Bazel rules
ENV ANDROID_HOME $SDK_ROOT
ENV ANDROID_NDK_HOME $SDK_ROOT/ndk/$ANDROID_NDK_VERSION
# Define the default command.
CMD ["bash"]

@ -18,19 +18,15 @@ set -ex
echo $ANDROID_HOME
echo $ANDROID_NDK_HOME
# Build all targets using the strict warning option which leverages the
# clang compiler to check if sources can pass a set of warning options.
# CPU are specified because gRPC does not build with 32bit NDK (which has socklen_t
# defined as int due to an accident).
# The python option is for disabling python2 enforcement when packing APK
# Android platforms only works with Bazel >= 7.0
export OVERRIDE_BAZEL_VERSION=7.1.0
python3 tools/run_tests/python_utils/bazel_report_helper.py --report_path bazel_binder_example_app
bazel_binder_example_app/bazel_wrapper \
--bazelrc=tools/remote_build/include/test_locally_with_resultstore_results.bazelrc \
build \
--define=use_strict_warning=true \
--copt=-Wno-unknown-warning-option \
--fat_apk_cpu=x86_64,arm64-v8a \
--extra_toolchains=@rules_python//python:autodetecting_toolchain_nonstrict \
--extra_toolchains=@androidndk//:all \
--android_platforms=//:android_x86_64,//:android_armv7,//:android_arm64 \
//examples/android/binder/java/io/grpc/binder/cpp/exampleclient:app \
//examples/android/binder/java/io/grpc/binder/cpp/exampleserver:app

Loading…
Cancel
Save