Impact
On Windows, the project cannot be built or tested at all. Two independent
task failures block it:
./gradlew test — fails. CONTRIBUTING Step 3 makes this a strict requirement
for Pull Request approval.
- Any APK build (
assembleDebug, installDebug, bundleRelease, …) — fails,
because :mirrorserver:dex is wired into merge*Assets and package*.
So a Windows contributor currently cannot satisfy the mandatory verification
steps in CONTRIBUTING, and cannot produce a build to test on hardware. I'm
flagging this ahead of my localization proposal (#103) because it affects
everyone, not just me.
There is no CI in the repository (.github/ holds only FUNDING.yml and
copilot-instructions.md), so nothing surfaces this automatically — it is
invisible unless someone actually develops on Windows.
Blocker 1 — :mirrorserver:dex looks for d8, Windows ships d8.bat
mirrorserver/build.gradle.kts:
val d8 = newest.resolve("d8")
check(d8.exists()) { "d8 not found at $d8" }
Android SDK build-tools on Windows contains d8.bat only; there is no
extensionless d8. The build fails with:
Execution failed for task ':mirrorserver:dex'.
> d8 not found at C:\Users\<user>\AppData\Local\Android\Sdk\build-tools\36.0.0\d8
The comment a few lines below ("the d8 shell wrapper (macOS)") suggests macOS
was considered here but Windows wasn't.
Suggested fix
val isWindows = System.getProperty("os.name").lowercase().contains("win")
val d8Name = if (isWindows) "d8.bat" else "d8"
val d8 = newest.resolve(d8Name)
check(d8.exists()) { "d8 not found at $d8" }
I've been running this on my own branch for a while and it works. Happy to open
a PR.
Related nit, same block
val newest = buildToolsDir.listFiles()?.filter { it.isDirectory }?.maxByOrNull { it.name }
maxByOrNull { it.name } compares directory names as strings, so a future
single-digit major version would sort above a two-digit one ("9.0.0" >
"36.0.0"). Not currently reachable, but comparing parsed version components
would be safer. Say the word and I'll include it in the same PR, or leave it
out to keep the fix minimal.
Blocker 2 — :app:nativeCTest cannot start on Windows
app/build.gradle.kts:
val nativeCTest = tasks.register<Exec>("nativeCTest") {
commandLine("./run_native_tests.sh")
}
// …
tasks.matching { it.name.contains("UnitTest") || it.name == "test" }.configureEach {
dependsOn(nativeCTest)
}
Execution failed for task ':app:nativeCTest'.
> A problem occurred starting process 'command './run_native_tests.sh''
Windows cannot exec a .sh file as a process directly. Even under Git Bash the
script additionally requires clang, which is not part of a standard Android
Studio install on Windows.
Because nativeCTest is a dependency of every test / *UnitTest task, fixing
Blocker 1 alone does not make ./gradlew test runnable — both need addressing.
Possible directions
I don't want to presume the design here, so a few options rather than a patch:
- Skip the task when no POSIX shell or
clang is available
(onlyIf { … }), so the JVM/Robolectric suites still run and native
coverage stays a Linux/macOS concern.
- Invoke the script through an explicit shell and gate it on
clang being
resolvable.
- Keep it mandatory, but document in CONTRIBUTING that Windows contributors
must run verification under WSL.
Option 3 is legitimate — but it should be stated, because right now CONTRIBUTING
requires a step that silently cannot succeed on Windows.
Reproduction
Windows 11, JDK 21, Android SDK build-tools 36.0.0, Gradle 9.3.1 (wrapper),
clean checkout of main at 92e1081 with only sdk.dir set in
local.properties:
./gradlew test
-> :app:nativeCTest FAILED (Blocker 2)
./gradlew test -x :app:nativeCTest
-> :mirrorserver:dex FAILED (Blocker 1)
./gradlew test -x :app:nativeCTest -x :mirrorserver:dex
-> runs; :core 170 passed, :gamefocus 24 passed, :domain 293 tests
For reference, the remaining :domain failures in that last run are 23
Robolectric cases (InstalledAppsManagerTest, RomManagerTest,
IpcParsersTest) failing with UnsatisfiedLinkError: no conscrypt_jni in java.library.path. That looks like a separate local-environment matter and I
have not investigated it further — mentioning it only so the numbers above are
not mistaken for a clean run.
I'm glad to send a PR for Blocker 1 immediately, and to follow your preferred
direction on Blocker 2.
Impact
On Windows, the project cannot be built or tested at all. Two independent
task failures block it:
./gradlew test— fails. CONTRIBUTING Step 3 makes this a strict requirementfor Pull Request approval.
assembleDebug,installDebug,bundleRelease, …) — fails,because
:mirrorserver:dexis wired intomerge*Assetsandpackage*.So a Windows contributor currently cannot satisfy the mandatory verification
steps in CONTRIBUTING, and cannot produce a build to test on hardware. I'm
flagging this ahead of my localization proposal (#103) because it affects
everyone, not just me.
There is no CI in the repository (
.github/holds onlyFUNDING.ymlandcopilot-instructions.md), so nothing surfaces this automatically — it isinvisible unless someone actually develops on Windows.
Blocker 1 —
:mirrorserver:dexlooks ford8, Windows shipsd8.batmirrorserver/build.gradle.kts:Android SDK build-tools on Windows contains
d8.batonly; there is noextensionless
d8. The build fails with:The comment a few lines below ("the d8 shell wrapper (macOS)") suggests macOS
was considered here but Windows wasn't.
Suggested fix
I've been running this on my own branch for a while and it works. Happy to open
a PR.
Related nit, same block
maxByOrNull { it.name }compares directory names as strings, so a futuresingle-digit major version would sort above a two-digit one (
"9.0.0">"36.0.0"). Not currently reachable, but comparing parsed version componentswould be safer. Say the word and I'll include it in the same PR, or leave it
out to keep the fix minimal.
Blocker 2 —
:app:nativeCTestcannot start on Windowsapp/build.gradle.kts:Windows cannot exec a
.shfile as a process directly. Even under Git Bash thescript additionally requires
clang, which is not part of a standard AndroidStudio install on Windows.
Because
nativeCTestis a dependency of everytest/*UnitTesttask, fixingBlocker 1 alone does not make
./gradlew testrunnable — both need addressing.Possible directions
I don't want to presume the design here, so a few options rather than a patch:
clangis available(
onlyIf { … }), so the JVM/Robolectric suites still run and nativecoverage stays a Linux/macOS concern.
clangbeingresolvable.
must run verification under WSL.
Option 3 is legitimate — but it should be stated, because right now CONTRIBUTING
requires a step that silently cannot succeed on Windows.
Reproduction
Windows 11, JDK 21, Android SDK build-tools 36.0.0, Gradle 9.3.1 (wrapper),
clean checkout of
mainat 92e1081 with onlysdk.dirset inlocal.properties:For reference, the remaining
:domainfailures in that last run are 23Robolectric cases (
InstalledAppsManagerTest,RomManagerTest,IpcParsersTest) failing withUnsatisfiedLinkError: no conscrypt_jni in java.library.path. That looks like a separate local-environment matter and Ihave not investigated it further — mentioning it only so the numbers above are
not mistaken for a clean run.
I'm glad to send a PR for Blocker 1 immediately, and to follow your preferred
direction on Blocker 2.