purego: support structs on Android and iOS#467
Merged
hajimehoshi merged 1 commit intoJun 23, 2026
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends PureGo’s struct-by-value ABI support to Android and iOS (amd64/arm64), aligning the runtime GOOS gating with ABIs already supported on macOS/Linux/Windows, and adds CI coverage to exercise the Android paths.
Changes:
- Allow struct arguments/returns on
GOOS=androidandGOOS=iosby wideningensureStructSupported, routing iOS through a newisDarwin()helper, and treating Android like Linux in callback struct decoding. - Update callback stack-reading/struct marshalling logic to apply the Darwin ARM64 packing rules on iOS as well.
- Add an Android emulator workflow job and a test harness path for loading prebuilt shared libraries via
PUREGO_TEST_PREBUILT_LIBDIR; teach tests to locate Android libc.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
syscall_unix.go |
Uses isDarwin() to apply Darwin ARM64 stack unpacking on iOS as well as macOS. |
struct_arm64.go |
Generalizes Darwin-vs-Linux ARM64 struct handling to include iOS/Android; expands callback struct support switches. |
struct_amd64.go |
Expands callback struct support switches to include iOS/Android on amd64. |
README.md |
Updates platform notes to reflect struct-by-value support on Android/iOS amd64/arm64. |
func.go |
Opens struct support gate for android/ios and introduces isDarwin() helper used across ABI logic. |
func_test.go |
Adds Android/iOS system library resolution and supports prebuilt test shared libraries via env var. |
.github/workflows/test.yml |
Adds an Android emulator CI job (amd64/arm64) that runs the test binary with prebuilt libraries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d6ee7a4 to
9fae168
Compare
Member
Author
|
@TotallyGamerJet Please take a look, thanks |
Enable passing and returning C structs by value on Android and iOS for amd64 and arm64, in both RegisterFunc calls and NewCallback callbacks. The struct-marshalling code already compiled into these builds and was only gated off by runtime.GOOS string checks. iOS shares the Apple ABI with macOS and Android shares the standard ABI with Linux, so route GOOS=ios through the Darwin path via a new isDarwin helper and treat GOOS=android like Linux. Open the ensureStructSupported gate, add ios and android to the getCallbackStruct callback switches, and extend the Darwin ARM64 stack-argument reads in the callback path to iOS. Add an Android emulator CI job (amd64 and arm64) that runs the test suite. Because the emulator has no C toolchain, the test libraries are cross-compiled on the host with the NDK and loaded via the new PUREGO_TEST_PREBUILT_LIBDIR instead of being compiled at run time. Closes ebitengine#466 Co-Authored-By: Claude Opus 4.8 <[email protected]>
9fae168 to
f49be2a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What issue is this addressing?
Closes #466
What type of issue is this addressing?
feature
What this PR does | solves
Enables passing and returning C structs by value on Android and iOS for
amd64 and arm64, in both
RegisterFunc/RegisterLibFunccalls andNewCallbackcallbacks — matching the support already available on macOS, Linux, and Windows
(#236, #237).
Why it works
The struct-marshalling code was already compiled into the iOS/Android builds and
only gated off by
runtime.GOOSstring checks. Their ABIs are identical toplatforms that already work:
So this routes
GOOS=iosthrough the Darwin path via a newisDarwinhelper,treats
GOOS=androidlike Linux, opens theensureStructSupportedgate toios/android, adds them to the
getCallbackStructcallback switches, and extendsthe Darwin ARM64 stack-argument reads in the callback path to iOS.
Tests / CI
Adds an Android emulator CI job (amd64 and arm64) that runs the test suite.
Because the emulator has no C toolchain, the test libraries are cross-compiled on
the host with the NDK and loaded via a new
PUREGO_TEST_PREBUILT_LIBDIRenv varinstead of being compiled at run time.
getSystemLibraryalso learns Android'slibc (and iOS, for a future job).
Reviewer notes
environment), so it may need a CI iteration to settle image/arch specifics —
notably the arm64-v8a image under full emulation on the x86_64 runner, and
dlopen("libc.so")for the adb-shell user. The harness change itself isverified on the host: the full suite passes through
PUREGO_TEST_PREBUILT_LIBDIR.since the iOS arm64 ABI matches macOS arm64, which the macOS runner already
exercises).
Authored by Claude (Claude Code) on behalf of @hajimehoshi.