Skip to content

Commit 6af1696

Browse files
committed
Build android using bazel too (bzlmod only)
1 parent 94c6595 commit 6af1696

6 files changed

Lines changed: 152 additions & 56 deletions

File tree

.bazelrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
build --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
2+
3+
common:skip_android --deleted_packages=android

.github/workflows/testing.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ jobs:
8080
strategy:
8181
matrix:
8282
bzlmod: [true, false]
83-
env:
84-
USE_BAZEL_VERSION: 8.7.0
8583

8684
steps:
8785
- uses: actions/checkout@v4
@@ -100,10 +98,10 @@ jobs:
10098
key: ${{ runner.os }}-bazel-${{ env.USE_BAZEL_VERSION }}-${{ hashFiles('WORKSPACE', 'repositories.bzl') }}
10199

102100
- name: Run bazel build
103-
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }}
101+
run: bazelisk build //... --config=skip_android --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }}
104102

105103
- name: Run bazel test
106-
run: bazelisk test //... --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }}
104+
run: bazelisk test //... --config=skip_android --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }}
107105

108106
- name: Run example bazel build
109107
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }}

COMPILING.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,14 @@ To build the grpc-java library:
164164
$ bazelisk build //...
165165
```
166166

167+
Some parts of grpc-java depend on Android. Bazel can build these parts too but,
168+
for size, licensing and maintenance reasons, it requires a locally installed
169+
Android SDK. If you don't have the SDK and/or don't care about Android, use the
170+
`skip_android` configuration to skip building the Android parts:
171+
172+
```sh
173+
$ bazelisk build //... --config=skip_android
174+
```
175+
167176
You cannot run the tests from Bazel at this time.
168177

MODULE.bazel

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,31 @@ IO_GRPC_GRPC_JAVA_ARTIFACTS = [
4646
]
4747
# GRPC_DEPS_END
4848

49+
ANDROID_ARTIFACTS = [
50+
"androidx.annotation:annotation:1.6.0",
51+
"androidx.annotation:annotation-jvm:1.6.0",
52+
"androidx.core:core:1.13.1",
53+
"androidx.lifecycle:lifecycle-common:2.6.2",
54+
]
55+
4956
bazel_dep(name = "abseil-cpp", version = "20250512.1")
5057
bazel_dep(name = "bazel_jar_jar", version = "0.1.11.bcr.1")
5158
bazel_dep(name = "bazel_skylib", version = "1.7.1")
5259
bazel_dep(name = "googleapis", version = "0.0.0-20240326-1c8d509c5", repo_name = "com_google_googleapis")
5360
bazel_dep(name = "grpc-proto", version = "0.0.0-20240627-ec30f58.bcr.1", repo_name = "io_grpc_grpc_proto")
5461
bazel_dep(name = "protobuf", version = "33.4", repo_name = "com_google_protobuf")
62+
bazel_dep(name = "rules_android", version = "0.7.2")
5563
bazel_dep(name = "rules_cc", version = "0.0.9")
5664
bazel_dep(name = "rules_java", version = "9.1.0")
5765
bazel_dep(name = "rules_jvm_external", version = "6.0")
5866

67+
android_sdk_repository_extension = use_extension(
68+
"@rules_android//rules/android_sdk_repository:rule.bzl",
69+
"android_sdk_repository_extension",
70+
)
71+
use_repo(android_sdk_repository_extension, "androidsdk")
72+
register_toolchains("@androidsdk//:sdk-toolchain", "@androidsdk//:all")
73+
5974
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
6075
maven.install(
6176
artifacts = IO_GRPC_GRPC_JAVA_ARTIFACTS,
@@ -64,7 +79,36 @@ maven.install(
6479
],
6580
strict_visibility = True,
6681
)
67-
use_repo(maven, "maven")
82+
83+
# We isolate Android-specific deps in this separate repo ('grpc_android_maven') instead of the one
84+
# above (having default name 'maven').
85+
#
86+
# Under bzlmod, rules_jvm_external merges all contributions to the same named repository (like the
87+
# default 'maven' repo) across the entire dependency graph. If we put Android dependencies there,
88+
# then *every* downstream consumer's merged 'maven' repository would include these Android
89+
# artifacts.
90+
#
91+
# Because merged repositories are resolved using only the root module's (the consumer's)
92+
# repository list, any consumer without 'maven.google.com' configured in their root module
93+
# would fail to resolve these artifacts, breaking their build even if they don't use Android.
94+
#
95+
# By using a distinct name ('grpc_android_maven'), we prevent merging. This repository is resolved
96+
# independently, allowing it to use grpc-java's own repository config (which includes
97+
# maven.google.com) without affecting downstream consumers' default 'maven' repo.
98+
maven.install(
99+
name = "grpc_android_maven",
100+
artifacts = ANDROID_ARTIFACTS,
101+
repositories = [
102+
"https://repo.maven.apache.org/maven2/",
103+
"https://maven.google.com", # for androidx.*
104+
],
105+
strict_visibility = True,
106+
# Enable Starlark Android rules in rules_jvm_external for Bazel 8+ compatibility.
107+
use_starlark_android_rules = True,
108+
# Explicitly set the label for aar_import since the default guess is incorrect under Bzlmod.
109+
aar_import_bzl_label = "@rules_android//rules:rules.bzl",
110+
)
111+
use_repo(maven, "maven", "grpc_android_maven")
68112

69113
maven.override(
70114
coordinates = "com.google.protobuf:protobuf-java",
@@ -158,3 +202,7 @@ maven.override(
158202
coordinates = "io.grpc:grpc-util",
159203
target = "@io_grpc_grpc_java//util",
160204
)
205+
maven.override(
206+
coordinates = "io.grpc:grpc-binder",
207+
target = "@io_grpc_grpc_java//binder",
208+
)

android/BUILD.bazel

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
load("@rules_android//rules:rules.bzl", "android_library")
2+
load("@rules_jvm_external//:defs.bzl", "artifact")
3+
4+
licenses(["notice"])
5+
6+
android_library(
7+
name = "android",
8+
srcs = glob([
9+
"src/main/java/**/*.java",
10+
]),
11+
manifest = "src/main/AndroidManifest.xml",
12+
custom_package = "io.grpc.android",
13+
visibility = ["//visibility:public"],
14+
deps = [
15+
"//api",
16+
"//core:internal",
17+
artifact("com.google.code.findbugs:jsr305"),
18+
artifact("com.google.errorprone:error_prone_annotations"),
19+
artifact("com.google.guava:guava"),
20+
],
21+
)

buildscripts/kokoro/android.sh

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,36 @@ cat <<EOF >> gradle.properties
1919
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=1024m
2020
EOF
2121

22-
export ANDROID_HOME=/tmp/Android/Sdk
22+
export ANDROID_HOME=$HOME/Android/Sdk
2323
mkdir -p "${ANDROID_HOME}/cmdline-tools"
2424
curl -Ls -o cmdline.zip \
2525
"https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip"
2626
unzip -qd "${ANDROID_HOME}/cmdline-tools" cmdline.zip
2727
rm cmdline.zip
2828
mv "${ANDROID_HOME}/cmdline-tools/cmdline-tools" "${ANDROID_HOME}/cmdline-tools/latest"
2929
(yes || true) | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" --licenses
30+
31+
# Bazel/android_rules requires build-tools at least version 35.0.0 and, unlike
32+
# gradle, won't download anything for itself.
33+
# TODO(jdcormie): Keep this version in sync with AGP's default and any
34+
# `buildToolsVersion` config.
35+
"${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" --install "build-tools;35.0.1"
36+
37+
# Bazelisk takes care of installing the proper version(s) of Bazel.
38+
mkdir -p /tmp/bazelisk
39+
curl -Ls -o /tmp/bazelisk/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.19.0/bazelisk-linux-amd64
40+
chmod +x /tmp/bazelisk/bazelisk
41+
export PATH=/tmp/bazelisk:$PATH
42+
43+
# TODO(jdcormie): Use the same SDK version as build.gradle's compileSdkVersion.
44+
"${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" --install "platforms;android-34"
45+
bazelisk build \
46+
//android
47+
3048
curl -Ls https://github.com/Kitware/CMake/releases/download/v3.26.3/cmake-3.26.3-linux-x86_64.tar.gz | \
3149
tar xz -C /tmp
3250
export PATH=/tmp/cmake-3.26.3-linux-x86_64/bin:$PATH
33-
51+
3452
# Proto deps
3553
buildscripts/make_dependencies.sh
3654

@@ -99,52 +117,52 @@ new_apk_size="$(stat --printf=%s $HELLO_WORLD_OUTPUT_DIR/apk/release/app-release
99117

100118

101119
# Get the APK size and dex count stats using the pull request base commit
102-
cd $BASE_DIR/github/grpc-java
103-
./gradlew clean
104-
git checkout HEAD^
105-
./gradlew --stop # use a new daemon to build the previous commit
106-
GRADLE_FLAGS="${GRADLE_FLAGS} -PskipCodegen=true" # skip codegen for build from previous commit since it wasn't built with --std=c++14 when making this change
107-
./gradlew publishToMavenLocal $GRADLE_FLAGS
108-
cd examples/android/helloworld/
109-
../../gradlew build $GRADLE_FLAGS
110-
111-
read -r ignored old_dex_count < \
112-
<("${ANDROID_HOME}/cmdline-tools/latest/bin/apkanalyzer" dex references app/build/outputs/apk/release/app-release-unsigned.apk)
113-
114-
set +x
115-
all_old_methods=`"${ANDROID_HOME}/cmdline-tools/latest/bin/apkanalyzer" dex packages --proguard-mapping app/build/outputs/mapping/release/mapping.txt app/build/outputs/apk/release/app-release-unsigned.apk | grep ^M | cut -f4 | sort`
116-
set -x
117-
118-
old_apk_size="$(stat --printf=%s app/build/outputs/apk/release/app-release-unsigned.apk)"
119-
120-
dex_count_delta="$((new_dex_count-old_dex_count))"
121-
122-
apk_size_delta="$((new_apk_size-old_apk_size))"
123-
124-
set +x
125-
dex_method_diff=`diff -u <(echo "$all_old_methods") <(echo "$all_new_methods") || true`
126-
set -x
127-
128-
if [[ -n "$dex_method_diff" ]]
129-
then
130-
echo "Method diff: ${dex_method_diff}"
131-
fi
132-
133-
# Update the statuses with the deltas
134-
135-
set +x
136-
gsutil cp gs://grpc-testing-secrets/github_credentials/oauth_token.txt ~/
137-
138-
desc="New DEX reference count: $(printf "%'d" "$new_dex_count") (delta: $(printf "%'d" "$dex_count_delta"))"
139-
echo "Setting status: $desc"
140-
curl -f -s -X POST -H "Content-Type: application/json" \
141-
-H "Authorization: token $(cat ~/oauth_token.txt | tr -d '\n')" \
142-
-d '{"state": "success", "context": "android/dex_diff", "description": "'"${desc}"'"}' \
143-
"https://api.github.com/repos/grpc/grpc-java/statuses/${KOKORO_GITHUB_PULL_REQUEST_COMMIT}"
144-
145-
desc="New APK size in bytes: $(printf "%'d" "$new_apk_size") (delta: $(printf "%'d" "$apk_size_delta"))"
146-
echo "Setting status: $desc"
147-
curl -f -s -X POST -H "Content-Type: application/json" \
148-
-H "Authorization: token $(cat ~/oauth_token.txt | tr -d '\n')" \
149-
-d '{"state": "success", "context": "android/apk_diff", "description": "'"${desc}"'"}' \
150-
"https://api.github.com/repos/grpc/grpc-java/statuses/${KOKORO_GITHUB_PULL_REQUEST_COMMIT}"
120+
#cd $BASE_DIR/github/grpc-java
121+
#./gradlew clean
122+
#git checkout HEAD^
123+
#./gradlew --stop # use a new daemon to build the previous commit
124+
#GRADLE_FLAGS="${GRADLE_FLAGS} -PskipCodegen=true" # skip codegen for build from previous commit since it wasn't built with --std=c++14 when making this change
125+
#./gradlew publishToMavenLocal $GRADLE_FLAGS
126+
#cd examples/android/helloworld/
127+
#../../gradlew build $GRADLE_FLAGS
128+
129+
#read -r ignored old_dex_count < \
130+
# <("${ANDROID_HOME}/cmdline-tools/latest/bin/apkanalyzer" dex references app/build/outputs/apk/release/app-release-unsigned.apk)
131+
132+
#set +x
133+
#all_old_methods=`"${ANDROID_HOME}/cmdline-tools/latest/bin/apkanalyzer" dex packages --proguard-mapping app/build/outputs/mapping/release/mapping.txt app/build/outputs/apk/release/app-release-unsigned.apk | grep ^M | cut -f4 | sort`
134+
#set -x
135+
136+
#old_apk_size="$(stat --printf=%s app/build/outputs/apk/release/app-release-unsigned.apk)"
137+
138+
#dex_count_delta="$((new_dex_count-old_dex_count))"
139+
140+
#apk_size_delta="$((new_apk_size-old_apk_size))"
141+
#
142+
#set +x
143+
#dex_method_diff=`diff -u <(echo "$all_old_methods") <(echo "$all_new_methods") || true`
144+
#set -x
145+
#
146+
#if [[ -n "$dex_method_diff" ]]
147+
#then
148+
# echo "Method diff: ${dex_method_diff}"
149+
#fi
150+
#
151+
## Update the statuses with the deltas
152+
#
153+
#set +x
154+
#gsutil cp gs://grpc-testing-secrets/github_credentials/oauth_token.txt ~/
155+
#
156+
#desc="New DEX reference count: $(printf "%'d" "$new_dex_count") (delta: $(printf "%'d" "$dex_count_delta"))"
157+
#echo "Setting status: $desc"
158+
#curl -f -s -X POST -H "Content-Type: application/json" \
159+
# -H "Authorization: token $(cat ~/oauth_token.txt | tr -d '\n')" \
160+
# -d '{"state": "success", "context": "android/dex_diff", "description": "'"${desc}"'"}' \
161+
# "https://api.github.com/repos/grpc/grpc-java/statuses/${KOKORO_GITHUB_PULL_REQUEST_COMMIT}"
162+
#
163+
#desc="New APK size in bytes: $(printf "%'d" "$new_apk_size") (delta: $(printf "%'d" "$apk_size_delta"))"
164+
#echo "Setting status: $desc"
165+
#curl -f -s -X POST -H "Content-Type: application/json" \
166+
# -H "Authorization: token $(cat ~/oauth_token.txt | tr -d '\n')" \
167+
# -d '{"state": "success", "context": "android/apk_diff", "description": "'"${desc}"'"}' \
168+
# "https://api.github.com/repos/grpc/grpc-java/statuses/${KOKORO_GITHUB_PULL_REQUEST_COMMIT}"

0 commit comments

Comments
 (0)