Skip to content

fix(packaging): ship libperry_ui_android.a to Windows installs so perry/ui android apps link (#4823)#5502

Merged
proggeramlug merged 1 commit into
mainfrom
fix/android-ui-lib-windows-packaging
Jun 21, 2026
Merged

fix(packaging): ship libperry_ui_android.a to Windows installs so perry/ui android apps link (#4823)#5502
proggeramlug merged 1 commit into
mainfrom
fix/android-ui-lib-windows-packaging

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes GitHub discussion #4823 — a Windows user with the NDK/SDK and Rust android targets installed could not build a perry/ui app for android. perry --target android cleared the runtime-only link step and then failed:

Error: perry/ui imported but libperry_ui_android.a not found.

Root cause is a packaging gap, not user error. Two distinct holes:

Changes (the two options approved on the discussion)

  1. release-packages.yml — the Windows build: leg now also cross-builds perry-ui-android (--profile dist; UI crates are already staticlib, so no -static wrapper). It's best-effort: a native non-zero exit is caught via an explicit $LASTEXITCODE guard (pwsh native failures aren't terminating errors) so a finicky aws-lc-rs cross-build can't sink the release; the mandatory runtime/stdlib builds are made explicitly fatal so they can't be masked. Staging of libperry_ui_android.a into the zip is Test-Path-guarded.
  2. stage-npm.sh — new stage_android_cross_libs helper stages all three android archives into the Windows npm package under bin/aarch64-linux-android/release/ (the layout library_search.rs probes, already inside the files allowlist), compressed to .a.zst like the rest. Each lib is sourced from the Windows build artifact first, falling back to the perry-cross-aarch64-linux-android bundle the npm-publish job already downloads — so the UI lib is backfilled from the authoritative ubuntu build even if the best-effort Windows cross-build was skipped. This also enables npm-installed android builds for the first time.

Also improves the link-time error message (build_and_run.rs) so binary-install users (no source tree) are pointed at dropping the prebuilt lib from perry-cross-aarch64-linux-android.tar.gz, not a cargo build they can't run.

Testing

  • stage_android_cross_libs validated end-to-end against a synthetic artifact layout (UI lib intentionally absent from the Windows artifact): runtime/stdlib resolve from the Windows artifact, UI lib backfills from the cross-bundle. Provenance confirmed byte-for-byte.
  • bash -n clean; conflict-free merge onto current main (v0.5.1197 → bump to v0.5.1198).

Note / open call

The zip path depends on the Windows-side perry-ui-android cross-build succeeding (aws-lc-rs cross-from-Windows is the risk). npm always gets the authoritative ubuntu lib via the fallback; the zip has no equivalent ubuntu fallback unless we add a post-merge job. Judged that over-engineering given the same leg already cross-builds runtime+stdlib fine — happy to add a zip-side fallback if preferred.

Summary by CodeRabbit

Release Notes v0.5.1198

  • Bug Fixes

    • Fixed Windows release artifacts to include Android static library (libperry_ui_android.a), enabling Android cross-compilation without additional manual setup.
    • Updated npm packages to properly include Android cross-compilation libraries for Windows installations.
  • Documentation

    • Improved error messaging to guide binary-install users to prebuilt Android libraries in release artifacts before attempting source builds.

…ry/ui android apps link (#4823)

A Windows user (discussion #4823) with the NDK/SDK and Rust android targets
installed could not build a `perry/ui` app for android: `perry --target
android` cleared the runtime-only link and then failed with "perry/ui imported
but libperry_ui_android.a not found". Root cause was a packaging gap, not user
error.

Two holes, two fixes (the options the maintainer approved):

1. release-packages.yml: the Windows build leg cross-built only the android
   runtime+stdlib (#872), never the UI backend. It now also cross-builds
   perry-ui-android (--profile dist; best-effort with an explicit $LASTEXITCODE
   guard so a finicky aws-lc-rs cross-build cannot sink the release) and stages
   libperry_ui_android.a into the zip.

2. stage-npm.sh dropped the aarch64-linux-android/release/ subdir entirely, so
   npm packages shipped no android libs at all. A new stage_android_cross_libs
   helper stages all three archives into the Windows npm package under
   bin/aarch64-linux-android/release/ (compressed to .a.zst), sourcing each from
   the Windows artifact first and falling back to the authoritative
   perry-cross-aarch64-linux-android bundle for the UI lib. Enables npm-installed
   android builds for the first time and backfills the UI lib if the Windows
   cross-build was skipped.

Also improves the link-time error message (build_and_run.rs) to point
binary-install users at the prebuilt cross bundle, not a cargo build they
cannot run.
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Version 0.5.1198 extends the Windows CI release workflow to best-effort cross-compile perry-ui-android for aarch64-linux-android using the NDK clang++ toolchain and conditionally stages libperry_ui_android.a into the release zip. A new stage_android_cross_libs helper in scripts/stage-npm.sh includes Android cross-libs in Windows npm packages with a fallback to an existing cross bundle tarball. The missing-library error message in build_and_run_link is updated to guide binary-install users to the prebuilt asset.

Changes

Android UI Library Windows Packaging Fix

Layer / File(s) Summary
Windows CI: NDK C++ wiring and best-effort perry-ui-android build
.github/workflows/release-packages.yml
Wires clang++ and CXX_aarch64_linux_android for the NDK toolchain; builds runtime and stdlib with $LASTEXITCODE checks; adds a best-effort perry-ui-android build that emits a warning and resets $LASTEXITCODE on failure; extends $androidLibs to conditionally include libperry_ui_android.a via Test-Path.
npm staging: stage_android_cross_libs helper and Windows invocation
scripts/stage-npm.sh
Adds stage_android_cross_libs to copy Android .a files into bin/aarch64-linux-android/release/ with host-artifact-first lookup and cross-bundle tarball fallback, optional zstd compression, and subdir cleanup when nothing is staged; invokes it for Windows packages.
Improved missing libperry_ui_android.a error guidance
crates/perry/src/commands/compile/link/build_and_run.rs
Updates the error message for a missing Android UI library to describe both the prebuilt-placement option for binary-install users and the existing source-build Cargo command.
Version bump and changelog for v0.5.1198
Cargo.toml, CLAUDE.md, CHANGELOG.md
Bumps workspace version to 0.5.1198 and adds a changelog entry describing the Windows packaging and npm staging fixes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PerryTS/perry#5145: Both PRs modify scripts/stage-npm.sh to zstd-compress shipped static .a archives into .a.zst for npm packaging; the new stage_android_cross_libs function follows the same compression convention introduced there.
  • PerryTS/perry#5406: Both PRs touch build_and_run_link in crates/perry/src/commands/compile/link/build_and_run.rs; the retrieved PR restructures that function while this PR adjusts its Android missing-library error message.

Poem

🐇 Hop hop, the Android lib was lost,
No libperry_ui_android.a — what a cost!
Now Windows builds it, best-effort style,
The npm helper zips it with a smile.
A fallback tarball waits just in case,
Binary users guided to the right place! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the problem, root cause, implemented changes, and testing; however, it violates the stated contribution guidelines by including version bumps and changelog updates that the template explicitly prohibits from contributor PRs. Remove version bumps from Cargo.toml and CLAUDE.md, and the CHANGELOG.md entry—these should be handled by maintainers at merge time per the template instructions.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: shipping libperry_ui_android.a to Windows installs to enable perry/ui Android app linking.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/android-ui-lib-windows-packaging

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
.github/workflows/release-packages.yml (1)

422-431: 💤 Low value

Consider logging a warning if clang++ is not found.

Unlike the C linker ($linker), the C++ linker ($linkerxx) is probed but not validated with an error exit. This is acceptable since it's only needed for the best-effort UI build, but emitting a Write-Warning when $linkerxx is missing would aid debugging when the UI build fails due to missing C++ toolchain.

💡 Optional diagnostic improvement
           $linkerxx = Join-Path $toolchain "aarch64-linux-android$($env:ANDROID_API_LEVEL)-clang++.exe"
           }
+          if (-not (Test-Path $linkerxx)) {
+            Write-Warning "Android NDK clang++ not found at $linkerxx — perry-ui-android build may fail."
+          }
           $env:CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER = $linker
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-packages.yml around lines 422 - 431, The C++
linker path variable $linkerxx is probed by checking for both the .cmd and .exe
versions but unlike the C linker, there is no validation or warning when neither
file is found. Add a Write-Warning statement after the $linkerxx assignment
block that checks if the resolved path does not exist and logs a warning message
indicating that the C++ linker clang++ could not be found, which will help with
debugging if the UI build subsequently fails due to missing C++ toolchain
components.
CHANGELOG.md (1)

7-10: 💤 Low value

Add language specifier to fenced code block.

Line 7 opens a code fence without a language identifier. Per markdownlint (MD040), add a language specifier (e.g., bash, sh, or text) to make the intent clear and improve syntax highlighting.

✨ Proposed fix
-```
+```sh
 Error: perry/ui imported but libperry_ui_android.a not found. Build with:
 RUSTC_BOOTSTRAP=1 RUSTFLAGS="-Z tls-model=global-dynamic" cargo build --release -p perry-ui-android --target aarch64-linux-android
-```
+```
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` around lines 7 - 10, The fenced code block in CHANGELOG.md
starting at line 7 is missing a language specifier on the opening fence. Add the
language identifier `sh` immediately after the opening triple backticks (```sh)
to comply with markdownlint rule MD040 and enable proper syntax highlighting for
the shell command block.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/release-packages.yml:
- Around line 422-431: The C++ linker path variable $linkerxx is probed by
checking for both the .cmd and .exe versions but unlike the C linker, there is
no validation or warning when neither file is found. Add a Write-Warning
statement after the $linkerxx assignment block that checks if the resolved path
does not exist and logs a warning message indicating that the C++ linker clang++
could not be found, which will help with debugging if the UI build subsequently
fails due to missing C++ toolchain components.

In `@CHANGELOG.md`:
- Around line 7-10: The fenced code block in CHANGELOG.md starting at line 7 is
missing a language specifier on the opening fence. Add the language identifier
`sh` immediately after the opening triple backticks (```sh) to comply with
markdownlint rule MD040 and enable proper syntax highlighting for the shell
command block.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5aab06c4-9a9e-4c46-b9a0-99daed157fea

📥 Commits

Reviewing files that changed from the base of the PR and between 12e976f and ad59427.

📒 Files selected for processing (6)
  • .github/workflows/release-packages.yml
  • CHANGELOG.md
  • CLAUDE.md
  • Cargo.toml
  • crates/perry/src/commands/compile/link/build_and_run.rs
  • scripts/stage-npm.sh

@proggeramlug proggeramlug merged commit 3729b46 into main Jun 21, 2026
15 checks passed
@proggeramlug proggeramlug deleted the fix/android-ui-lib-windows-packaging branch June 21, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant