Description
Cross-compiling a real v3 app (backend Go service + vanilla HTML/JS frontend, no mobile-specific code beyond what the templates generate) for GOOS=ios and GOOS=android fails outright on v3.0.0-alpha.98 — before even reaching app-specific code. Filed with a PR that fixes all five.
Environment
- Wails CLI: v3.0.0-alpha.98
- Go: go1.26.3 darwin/arm64
- macOS 26.6, Xcode 26.6
- Android NDK 27.1.12297006,
compileSdk 34, minSdk 21
Bugs found (all reproduced by direct go build, not just via wails3 task)
1. wails3 ios overlay:gen can't run outside the Wails monorepo checkout
internal/commands/ios_overlay_gen.go's repoRoot() walks up from the current working directory looking for a folder named v3/internal/commands. That only exists inside a checkout of wailsapp/wails itself — any normal downstream project (including the one generated by wails3 init -t vanilla) has no such path, so wails3 ios overlay:gen -out build/ios/xcode/overlay.json -config build/config.yml always fails with a bare file does not exist. This blocks task ios:build/task ios:run for literally any project.
2. iOS cross-compile: linux_cgo.c/linux_cgo.h build tags don't exclude Android — wait, this one's Android, see #4.
3. iOS cross-compile: messageprocessor.go:201 references androidMethodNames unconditionally
pkg/application/messageprocessor.go has a Debug-logging switch that references both iosMethodNames and androidMethodNames with no build tag on the file itself. messageprocessor_ios.go (//go:build ios) defines iosMethodNames but never defines androidMethodNames — only messageprocessor_android.go (//go:build android) and the desktop stub (//go:build !ios && !android) do. Result: GOOS=ios go build fails with undefined: androidMethodNames.
4. iOS cross-compile: events_common_ios.go:9 references events.IOS, which doesn't exist
pkg/events/events.go:488 defines var iOS = newIOSEvents() — lowercase, unexported — while every sibling (Common, Linux, Mac, Windows) is exported. events_common_ios.go was written against the exported name (events.IOS.ApplicationDidFinishLaunching), so it fails with undefined: events.IOS. Looks like a partial rename.
5. Android cross-compile: linux_cgo.c/linux_cgo.h build tag is missing && !android
Both files have //go:build linux && !gtk3 && !server. Go implicitly sets the linux build tag when GOOS=android (Android is Linux-based), so these GTK-dependent cgo files get pulled into Android builds too and fail on gtk/gtk.h: file not found. application_linux.go/linux_cgo.go already correctly exclude !android — just the .c/.h files were missed.
6. Android cross-compile: messageprocessor_android.go is missing iosMethodNames — same root cause as #3, mirrored: GOOS=android fails with undefined: iosMethodNames.
7. Android cross-compile: pkg/events has no Android events var at all
events_common_android.go:9 references events.Android.ActivityCreated, but pkg/events never defines an Android var/struct (only Common/Linux/Mac/Windows/IOS). Fails with undefined: events.Android.
8. Android cross-compile: application_android.go's JNI page-finished handler calls runtime.Core() with no arguments
Every other platform calls runtime.Core(globalApplication.impl.GetFlags(globalApplication.options)) (see webview_window_darwin.go, webview_window_windows.go, webview_window_linux.go). The Android call site just does runtime.Core(), which doesn't match runtime.Core(flags map[string]any)'s signature — androidApp.GetFlags already exists, it's just never wired into this call.
Reproduction
# iOS
SDK_PATH=$(xcrun --sdk iphonesimulator --show-sdk-path)
GOOS=ios CGO_ENABLED=1 GOARCH=arm64 \
CGO_CFLAGS="-isysroot $SDK_PATH -target arm64-apple-ios15.0-simulator -mios-simulator-version-min=15.0" \
CGO_LDFLAGS="-isysroot $SDK_PATH -target arm64-apple-ios15.0-simulator" \
go build -buildmode=c-archive -tags ios,debug -o /tmp/app.a .
# → undefined: androidMethodNames, undefined: events.IOS
# Android (NDK r27)
export CC=".../aarch64-linux-android21-clang" CGO_ENABLED=1 GOOS=android GOARCH=arm64
go build -buildmode=c-shared -tags android,debug -o /tmp/libwails.so .
# → fatal error: 'gtk/gtk.h' file not found
# (after working around that) → undefined: iosMethodNames, undefined: events.Android,
# not enough arguments in call to runtime.Core
Fix
PR incoming with all fixes applied — verified not just compile-clean but running: packaged and launched a real .app in the iOS Simulator, and a real debug APK in an arm64-v8a Android emulator, both booting the Go runtime and completing the native JS-bridge handshake without crashing.
Description
Cross-compiling a real v3 app (backend Go service + vanilla HTML/JS frontend, no mobile-specific code beyond what the templates generate) for
GOOS=iosandGOOS=androidfails outright onv3.0.0-alpha.98— before even reaching app-specific code. Filed with a PR that fixes all five.Environment
compileSdk 34,minSdk 21Bugs found (all reproduced by direct
go build, not just viawails3 task)1.
wails3 ios overlay:gencan't run outside the Wails monorepo checkoutinternal/commands/ios_overlay_gen.go'srepoRoot()walks up from the current working directory looking for a folder namedv3/internal/commands. That only exists inside a checkout ofwailsapp/wailsitself — any normal downstream project (including the one generated bywails3 init -t vanilla) has no such path, sowails3 ios overlay:gen -out build/ios/xcode/overlay.json -config build/config.ymlalways fails with a barefile does not exist. This blockstask ios:build/task ios:runfor literally any project.2. iOS cross-compile:
linux_cgo.c/linux_cgo.hbuild tags don't exclude Android — wait, this one's Android, see #4.3. iOS cross-compile:
messageprocessor.go:201referencesandroidMethodNamesunconditionallypkg/application/messageprocessor.gohas a Debug-logging switch that references bothiosMethodNamesandandroidMethodNameswith no build tag on the file itself.messageprocessor_ios.go(//go:build ios) definesiosMethodNamesbut never definesandroidMethodNames— onlymessageprocessor_android.go(//go:build android) and the desktop stub (//go:build !ios && !android) do. Result:GOOS=ios go buildfails withundefined: androidMethodNames.4. iOS cross-compile:
events_common_ios.go:9referencesevents.IOS, which doesn't existpkg/events/events.go:488definesvar iOS = newIOSEvents()— lowercase, unexported — while every sibling (Common,Linux,Mac,Windows) is exported.events_common_ios.gowas written against the exported name (events.IOS.ApplicationDidFinishLaunching), so it fails withundefined: events.IOS. Looks like a partial rename.5. Android cross-compile:
linux_cgo.c/linux_cgo.hbuild tag is missing&& !androidBoth files have
//go:build linux && !gtk3 && !server. Go implicitly sets thelinuxbuild tag whenGOOS=android(Android is Linux-based), so these GTK-dependent cgo files get pulled into Android builds too and fail ongtk/gtk.h: file not found.application_linux.go/linux_cgo.goalready correctly exclude!android— just the.c/.hfiles were missed.6. Android cross-compile:
messageprocessor_android.gois missingiosMethodNames— same root cause as #3, mirrored:GOOS=androidfails withundefined: iosMethodNames.7. Android cross-compile:
pkg/eventshas noAndroidevents var at allevents_common_android.go:9referencesevents.Android.ActivityCreated, butpkg/eventsnever defines anAndroidvar/struct (onlyCommon/Linux/Mac/Windows/IOS). Fails withundefined: events.Android.8. Android cross-compile:
application_android.go's JNI page-finished handler callsruntime.Core()with no argumentsEvery other platform calls
runtime.Core(globalApplication.impl.GetFlags(globalApplication.options))(seewebview_window_darwin.go,webview_window_windows.go,webview_window_linux.go). The Android call site just doesruntime.Core(), which doesn't matchruntime.Core(flags map[string]any)'s signature —androidApp.GetFlagsalready exists, it's just never wired into this call.Reproduction
Fix
PR incoming with all fixes applied — verified not just compile-clean but running: packaged and launched a real
.appin the iOS Simulator, and a real debug APK in an arm64-v8a Android emulator, both booting the Go runtime and completing the native JS-bridge handshake without crashing.