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
66 changes: 63 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,70 @@ jobs:
path: artifacts/packages/*
retention-days: 14

android:
name: Build Android arm64
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6

# A .NET 9 SDK is required even though the project targets net8.0: the source generator needs
# Roslyn >= 4.10.
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 9.0.x

- name: Setup JDK
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '17'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: '8.7'

# The NDK version has to match ndkVersion in Brovan/Android/app/brovan/build.gradle; the runner image
# preinstalls a newer one that build-apk.sh would otherwise pick.
- name: Install the Android NDK and CMake
run: |
SDKMANAGER="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager"
yes | "$SDKMANAGER" --licenses > /dev/null 2>&1 || true
"$SDKMANAGER" "ndk;26.3.11579264" "cmake;3.22.1" "platforms;android-34" "build-tools;34.0.0"
echo "ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk/26.3.11579264" >> "$GITHUB_ENV"

- name: Cache OpenSSL
uses: actions/cache@v4
with:
path: ~/brovan-toolchain/openssl-3.5.4
key: brovan-openssl-3.5.4-android-arm64

- name: Build OpenSSL for android-arm64
run: bash Brovan/Android/build-openssl.sh

- name: Cache Unicorn
uses: actions/cache@v4
with:
path: Brovan/.cache/unicorn
key: brovan-unicorn-android-arm64-${{ hashFiles('Brovan/Brovan.Unicorn.targets') }}

- name: Build APK
run: bash Brovan/Android/build-apk.sh

- name: Upload CI Artifact
uses: actions/upload-artifact@v6
with:
name: Brovan Android arm64
path: artifacts/android/*.apk
retention-days: 14

release:
name: Publish GitHub Release
if: startsWith(github.ref, 'refs/tags/')
needs: build
needs: [ build, android ]
runs-on: ubuntu-latest
permissions:
contents: write
Expand All @@ -80,6 +140,6 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${{ github.ref_name }}" release-artifacts/**/*
--title "${{ github.ref_name }}"
gh release create "${{ github.ref_name }}" release-artifacts/**/* \
--title "${{ github.ref_name }}" \
--generate-notes
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ nunit-*.xml
/Brovan.Graphics/brovvulk-icd/generated
/VirtualFS
/Brovan/Properties
/Brovan/Android/app/.gradle/
/Brovan/Android/app/**/build/
/Brovan/Android/app/local.properties
/Brovan/Android/app/brovan/src/main/jniLibs/
/*.apk
34 changes: 34 additions & 0 deletions Brovan.Android/Brovan.Android.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<!--
Solution entry point for the APK. Nothing is compiled here: Brovan/Android/build-apk.sh publishes the
emulator for linux-bionic-arm64, cross-builds Unicorn and runs gradle. The script only works on a Linux
host (NativeAOT does not cross-compile from Windows to linux-bionic), so a Windows build is a no-op.
-->

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
<BuildAndroidApk Condition="'$(BuildAndroidApk)' == '' and $([MSBuild]::IsOSPlatform('Windows'))">false</BuildAndroidApk>
<BuildAndroidApk Condition="'$(BuildAndroidApk)' == ''">true</BuildAndroidApk>
<AndroidBuildScript>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory), '..', 'Brovan', 'Android', 'build-apk.sh'))</AndroidBuildScript>
<AndroidApkOutput>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory), '..', 'artifacts', 'android', 'brovan-arm64-v8a.apk'))</AndroidApkOutput>
</PropertyGroup>

<Target Name="ReportSkippedAndroidApk" AfterTargets="Build" Condition="'$(BuildAndroidApk)' != 'true'">
<Message Importance="normal" Text="[Brovan.Android] APK skipped on this host; build on Linux or pass -p:BuildAndroidApk=true." />
</Target>

<Target Name="BuildAndroidApk" AfterTargets="Build" Condition="'$(BuildAndroidApk)' == 'true'">
<Message Importance="high" Text="[Brovan.Android] Building the APK ($(Configuration))..." />
<Exec Command="bash &quot;$(AndroidBuildScript)&quot;" IgnoreExitCode="true"
EnvironmentVariables="CONFIG=$(Configuration);BROVAN_APK_OUTPUT=$(AndroidApkOutput)">
<Output TaskParameter="ExitCode" PropertyName="_AndroidApkExitCode" />
</Exec>
<!-- 3 is build-apk.sh's "no Android toolchain here"; a desktop Linux checkout should still build. -->
<Warning Condition="'$(_AndroidApkExitCode)' == '3'" Text="[Brovan.Android] APK skipped: no Android toolchain on this host (see Brovan/Android/README.md)." />
<Error Condition="'$(_AndroidApkExitCode)' != '0' and '$(_AndroidApkExitCode)' != '3'" Text="[Brovan.Android] build-apk.sh failed with exit code $(_AndroidApkExitCode)." />
<Message Condition="'$(_AndroidApkExitCode)' == '0'" Importance="high" Text="[Brovan.Android] APK -> $(AndroidApkOutput)" />
</Target>

</Project>
15 changes: 12 additions & 3 deletions Brovan.Generators/VulkanForwardGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ private static string EmitHostCase(Model m, Command c, int id)
" uint hasCi = r.ReadU32();\n" +
" System.IntPtr ci = System.IntPtr.Zero;\n" +
" if (hasCi != 0) ci = BrovVulkGenStruct.Rebuild(" + StructId["VkInstanceCreateInfo"] + ", r, st);\n" +
" if (Brovan.GeneralHelper.IsLinux && ci != System.IntPtr.Zero)\n" +
" if ((Brovan.GeneralHelper.IsLinux || Brovan.Android.AndroidHost.IsActive) && ci != System.IntPtr.Zero)\n" +
" {\n" +
" System.IntPtr extPtr = *(System.IntPtr*)(ci + 56);\n" +
" uint extCount = *(uint*)(ci + 48);\n" +
Expand All @@ -1100,7 +1100,7 @@ private static string EmitHostCase(Model m, Command c, int id)
" }\n" +
" if (sawWin32)\n" +
" {\n" +
" System.IntPtr xcbName = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(\"VK_KHR_xcb_surface\");\n" +
" System.IntPtr xcbName = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(Brovan.Android.AndroidHost.IsActive ? \"VK_KHR_android_surface\" : \"VK_KHR_xcb_surface\");\n" +
" System.Runtime.InteropServices.Marshal.WriteIntPtr(newArr, (int)(newCount * 8), xcbName);\n" +
" newCount++;\n" +
" *(uint*)(ci + 48) = newCount;\n" +
Expand All @@ -1118,7 +1118,16 @@ private static string EmitHostCase(Model m, Command c, int id)
" System.IntPtr vi = st.Lookup(r.ReadU32(), \"VkInstance\");\n" +
" System.IntPtr surf = System.IntPtr.Zero;\n" +
" int rr;\n" +
" if (Brovan.GeneralHelper.IsLinux)\n" +
" if (Brovan.Android.AndroidHost.IsActive)\n" +
" {\n" +
" System.IntPtr awin = inst.WinHelper.EnsureHostWindowHandle();\n" +
" byte* ci = stackalloc byte[32];\n" +
" for (int z = 0; z < 32; z++) ci[z] = 0;\n" +
" *(int*)(ci + 0) = " + "1000008000" + ";\n" +
" *(void**)(ci + 24) = (void*)awin;\n" +
" rr = (int)Brovan.Android.AndroidVulkanWsi.vkCreateAndroidSurfaceKHR(vi, (System.IntPtr)ci, System.IntPtr.Zero, (System.IntPtr)(&surf));\n" +
" }\n" +
" else if (Brovan.GeneralHelper.IsLinux)\n" +
" {\n" +
" System.IntPtr xdpy; System.IntPtr xwin;\n" +
" inst.WinHelper.EnsureHostXlibSurfaceHandles(out xdpy, out xwin);\n" +
Expand Down
Loading
Loading