mappu / miqt

MIT-licensed Qt bindings for Go
MIT License
267 stars 10 forks source link

Android support #33

Closed mappu closed 1 month ago

mappu commented 1 month ago

Miqt should support easily compiling Qt Widgets apps for Android.

mappu commented 1 month ago
Work in progress 2024-09-21 1. Create docker container ```dockerfile FROM raymii/qt:5.15-android-source RUN wget 'https://go.dev/dl/go1.23.1.linux-amd64.tar.gz' && \ tar x -C /usr/local/ -f go1.23.1.linux-amd64.tar.gz && \ rm go1.23.1.linux-amd64.tar.gz ENV PATH=/usr/local/go/bin:/opt/cmake/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/Qt-5.15.13/bin:/opt/android-sdk/cmdline-tools/tools/bin:/opt/android-sdk/tools:/opt/android-sdk/tools/bin:/opt/android-sdk/platform-tools ENV CC=/opt/android-sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang ENV CXX=/opt/android-sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang++ ENV CGO_ENABLED=1 ENV GOOS=android ENV GOARCH=arm64 ENV GOFLAGS=-buildvcs=false ``` 2. Create androiddeployqt properties file (these paths are specialized for the above docker container) ```json { "_description": "Available fields are documented in the template file at /usr/local/Qt-5.15.13/mkspecs/features/android/android_deployment_settings.prf", "application-binary": "handbindings", "architectures": { "arm64-v8a" : "aarch64-linux-android" }, "android-extra-libs": "/opt/android_openssl/ssl_1.1/arm64-v8a/libssl.so,/opt/android_openssl/ssl_1.1/arm64-v8a/libssl_1_1.so,/opt/android_openssl/ssl_1.1/arm64-v8a/libcrypto.so,/opt/android_openssl/ssl_1.1/arm64-v8a/libcrypto_1_1.so", "android-min-sdk-version": "23", "android-target-sdk-version": "30", "ndk": "/opt/android-sdk/ndk/22.1.7171670", "ndk-host": "linux-x86_64", "qml-root-path": "/miqt/cmd/handbindings", "qt": "/usr/local/Qt-5.15.13/", "sdk": "/opt/android-sdk", "sdkBuildToolsRevision": "30.0.2", "stdcpp-path": "/opt/android-sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/", "tool-prefix": "llvm", "toolchain-prefix": "llvm", "useLLVM": true } ``` 3. Patch updated android_cflags.go ```golang //+build android package main /* #cgo CXXFLAGS: -DQT_WIDGETS_LIB -I/usr/local/Qt-5.15.13/include/QtWidgets -I/usr/local/Qt-5.15.13/include/ -I/usr/local/Qt-5.15.13/include/QtCore -DQT_GUI_LIB -I/usr/local/Qt-5.15.13/include/QtGui -DQT_CORE_LIB #cgo LDFLAGS: /usr/local/Qt-5.15.13/lib/libQt5Widgets_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Gui_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Core_arm64-v8a.so // or #cgo CXXFLAGS: -fPIC -DQT_WIDGETS_LIB -I/usr/local/Qt-5.15.13/include/QtWidgets -I/usr/local/Qt-5.15.13/include/ -I/usr/local/Qt-5.15.13/include/QtCore -DQT_GUI_LIB -I/usr/local/Qt-5.15.13/include/QtGui -DQT_CORE_LIB #cgo LDFLAGS: /usr/local/Qt-5.15.13/lib/libQt5Widgets_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Gui_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Core_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Svg_arm64-v8a.so */ import "C" ``` 4. Enter docker container ```bash docker run --rm -v $(pwd):/miqt -it raymii/qt:5.15-android-source ``` 5. Compile Go app to android .so ```bash go build -ldflags "-s -w" -o android-build/libs/arm64-v8a/libhandbindings_arm64-v8a.so # or go build -buildmode c-shared -ldflags "-s -w -extldflags -Wl,-soname,libhandbindings_arm64-v8a.so" -o android-build/libs/arm64-v8a/libhandbindings_arm64-v8a.so ``` 6. Package android .so with Qt libraries as .apk bundle ```bash androiddeployqt --input ./android-deployment-settings.json --output ./android-build/ # Can add --release ``` However, the resulting app segfaults on my test device (Android 13): ``` *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** LineageOS Version: '20.0-20231031-NIGHTLY-beryllium' Build fingerprint: 'Xiaomi/beryllium/beryllium:10/QKQ1.190828.002/V12.0.3.0.QEJMIXM:user/release-keys' Revision: '0' ABI: 'arm64' Timestamp: 2024-09-22 13:07:14.699278279+1200 Process uptime: 582s Cmdline: org.qtproject.example.handbindings pid: 23128, tid: 25894, name: qtMainLoopThrea >>> org.qtproject.example.handbindings <<< uid: 10316 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000 Cause: null pointer dereference x0 0000000000000001 x1 0000007310c1be38 x2 00000075e49d354c x3 0000007310c1bcf8 x4 00000000000000e8 x5 0000007310c1b0e0 x6 0000000000000001 x7 002f003a00730074 x8 0000000000000000 x9 0000000000000001 x10 0000000000000000 x11 0000000000000002 x12 00000000000064df x13 0000000000000001 x14 0000000000000000 x15 0000000000002f0a x16 0000000000000001 x17 00000075e493dfc0 x18 00000072b2d26000 x19 0000000000000001 x20 00000072aa5f9c10 x21 00000072aa5f9000 x22 0000007310c1d000 x23 0000000000000000 x24 0000000000000000 x25 000000734dd38f50 x26 0000007310c1c79c x27 0000007310c1c798 x28 0000007310c1c6a0 x29 0000007310c1c640 lr 00000072aa51bc58 sp 0000007310c1bdf0 pc 0000000000000000 pst 0000000060000000 backtrace: #00 pc 0000000000000000 #01 pc 0000000000056c54 /data/app/~~N3A0yPAyQ7_g_C-96KZRUA==/org.qtproject.example.handbindings-0Vnj7BGCGkKrnewuC-pgTg==/lib/arm64/libplugins_platforms_qtforandroid_arm64-v8a.so (BuildId: 15bfa0d5f5d097b55236b90f87c48822cfbd0789) ```