#!/bin/bash # # android-stub-gen generates a .so that runs an exported function from another # so file. This is because Qt for Android always tries to run `main`, but Go's # c-shared build mode cannot export a function named `main`. set -eu # QT_PATH is already pre-set in our docker container environment. Includes trailing slash. QT_PATH=${QT_PATH:-/usr/local/Qt-5.15.13/} main() { if [[ $# -ne 3 ]] ; then echo "Usage: android-gen-stub.sh src.so function-name dest.so" >&2 exit 1 fi local ARG_SOURCE_SOFILE="$1" local ARG_FUNCTIONNAME="$2" local ARG_DEST_SOFILE="$3" local tmpdir=$(mktemp -d) trap "rm -r ${tmpdir}" EXIT echo "- Using temporary directory: ${tmpdir}" echo "- Found Qt path: ${QT_PATH}" echo "Generating stub..." cat > $tmpdir/miqtstub.cpp < #include #include typedef void goMainFunc_t(); int main(int argc, char** argv) { __android_log_print(ANDROID_LOG_VERBOSE, "miqt_stub", "Starting up"); void* handle = dlopen("$(basename "$ARG_SOURCE_SOFILE")", RTLD_LAZY); if (handle == NULL) { __android_log_print(ANDROID_LOG_VERBOSE, "miqt_stub", "miqt_stub: null handle opening so: %s", dlerror()); exit(1); } void* goMain = dlsym(handle, "${ARG_FUNCTIONNAME}"); if (goMain == NULL) { __android_log_print(ANDROID_LOG_VERBOSE, "miqt_stub", "miqt_stub: null handle looking for function: %s", dlerror()); exit(1); } __android_log_print(ANDROID_LOG_VERBOSE, "miqt_stub", "miqt_stub: Found target, calling"); // Cast to function pointer and call goMainFunc_t* f = (goMainFunc_t*)goMain; f(); __android_log_print(ANDROID_LOG_VERBOSE, "miqt_stub", "miqt_stub: Target function returned"); return 0; } EOF # Compile # Link with Qt libraries so that androiddeployqt detects us as being the # main shared library $CXX -shared \ -ldl \ -llog \ ${QT_PATH}plugins/platforms/libplugins_platforms_qtforandroid_arm64-v8a.so \ ${QT_PATH}lib/libQt5Widgets_arm64-v8a.so /usr/local/Qt-5.15.13/lib/libQt5Gui_arm64-v8a.so \ ${QT_PATH}lib/libQt5Core_arm64-v8a.so \ ${QT_PATH}lib/libQt5Svg_arm64-v8a.so \ ${QT_PATH}lib/libQt5AndroidExtras_arm64-v8a.so \ -fPIC -DQT_WIDGETS_LIB -I${QT_PATH}include/QtWidgets -I${QT_PATH}include/ -I${QT_PATH}include/QtCore -DQT_GUI_LIB -I${QT_PATH}include/QtGui -DQT_CORE_LIB \ $tmpdir/miqtstub.cpp \ "-Wl,-soname,$(basename "$ARG_DEST_SOFILE")" \ -o "$ARG_DEST_SOFILE" echo "Done." } main "$@"