Skip to content

Commit fc6422f

Browse files
committed
Publish an AAR for Android developers.
This extends the existing Android workflow to collect the validation layer libraries into an AAR that is published to the repository's GitHub Packages Repository. This way, Android Gradle users can point their build at this repository and add a new dependency to their build.gradle.kts file rather than needing to download and manage the artifacts manually. Fixes #8167
1 parent 31118fe commit fc6422f

File tree

3 files changed

+191
-21
lines changed

3 files changed

+191
-21
lines changed

.github/workflows/sdk_android_build.yml

Lines changed: 103 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ name: SDK Android Build
1919
# artifacts to the release when a Vulkan SDK tag is pushed. The
2020
# Vulkan SDK does not include binaries for Android, so we publish
2121
# them here to provide Android binaries built from the same source
22-
# used to build the Vulkan SDK.
22+
# used to build the Vulkan SDK. The artifacts will also be bundled into an AAR
23+
# (the library counterpart the APK application format) and uploaded to GitHub
24+
# Packages so app developers can include the validation layers in their
25+
# application the same way they would any Java dependencies.
2326
#
2427
# The tag needs to be pushed by name, as `git push --tags` to push all
2528
# tags does not appear to trigger the action.
@@ -48,7 +51,23 @@ on:
4851
tags:
4952
- vulkan-sdk-*
5053

54+
env:
55+
MIN_SDK_VERSION: 26
56+
ARTIFACT_ID: vulkan-validation-layers
57+
5158
jobs:
59+
sdk-version:
60+
name: Get SDK version
61+
runs-on: ubuntu-22.04
62+
outputs:
63+
sdk_version: ${{ steps.get_sdk_version.outputs.sdk_version}}
64+
steps:
65+
- name: Get sdk version string
66+
id: get_sdk_version
67+
run: |
68+
sdk_version=`echo "${{ github.ref }}" | cut -d "-" -f 3`
69+
echo "sdk_version=$sdk_version" >> $GITHUB_OUTPUT
70+
5271
android:
5372
name: Android SDK Release
5473
runs-on: ubuntu-22.04
@@ -63,36 +82,105 @@ jobs:
6382
with:
6483
python-version: '3.10'
6584
- name: CMake Build
66-
run: python scripts/android.py --config Release --app-abi ${{ matrix.abi }} --app-stl c++_static
85+
run: python scripts/android.py --config Release --app-abi ${{ matrix.abi }} --app-stl c++_static --min-sdk-version $MIN_SDK_VERSION
6786
- name: Upload artifacts
6887
uses: actions/upload-artifact@v4
6988
with:
7089
name: vvl-android-${{ matrix.abi }}
7190
path: ./build-android/libs/lib/
7291

92+
aar:
93+
name: Create AAR
94+
runs-on: ubuntu-22.04
95+
needs: [android, sdk-version]
96+
steps:
97+
- name: Clone repository
98+
uses: actions/checkout@v4
99+
- uses: actions/setup-python@v5
100+
with:
101+
python-version: '3.10'
102+
- name: Download artifacts
103+
uses: actions/download-artifact@v4
104+
with:
105+
path: ./libs
106+
merge-multiple: true
107+
pattern: vvl-android-*
108+
- name: Assemble AAR
109+
# GROUP_ID must be configured as a repoistory variable in Settings ->
110+
# Actions -> Variables.
111+
run: |
112+
python scripts/aar.py \
113+
--group-id ${{ vars.GROUP_ID }} \
114+
--artifact-id ${{ env.ARTIFACT_ID }} \
115+
--min-sdk-version $MIN_SDK_VERSION \
116+
-o vulkan-validation-layers-${{ needs.sdk-version.outputs.sdk_version }}.aar \
117+
libs
118+
- name: Upload AAR
119+
uses: actions/upload-artifact@v4
120+
with:
121+
name: vulkan-validation-layers-aar
122+
path: vulkan-validation-layers-${{ needs.sdk-version.outputs.sdk_version }}.aar
123+
if-no-files-found: error
124+
125+
maven:
126+
name: Push AAR to GitHub Packages
127+
runs-on: ubuntu-22.04
128+
needs: [aar, sdk-version]
129+
steps:
130+
- name: Set up Java
131+
uses: actions/setup-java@v4
132+
with:
133+
# Neither are really important. We need the mvn tool, but we aren't
134+
# going to use it to build anything.
135+
distribution: "temurin"
136+
java-version: "21"
137+
- name: Download artifacts
138+
uses: actions/download-artifact@v4
139+
with:
140+
path: aar
141+
name: vulkan-validation-layers-aar
142+
- name: Publish
143+
# Useful docs for this section:
144+
# https://maven.apache.org/guides/mini/guide-3rd-party-jars-remote.html
145+
# https://docs.github.com/en/actions/publishing-packages/publishing-java-packages-with-maven
146+
run: |
147+
mvn --batch-mode deploy:deploy-file \
148+
-DgroupId=${{ vars.GROUP_ID }} \
149+
-DartifactId=$ARTIFACT_ID \
150+
-Dversion=${{ needs.sdk-version.outputs.sdk_version }} \
151+
-Dpackaging=aar \
152+
-DrepositoryId=github \
153+
-Durl=https://maven.pkg.github.com/${{ github.repository }} \
154+
-Dfile=aar/vulkan-validation-layers-${{ needs.sdk-version.outputs.sdk_version }}.aar
155+
env:
156+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
157+
73158
release:
74159
name: Create Release for Tag
75160
permissions: write-all
76161
runs-on: ubuntu-22.04
77-
needs: android
162+
needs: [android, sdk-version]
78163
steps:
79-
- name: Get sdk version string
80-
id: get_sdk_version
81-
run: |
82-
sdk_version=`echo "${{ github.ref }}" | cut -d "-" -f 3`
83-
echo "sdk_version=$sdk_version" >> $GITHUB_OUTPUT
84164
- name: Create release
85165
id: create_release
86166
uses: actions/create-release@v1
87167
env:
88168
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89169
with:
90170
tag_name: ${{ github.ref }}
91-
release_name: Android binaries for ${{ steps.get_sdk_version.outputs.sdk_version }} SDK release
171+
release_name: Android binaries for ${{ needs.sdk-version.outputs.sdk_version }} SDK release
92172
body: |
93173
These Android Validation Layer binaries were built with ndk version 25.2.9519653
94174
95-
The validation binaries can only be used with a device that supports Android API version 26 or higher.
175+
The validation binaries can only be used with a device that supports Android API version ${{ env.MIN_SDK_VERSION }} or higher.
176+
177+
If you're using Android Gradle to build your app, it will be easier
178+
to use the validation layers direcetly from the GitHub Package
179+
Repository: ${{ github.repositoryUrl }}/packages/. See
180+
https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#using-a-published-package
181+
for instructions on using packages from this repository. To include
182+
the validation layers only in your debug APK (recommended), use
183+
`debugImplementation` rather than `implementation` as the docs say.
96184
draft: false
97185
prerelease: false
98186
- name: Get release URL
@@ -107,7 +195,7 @@ jobs:
107195
publish:
108196
runs-on: ubuntu-22.04
109197
permissions: write-all
110-
needs: release
198+
needs: [release, sdk-version]
111199
strategy:
112200
fail-fast: false
113201
matrix:
@@ -123,20 +211,15 @@ jobs:
123211
suffix: "zip"
124212
type: "application/zip"
125213
steps:
126-
- name: Get sdk version string
127-
id: get_sdk_version
128-
run: |
129-
sdk_version=`echo "${{ github.ref }}" | cut -d "-" -f 3`
130-
echo "sdk_version=$sdk_version" >> $GITHUB_OUTPUT
131214
- name: Download artifacts
132215
uses: actions/download-artifact@v4
133216
with:
134-
path: ./android-binaries-${{ steps.get_sdk_version.outputs.sdk_version }}
217+
path: ./android-binaries-${{ needs.sdk-version.outputs.sdk_version }}
135218
merge-multiple: true
136219
pattern: ${{ matrix.config.artifact }}-*
137220
- name: Make release artifacts
138221
run: |
139-
${{ matrix.config.command }} android-binaries-${{ steps.get_sdk_version.outputs.sdk_version }}.${{ matrix.config.suffix }} android-binaries-${{ steps.get_sdk_version.outputs.sdk_version }}
222+
${{ matrix.config.command }} android-binaries-${{ needs.sdk-version.outputs.sdk_version }}.${{ matrix.config.suffix }} android-binaries-${{ needs.sdk-version.outputs.sdk_version }}
140223
- name: Download release URL
141224
uses: actions/download-artifact@v4
142225
with:
@@ -153,6 +236,6 @@ jobs:
153236
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154237
with:
155238
upload_url: ${{ steps.set_upload_url.outputs.upload_url }}
156-
asset_name: android-binaries-${{ steps.get_sdk_version.outputs.sdk_version }}.${{ matrix.config.suffix }}
157-
asset_path: ./android-binaries-${{ steps.get_sdk_version.outputs.sdk_version }}.${{ matrix.config.suffix }}
239+
asset_name: android-binaries-${{ needs.sdk-version.outputs.sdk_version }}.${{ matrix.config.suffix }}
240+
asset_path: ./android-binaries-${{ needs.sdk-version.outputs.sdk_version }}.${{ matrix.config.suffix }}
158241
asset_content_type: ${{ matrix.config.type }}

scripts/aar.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2024 LunarG, Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
from pathlib import Path
18+
from zipfile import ZipFile
19+
import argparse
20+
import textwrap
21+
22+
23+
def generate_aar(
24+
output_path: Path,
25+
library_dir: Path,
26+
group_id: str,
27+
artifact_id: str,
28+
min_sdk_version: int,
29+
) -> None:
30+
"""Creates an AAR from the CMake binaries."""
31+
with ZipFile(output_path, mode="w") as zip_file:
32+
zip_file.writestr(
33+
"AndroidManifest.xml",
34+
textwrap.dedent(
35+
f"""\
36+
<?xml version="1.0" encoding="utf-8"?>
37+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
38+
package="{group_id}.{artifact_id}" >
39+
<uses-sdk android:minSdkVersion="{min_sdk_version}" />
40+
</manifest>
41+
"""
42+
),
43+
)
44+
45+
for abi_dir in library_dir.iterdir():
46+
libs = list(abi_dir.glob("*.so"))
47+
if not libs:
48+
raise RuntimeError(f"No libraries found matching {abi_dir}/*.so")
49+
for lib in libs:
50+
zip_file.write(lib, arcname=f"jni/{abi_dir.name}/{lib.name}")
51+
52+
53+
def main() -> None:
54+
parser = argparse.ArgumentParser()
55+
parser.add_argument(
56+
"--group-id", help="The group ID of the AAR that will be published"
57+
)
58+
parser.add_argument(
59+
"--artifact-id", help="The artifact ID of the AAR that will be published"
60+
)
61+
parser.add_argument(
62+
"--min-sdk-version",
63+
type=int,
64+
default=26,
65+
help="The minSdkVersion of the built artifacts",
66+
)
67+
parser.add_argument("-o", "--output", type=Path, help="Output file name")
68+
parser.add_argument(
69+
"library_directory",
70+
type=Path,
71+
help="Directory containing the built libraries, separated into ABI-named subdirectories",
72+
)
73+
args = parser.parse_args()
74+
75+
generate_aar(
76+
args.output,
77+
args.library_directory,
78+
args.group_id,
79+
args.artifact_id,
80+
args.min_sdk_version,
81+
)
82+
83+
84+
if __name__ == "__main__":
85+
main()

scripts/android.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def main():
8383
parser = argparse.ArgumentParser()
8484
parser.add_argument('--config', type=str, choices=configs, default=configs[0])
8585
parser.add_argument('--app-abi', dest='android_abi', type=str, default="arm64-v8a")
86+
parser.add_argument('--min-sdk-version', type=int, default=26, help='The minSdkVersion of the built artifacts')
8687
parser.add_argument('--app-stl', dest='android_stl', type=str, choices=["c++_static", "c++_shared"], default="c++_static")
8788
parser.add_argument('--apk', action='store_true', help='Generate an APK as a post build step.')
8889
parser.add_argument('--clean', action='store_true', help='Cleans CMake build artifacts')
@@ -91,6 +92,7 @@ def main():
9192
cmake_config = args.config
9293
android_abis = args.android_abi.split(" ")
9394
android_stl = args.android_stl
95+
min_sdk_version = args.min_sdk_version
9496
create_apk = args.apk
9597
clean = args.clean
9698

@@ -159,7 +161,7 @@ def main():
159161
cmake_cmd += f' -D BUILD_TESTS={create_apk}'
160162
cmake_cmd += f' -D CMAKE_ANDROID_STL_TYPE={android_stl}'
161163

162-
cmake_cmd += ' -D ANDROID_PLATFORM=26'
164+
cmake_cmd += f' -D ANDROID_PLATFORM={min_sdk_version}'
163165
cmake_cmd += ' -D ANDROID_USE_LEGACY_TOOLCHAIN_FILE=NO'
164166

165167
common_ci.RunShellCmd(cmake_cmd)

0 commit comments

Comments
 (0)