From b67aebd4626d9d61d070342f571d135265430853 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Mon, 1 Jan 2024 19:02:09 -0800 Subject: [PATCH] recreate a working iOS device build The current XCode and Qt 5.15.2 (the newest version that we can use due to Kirigami and the lack of binaries for the later open source releases of Qt 5.15) have some issues. Work around those. Also, don't create fat armv7/arm64 binaries anymore for iOS - there are no supported armv7 devices anymore. Signed-off-by: Dirk Hohndel --- Subsurface-mobile.pro | 22 ++--- packaging/ios/build.sh | 206 ++++++++++++++++++++++------------------- 2 files changed, 123 insertions(+), 105 deletions(-) diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index 31c104a01..df84553fc 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -419,11 +419,11 @@ ios { Q_ENABLE_BITCODE.value = NO QMAKE_MAC_XCODE_SETTINGS += Q_ENABLE_BITCODE - LIBS += ../install-root/ios/lib/libdivecomputer.a \ - ../install-root/ios/lib/libgit2.a \ - ../install-root/ios/lib/libzip.a \ - ../install-root/ios/lib/libxslt.a \ - ../install-root/ios/lib/qml/org/kde/kirigami.2/libkirigamiplugin.a \ + LIBS += ../install-root/ios/$${QT_ARCH}/lib/libdivecomputer.a \ + ../install-root/ios/$${QT_ARCH}/lib/libgit2.a \ + ../install-root/ios/$${QT_ARCH}/lib/libzip.a \ + ../install-root/ios/$${QT_ARCH}/lib/libxslt.a \ + ../install-root/ios/$${QT_ARCH}/lib/qml/org/kde/kirigami.2/libkirigamiplugin.a \ ../googlemaps-build/libqtgeoservices_googlemaps.a \ -liconv \ -lsqlite3 \ @@ -431,14 +431,14 @@ ios { LIBS += -framework MessageUI - INCLUDEPATH += ../install-root/ios/include/ \ - ../install-root/lib/libzip/include \ - ../install-root/ios/include/libxstl \ - ../install-root/ios/include/libexstl \ - ../install-root/ios/include/openssl \ + INCLUDEPATH += ../install-root/ios/$${QT_ARCH}/include/ \ + ../install-root/ios/$${QT_ARCH}/include \ + ../install-root/ios/$${QT_ARCH}/include/libxstl \ + ../install-root/ios/$${QT_ARCH}/include/libexstl \ + ../install-root/ios/$${QT_ARCH}/include/openssl \ . \ ./core \ ./mobile-widgets/3rdparty/kirigami/src/libkirigami \ - /usr/include/libxml2 + ../install-root/ios/$${QT_ARCH}/include/libxml2 } diff --git a/packaging/ios/build.sh b/packaging/ios/build.sh index 562b035c5..b637f3c65 100755 --- a/packaging/ios/build.sh +++ b/packaging/ios/build.sh @@ -1,13 +1,15 @@ #!/bin/bash +# shellcheck disable=SC2155 # # show what you are doing and stop when things break set -x set -e DEBUGRELEASE="Release" -ARCHS="armv7 arm64 x86_64" +ARCH="arm64" TARGET="iphoneos" TARGET2="Device" + # deal with all the command line arguments while [[ $# -gt 0 ]] ; do arg="$1" @@ -23,10 +25,14 @@ while [[ $# -gt 0 ]] ; do ;; -simulator) # build for the simulator instead of for a device - ARCHS="x86_64" + ARCH="x86_64" TARGET="iphonesimulator" TARGET2="simulator" ;; + -device) + # build for device instead of for the simulator + ARCH="arm64" + ;; -all) # build both debug and release for all devices DEBUGRELEASE="All" @@ -49,17 +55,30 @@ cd .. export PARENT_DIR=$PWD popd -IOS_QT=~/Qt -QT_VERSION=$(cd "$IOS_QT"; ls -d [1-9]* | awk -F. '{ printf("%02d.%02d.%02d\n", $1,$2,$3); }' | sort -n | tail -1 | sed -e 's/\.0/\./g;s/^0//') - -if [ -z $QT_VERSION ] ; then +IOS_QT=${IOS_QT:-~/Qt} +if [ -z "$QT_VERSION" ] ; then + QT_VERSION=$(cd "$IOS_QT"; ls -d [1-9]* | awk -F. '{ printf("%02d.%02d.%02d\n", $1,$2,$3); }' | sort -n | tail -1 | sed -e 's/\.0/\./g;s/^0//') +fi +if [ -z "$QT_VERSION" ] ; then echo "Couldn't determine Qt version; giving up" exit 1 fi +# Xcode / SDK 14 and later trigger a bug in Qt 5.15 +QMAKE="${IOS_QT}/${QT_VERSION}/ios/bin/qmake" +if [[ $QT_VERSION = 5.15* ]] ; then + QMAKEARG=" -early QMAKE_DEFAULT_LIBDIRS=$(xcrun -show-sdk-path)/usr/lib" + + # also, one Python script in Qt 5.15 still references the unversioned Python interpreter; + # let's fix that... + if ! grep -q /usr/bin/python3 "${IOS_QT}/${QT_VERSION}/ios/mkspecs/features/uikit/devices.py" ; then + sed -i.bak 's/\/usr\/bin\/python/\/usr\/bin\/python3/' "${IOS_QT}/${QT_VERSION}/ios/mkspecs/features/uikit/devices.py" + fi +fi + # set up the Subsurface versions by hand GITVERSION=$(cd "$SUBSURFACE_SOURCE" ; git describe --match "v[0-9]*" --abbrev=12) -CANONICALVERSION=$(echo $GITVERSION | sed -e 's/-g.*$// ; s/^v//' | sed -e 's/-/./') +CANONICALVERSION=$(echo "$GITVERSION" | sed -e 's/-g.*$// ; s/^v//' | sed -e 's/-/./') MOBILEVERSION=$(grep MOBILE "$SUBSURFACE_SOURCE"/cmake/Modules/version.cmake | cut -d\" -f 2) echo "#define GIT_VERSION_STRING \"$GITVERSION\"" > "$SUBSURFACE_SOURCE"/ssrf-version.h echo "#define CANONICAL_VERSION_STRING \"$CANONICALVERSION\"" >> "$SUBSURFACE_SOURCE"/ssrf-version.h @@ -72,6 +91,7 @@ fi pushd "$SUBSURFACE_SOURCE"/packaging/ios # create Info.plist with the correct versions +# shellcheck disable=SC2002 cat Info.plist.in | sed "s/@MOBILE_VERSION@/$MOBILEVERSION/;s/@CANONICAL_VERSION@/$CANONICALVERSION/;s/@PRODUCT_BUNDLE_IDENTIFIER@/$BUNDLE/" > Info.plist popd @@ -79,9 +99,6 @@ if [ "$versionOnly" = "1" ] ; then exit 0 fi -# Build Subsurface-mobile by default -SUBSURFACE_MOBILE=1 - pushd "$SUBSURFACE_SOURCE" bash scripts/mobilecomponents.sh popd @@ -94,13 +111,11 @@ popd if [ "$QUICK" != "1" ] ; then -for ARCH in $ARCHS; do + echo "building dependencies for $ARCH" - echo next building for $ARCH - - INSTALL_ROOT=$PARENT_DIR/install-root/ios/$ARCH - mkdir -p "$INSTALL_ROOT"/lib "$INSTALL_ROOT"/bin "$INSTALL_ROOT"/include - PKG_CONFIG_LIBDIR="$INSTALL_ROOT"/lib/pkgconfig + INSTALL_ROOT="${PARENT_DIR}/install-root/ios/${ARCH}" + mkdir -p "${INSTALL_ROOT}/lib" "${INSTALL_ROOT}/bin" "${INSTALL_ROOT}/include" + PKG_CONFIG_LIBDIR="${INSTALL_ROOT}/lib/pkgconfig" declare -x PKG_CONFIG_PATH=$PKG_CONFIG_LIBDIR declare -x PREFIX=$INSTALL_ROOT @@ -129,15 +144,23 @@ for ARCH in $ARCHS; do declare -x LDFLAGS="$CFLAGS -lsqlite3 -lpthread -lc++ -L$SDK_DIR/usr/lib -fembed-bitcode" # openssl build stuff. - export DEVELOPER=$(xcode-select --print-path)\ - export IPHONEOS_SDK_VERSION=$(xcrun --sdk iphoneos --show-sdk-version) - export IPHONEOS_DEPLOYMENT_VERSION="6.0" - export IPHONEOS_PLATFORM=$(xcrun --sdk iphoneos --show-sdk-platform-path) - export IPHONEOS_SDK=$(xcrun --sdk iphoneos --show-sdk-path) - export IPHONESIMULATOR_PLATFORM=$(xcrun --sdk iphonesimulator --show-sdk-platform-path) - export IPHONESIMULATOR_SDK=$(xcrun --sdk iphonesimulator --show-sdk-path) + export DEVELOPER=$(xcode-select --print-path) + export IPHONEOS_DEPLOYMENT_VERSION="12.0" + if [ "$ARCH" = "arm64" ] ; then + export IPHONEOS_SDK_VERSION=$(xcrun --sdk iphoneos --show-sdk-version) + export IPHONEOS_PLATFORM=$(xcrun --sdk iphoneos --show-sdk-platform-path) + export IPHONEOS_SDK=$(xcrun --sdk iphoneos --show-sdk-path) + export IPHONESIMULATOR_PLATFORM="" + export IPHONESIMULATOR_SDK="" + else + export IPHONEOS_SDK_VERSION="" + export IPHONEOS_PLATFORM="" + export IPHONEOS_SDK="" + export IPHONESIMULATOR_PLATFORM=$(xcrun --sdk iphonesimulator --show-sdk-platform-path) + export IPHONESIMULATOR_SDK=$(xcrun --sdk iphonesimulator --show-sdk-path) + fi export OSX_SDK_VERSION=$(xcrun --sdk macosx --show-sdk-version) - export OSX_DEPLOYMENT_VERSION="10.8" + export OSX_DEPLOYMENT_VERSION="11.0" export OSX_PLATFORM=$(xcrun --sdk macosx --show-sdk-platform-path) export OSX_SDK=$(xcrun --sdk macosx --show-sdk-path) @@ -153,7 +176,7 @@ for ARCH in $ARCHS; do "$PARENT_DIR"/libxml2/configure --host=${BUILDCHAIN} --prefix="$PREFIX" --without-lzma --without-python --without-iconv --enable-static --disable-shared perl -pi -e 's/runtest\$\(EXEEXT\)//' Makefile perl -pi -e 's/testrecurse\$\(EXEEXT\)//' Makefile - make + make -j make install popd fi @@ -163,10 +186,10 @@ for ARCH in $ARCHS; do autoreconf --install popd if [ ! -e "$PKG_CONFIG_LIBDIR"/libxslt.pc ] ; then - mkdir -p "$PARENT_DIR"/libxslt-build-$ARCH - pushd "$PARENT_DIR"/libxslt-build-$ARCH + mkdir -p "${PARENT_DIR}/libxslt-build-${ARCH}" + pushd "${PARENT_DIR}/libxslt-build-${ARCH}" "$PARENT_DIR"/libxslt/configure --host=$BUILDCHAIN --prefix="$PREFIX" --with-libxml-include-prefix="$INSTALL_ROOT"/include/libxml2 --without-python --without-crypto --enable-static --disable-shared - make + make -j make install popd fi @@ -175,8 +198,8 @@ for ARCH in $ARCHS; do pushd "$PARENT_DIR"/libzip # don't waste time on building command line tools, examples, manual, and regression tests - and don't build the BZIP2 support we don't need sed -i.bak 's/ADD_SUBDIRECTORY(src)//;s/ADD_SUBDIRECTORY(examples)//;s/ADD_SUBDIRECTORY(man)//;s/ADD_SUBDIRECTORY(regress)//' CMakeLists.txt - mkdir -p "$PARENT_DIR"/libzip-build-$ARCH - pushd "$PARENT_DIR"/libzip-build-$ARCH + mkdir -p "${PARENT_DIR}/libzip-build-${ARCH}" + pushd "${PARENT_DIR}/libzip-build-${ARCH}" cmake -DBUILD_SHARED_LIBS="OFF" \ -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" \ -DCMAKE_INSTALL_PREFIX="$PREFIX" \ @@ -184,10 +207,10 @@ for ARCH in $ARCHS; do -DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE \ -DENABLE_OPENSSL=FALSE \ -DENABLE_GNUTLS=FALSE \ - "$PARENT_DIR"/libzip + "${PARENT_DIR}/libzip" # quiet the super noise warnings sed -i.bak 's/C_FLAGS = /C_FLAGS = -Wno-nullability-completeness -Wno-expansion-to-defined /' lib/CMakeFiles/zip.dir/flags.make - make + make -j make install popd mv CMakeLists.txt.bak CMakeLists.txt @@ -199,10 +222,10 @@ for ARCH in $ARCHS; do sed -i.bak 's/ADD_C_FLAG_IF_SUPPORTED(-W/# ADD_C_FLAG_IF_SUPPORTED(-W/' CMakeLists.txt popd - if [ ! -e $PKG_CONFIG_LIBDIR/libgit2.pc ] ; then - mkdir -p "$PARENT_DIR"/libgit2-build-$ARCH - pushd "$PARENT_DIR"/libgit2-build-$ARCH - cmake "$PARENT_DIR"/libgit2 \ + if [ ! -e "${PKG_CONFIG_LIBDIR}/libgit2.pc" ] ; then + mkdir -p "${PARENT_DIR}/libgit2-build-${ARCH}" + pushd "${PARENT_DIR}/libgit2-build-${ARCH}" + cmake "${PARENT_DIR}/libgit2" \ -G "Unix Makefiles" \ -DBUILD_SHARED_LIBS="OFF" \ -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" \ @@ -212,16 +235,16 @@ for ARCH in $ARCHS; do -DCMAKE_PREFIX_PATH="$PREFIX" \ -DCURL=OFF \ -DUSE_SSH=OFF \ - "$PARENT_DIR"/libgit2/ + "${PARENT_DIR}/libgit2/" sed -i.bak 's/C_FLAGS = /C_FLAGS = -Wno-nullability-completeness -Wno-expansion-to-defined /' src/CMakeFiles/git2.dir/flags.make - make + make -j make install # Patch away pkg-config dependency to zlib, its there, i promise - perl -pi -e 's/^(Requires.private:.*)zlib(.*)$/$1 $2/' $PKG_CONFIG_LIBDIR/libgit2.pc + perl -pi -e 's/^(Requires.private:.*)zlib(.*)$/$1 $2/' "${PKG_CONFIG_LIBDIR}/libgit2.pc" popd fi -# build libdivecomputer + # build libdivecomputer if [ ! -d "$SUBSURFACE_SOURCE"/libdivecomputer/src ] ; then pushd "$SUBSURFACE_SOURCE" git submodule init @@ -234,69 +257,63 @@ for ARCH in $ARCHS; do autoreconf --install popd fi - mkdir -p "$PARENT_DIR"/libdivecomputer-build-$ARCH - if [ ! -f "$PARENT_DIR"/libdivecomputer-build-$ARCH/git.SHA ] ; then - echo "" > "$PARENT_DIR"/libdivecomputer-build-$ARCH/git.SHA + mkdir -p "${PARENT_DIR}/libdivecomputer-build-${ARCH}" + if [ ! -f "${PARENT_DIR}/libdivecomputer-build-${ARCH}/git.SHA" ] ; then + echo "" > "${PARENT_DIR}/libdivecomputer-build-${ARCH}/git.SHA" fi - CURRENT_SHA=$(cd "$SUBSURFACE_SOURCE"/libdivecomputer ; git describe) - PREVIOUS_SHA=$(cat "$PARENT_DIR"/libdivecomputer-build-$ARCH/git.SHA) + CURRENT_SHA=$(cd "${SUBSURFACE_SOURCE}/libdivecomputer" ; git describe) + PREVIOUS_SHA=$(cat "${PARENT_DIR}/libdivecomputer-build-${ARCH}/git.SHA") if [ ! "$CURRENT_SHA" = "$PREVIOUS_SHA" ] ; then - echo $CURRENT_SHA > "$PARENT_DIR"/libdivecomputer-build-$ARCH/git.SHA - pushd "$PARENT_DIR"/libdivecomputer-build-$ARCH - ${SUBSURFACE_SOURCE}/libdivecomputer/configure --host=${BUILDCHAIN} --prefix="$PREFIX" --enable-static --disable-shared --enable-examples=no --without-libusb --without-hidapi --enable-ble - make + echo "$CURRENT_SHA" > "${PARENT_DIR}/libdivecomputer-build-${ARCH}/git.SHA" + pushd "${PARENT_DIR}/libdivecomputer-build-${ARCH}" + "${SUBSURFACE_SOURCE}/libdivecomputer/configure" --host=${BUILDCHAIN} --prefix="$PREFIX" --enable-static --disable-shared --enable-examples=no --without-libusb --without-hidapi + make -j make install popd fi -done -# build googlemaps -mkdir -p "$PARENT_DIR"/googlemaps-build -pushd "$PARENT_DIR"/googlemaps-build -"$IOS_QT"/"$QT_VERSION"/ios/bin/qmake "$PARENT_DIR"/googlemaps/googlemaps.pro CONFIG+=release -make -if [ "$DEBUGRELEASE" != "Release" ] ; then - "$IOS_QT"/"$QT_VERSION"/ios/bin/qmake "$PARENT_DIR"/googlemaps/googlemaps.pro CONFIG+=debug - make clean + # build googlemaps + mkdir -p "$PARENT_DIR"/googlemaps-build + pushd "$PARENT_DIR"/googlemaps-build + # yes, shellcheck will complain that we don't enclose QMAKEARG in quotes when we use it + # that's intentional so that the command line argument actually works + # shellcheck disable=SC2086 + "$QMAKE" $QMAKEARG "$PARENT_DIR"/googlemaps/googlemaps.pro \ + -spec macx-ios-clang CONFIG+=$TARGET CONFIG+=$TARGET2 CONFIG+=release make -fi -popd + if [ "$DEBUGRELEASE" != "Release" ] ; then + # shellcheck disable=SC2086 + "$QMAKE" $QMAKEARG "$PARENT_DIR"/googlemaps/googlemaps.pro \ + -spec macx-ios-clang CONFIG+=$TARGET CONFIG+=$TARGET2 CONFIG+=debug + make clean + make -j + fi + popd -# build Kirigami -mkdir -p "$PARENT_DIR"/kirigami-release-build -pushd "$PARENT_DIR"/kirigami-release-build -"$IOS_QT"/"$QT_VERSION"/ios/bin/qmake "$SUBSURFACE_SOURCE"/mobile-widgets/3rdparty/kirigami/kirigami.pro CONFIG+=release -make -# since the install prefix for qmake is rather weirdly implemented, let's copy things by hand into the multiarch destination -mkdir -p "$INSTALL_ROOT"/../lib/qml/ -cp -a org "$INSTALL_ROOT"/../lib/qml/ -popd -if [ "$DEBUGRELEASE" != "Release" ] ; then - mkdir -p "$PARENT_DIR"/kirigami-debug-build - pushd "$PARENT_DIR"/kirigami-debug-build - "$IOS_QT"/"$QT_VERSION"/ios/bin/qmake "$SUBSURFACE_SOURCE"/mobile-widgets/3rdparty/kirigami/kirigami.pro CONFIG+=debug - make + # build Kirigami + mkdir -p "$PARENT_DIR"/kirigami-release-build + pushd "$PARENT_DIR"/kirigami-release-build + # shellcheck disable=SC2086 + "$QMAKE" $QMAKEARG "$SUBSURFACE_SOURCE"/mobile-widgets/3rdparty/kirigami/kirigami.pro \ + -spec macx-ios-clang CONFIG+=$TARGET CONFIG+=$TARGET2 CONFIG+=release + make -j # since the install prefix for qmake is rather weirdly implemented, let's copy things by hand into the multiarch destination - mkdir -p "$INSTALL_ROOT"/../lib/qml/ - cp -a org "$INSTALL_ROOT"/../lib/qml/ + mkdir -p "$INSTALL_ROOT"/lib/qml/ + cp -a org "$INSTALL_ROOT"/lib/qml/ popd -fi - -# now combine the libraries into fat libraries -ARCH_ROOT=$PARENT_DIR/install-root/ios -cp -a "$ARCH_ROOT"/x86_64/* "$ARCH_ROOT" -if [ "$TARGET" = "iphoneos" ] ; then - pushd "$ARCH_ROOT"/lib - for LIB in $(find . -type f -name \*.a); do - # libkirigamiplugin is already a fat library - if grep -v -q "kirigami" <<< "$LIB" ; then - lipo "$ARCH_ROOT"/armv7/lib/"$LIB" "$ARCH_ROOT"/arm64/lib/"$LIB" "$ARCH_ROOT"/x86_64/lib/"$LIB" -create -output "$LIB" - fi - done - popd -fi - + if [ "$DEBUGRELEASE" != "Release" ] ; then + mkdir -p "$PARENT_DIR"/kirigami-debug-build + pushd "$PARENT_DIR"/kirigami-debug-build + # shellcheck disable=SC2086 + "$QMAKE" $QMAKEARG "$SUBSURFACE_SOURCE"/mobile-widgets/3rdparty/kirigami/kirigami.pro \ + -spec macx-ios-clang CONFIG+=$TARGET CONFIG+=$TARGET2 CONFIG+=debug + make -j + # since the install prefix for qmake is rather weirdly implemented, let's copy things by hand into the multiarch destination + mkdir -p "$INSTALL_ROOT"/lib/qml/ + cp -a org "$INSTALL_ROOT"/lib/qml/ + popd + fi fi pushd "$SUBSURFACE_SOURCE"/translations @@ -328,9 +345,10 @@ for BUILD_NOW in $BUILD_LOOP; do pushd "$BUILDX" rm -f ssrf-version.h ln -s "$SUBSURFACE_SOURCE"/ssrf-version.h . - "$IOS_QT"/"$QT_VERSION"/ios/bin/qmake "$SUBSURFACE_SOURCE"/Subsurface-mobile.pro \ + # shellcheck disable=SC2086 + "$QMAKE" $QMAKEARG "$SUBSURFACE_SOURCE"/Subsurface-mobile.pro \ -spec macx-ios-clang CONFIG+=$TARGET CONFIG+=$TARGET2 CONFIG+=$DRCONFIG - make + make -j popd done