From 56f5a09737493b6bff566dff2e78b43fda5f9761 Mon Sep 17 00:00:00 2001 From: Laurent Trinques Date: Thu, 14 May 2026 11:20:36 +0200 Subject: [PATCH] Update MacQetDeploy_arm64.sh --- misc/MacQetDeploy_arm64.sh | 238 +++++++++++++++++++++++-------------- 1 file changed, 147 insertions(+), 91 deletions(-) diff --git a/misc/MacQetDeploy_arm64.sh b/misc/MacQetDeploy_arm64.sh index 305191de3..de258291b 100644 --- a/misc/MacQetDeploy_arm64.sh +++ b/misc/MacQetDeploy_arm64.sh @@ -16,7 +16,6 @@ # along with QElectroTech. If not, see . # Need homebrew and coreutils installed see . - #Force MacOSX12.3.sdk #see: https://www.downtowndougbrown.com/2023/08/how-to-create-a-qt-5-arm-intel-universal-binary-for-mac/ @@ -27,13 +26,13 @@ APPNAME='qelectrotech' BUNDLE=$APPNAME.app APPBIN="$BUNDLE/Contents/MacOS/$APPNAME" -# Emplacement du script +# Script location current_dir=$(dirname "$0") -# On se remet au depart +# Go back to repo root cd "${current_dir}/../" -# Emplacement courant +# Current directory current_dir=$(PWD) @@ -46,11 +45,11 @@ echo "Please see the \"Deploying an Application on Qt/Mac\"" echo "page in the Qt documentation for more information." echo echo "This script :" -echo "\t - up date the git depot" -echo "\t - built the application bundle," +echo "\t - update the git depot" +echo "\t - build the application bundle," echo "\t - copy over required Qt frameworks," echo "\t - copy additional files: translations, titleblocks and elements," -echo "\t - create image disk." +echo "\t - create DMG disk image." echo echo "Enjoy ;-)" echo @@ -70,24 +69,23 @@ echo echo "______________________________________________________________" echo "Run GIT:" -# Fait une mise à jour git submodule init git submodule update git pull --recurse-submodules git pull -#git checkout foliolist_position - -# recupere le numero de la nouvelle revision +# Get revision number and version GITCOMMIT=$(git rev-parse --short HEAD) A=$(git rev-list HEAD --count) HEAD=$(($A+473)) - VERSION=$(cat sources/qetversion.cpp | grep "return QVersionNumber{"| head -n 1| awk -F "{" '{ print $2 }' | awk -F "}" '{ print $1 }' | sed -e 's/,/./g' -e 's/ //g') -# Tarball de la dernière revision déjà créé -if [ -e "build-aux/mac-osx/${APPNAME}-$VERSION-r$HEAD-arm64.zip" ] ; then +DMG_NAME="${APPNAME}-$VERSION-r$HEAD-arm64.dmg" +DMG_PATH="build-aux/mac-osx/$DMG_NAME" + +# Check if already built +if [ -e "$DMG_PATH" ] ; then echo "There are not new updates, make disk image can" echo "take a lot of time (5 min). Can you continu?" echo "[y/n]" @@ -107,28 +105,27 @@ echo echo "______________________________________________________________" echo "Run make install:" -# pour effacer l'ancienne compilation +# Remove old bundle if [ -d $BUNDLE ] ; then - echo "Removing hold bundle..." + echo "Removing old bundle..." rm -rf $BUNDLE fi if [ -e Makefile ] ; then - echo "Removing hold Makefile..." + echo "Removing old Makefile..." rm .qmake.stash make clean fi -# genere le Makefile +# Generate Makefile echo "Generating new makefile..." -qmake -spec macx-clang +qmake -spec macx-clang -# compilation +# Compile if [ -e Makefile.Release ] ; then - START_TIME=$SECONDS - - # arret du script si erreur de compilation + START_TIME=$SECONDS + testSuccessBuild () { - if [ $? -ne 0 ]; then + if [ $? -ne 0 ]; then cleanVerionTag ELAPSED_TIME=$(($SECONDS - $START_TIME)) echo @@ -137,19 +134,18 @@ if [ -e Makefile.Release ] ; then fi } - # utilise tout les coeurs pour une compilation plus rapide coeur=$(sysctl hw.ncpu | awk '{print $2}') - if [ $? -ne 0 ]; then + if [ $? -ne 0 ]; then make -f Makefile.Release testSuccessBuild else make -j$(($coeur + 1)) -f Makefile.Release testSuccessBuild fi - + ELAPSED_TIME=$(($SECONDS - $START_TIME)) - echo - echo "The time of compilation is $(($ELAPSED_TIME/60)) min $(($ELAPSED_TIME%60)) sec" + echo + echo "The time of compilation is $(($ELAPSED_TIME/60)) min $(($ELAPSED_TIME%60)) sec" else echo "ERROR: Makefile not found. This script requires the macx-clang makespec" exit @@ -157,8 +153,7 @@ fi cp -R ${current_dir}/misc/Info.plist qelectrotech.app/Contents/ cp -R ${current_dir}/ico/mac_icon/*.icns qelectrotech.app/Contents/Resources/ -# On rajoute le numero de version pour "cmd + i" -/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $VERSION r$HEAD" "qelectrotech.app/Contents/Info.plist" # Version number +/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $VERSION r$HEAD" "qelectrotech.app/Contents/Info.plist" ### copy over frameworks ############################################ @@ -167,35 +162,29 @@ echo echo "______________________________________________________________" echo "Copy Qt libraries and private frameworks:" -echo "Processing Mac deployment tool..." +echo "Processing Mac deployment tool..." if [ ! -d $BUNDLE ] ; then echo "ERROR: cannot find application bundle \"$BUNDLE\" in current directory" exit fi macdeployqt $BUNDLE -### add file missing ####################################### +### add missing files ############################################### echo echo "______________________________________________________________" -echo "Copy file missing:" +echo "Copy missing files:" -# Dossier à ajouter QET_ELMT_DIR="${current_dir}/elements/" QET_TBT_DIR="${current_dir}/titleblocks/" QET_LANG_DIR="${current_dir}/lang/" QET_EXAMPLES_DIR="${current_dir}/examples/" QET_FONTS_DIR="${current_dir}/fonts/" QET_LICENSES_DIR="${current_dir}/licenses/" - - -# Add new folder for Qt dialog translation see -## see . - LANG_DIR="${current_dir}/lang1/" if [ -d "${QET_ELMT_DIR}" ]; then - echo "Copying add elements in the bundle..." + echo "Copying elements in the bundle..." cp -R ${QET_ELMT_DIR} $BUNDLE/Contents/Resources/elements fi @@ -205,26 +194,26 @@ if [ -d "${QET_TBT_DIR}" ]; then fi if [ -d "${QET_LANG_DIR}" ]; then - echo "Copying translations in the bundle... " + echo "Copying translations in the bundle..." mkdir $BUNDLE/Contents/Resources/lang cp ${current_dir}/lang/*.qm $BUNDLE/Contents/Resources/lang fi if [ -d "${LANG_DIR}" ]; then - echo "Copying translations in the bundle... " - cp ${current_dir}/lang1/*.qm $BUNDLE/Contents/Resources/lang + echo "Copying extra translations in the bundle..." + cp ${current_dir}/lang1/*.qm $BUNDLE/Contents/Resources/lang fi if [ -d "${QET_EXAMPLES_DIR}" ]; then - echo "Copying examples in the bundle... " - mkdir $BUNDLE/Contents/Resources/examples - cp ${current_dir}/examples/*.qet $BUNDLE/Contents/Resources/examples + echo "Copying examples in the bundle..." + mkdir $BUNDLE/Contents/Resources/examples + cp ${current_dir}/examples/*.qet $BUNDLE/Contents/Resources/examples fi if [ -d "${QET_FONTS_DIR}" ]; then - echo "Copying fonts in the bundle... " - mkdir $BUNDLE/Contents/Resources/fonts - cp ${current_dir}/fonts/*.ttf $BUNDLE/Contents/Resources/fonts + echo "Copying fonts in the bundle..." + mkdir $BUNDLE/Contents/Resources/fonts + cp ${current_dir}/fonts/*.ttf $BUNDLE/Contents/Resources/fonts fi if [ -d "${QET_LICENSES_DIR}" ]; then @@ -233,74 +222,141 @@ if [ -d "${QET_LICENSES_DIR}" ]; then cp -R -L ${QET_LICENSES_DIR} $BUNDLE/Contents/Resources/licenses fi -codesign --force --deep --sign --timestamp -s "Developer ID Application: Laurent TRINQUES (Y73WZ6WZ5X)" --options=runtime $BUNDLE - -### create zip tarball for notarization ############################################### +### Sign the bundle ################################################# echo echo "______________________________________________________________" -echo "Create zip tarball for notarization:" +echo "Code signing bundle:" -/usr/bin/ditto -c -k --keepParent $BUNDLE "build-aux/mac-osx/${APPNAME}-$VERSION-r$HEAD-arm64.zip" +codesign --force --deep --sign --timestamp \ + -s "Developer ID Application: Laurent TRINQUES (Y73WZ6WZ5X)" \ + --options=runtime $BUNDLE -### notarize zip tarball ############################################### -echo -e "\033[1;31mWould you like to upload for Notarize packages "${APPNAME}"-"$VERSION"-"r$HEAD-arm64.zip", n/Y?.\033[m" +### Create zip for notarization only ################################ +# This ZIP is temporary — used only to submit to notarytool. +# The final deliverable will be a DMG (see below). + +echo +echo "______________________________________________________________" +echo "Create temporary zip for notarization:" + +NOTARIZE_ZIP="/tmp/${APPNAME}-$VERSION-r$HEAD-arm64-notarize.zip" +/usr/bin/ditto -c -k --keepParent $BUNDLE "$NOTARIZE_ZIP" + +### Notarize ######################################################## + +echo -e "\033[1;31mWould you like to upload for notarization \"${APPNAME}-${VERSION}-r${HEAD}-arm64\", n/Y?\033[m" read a if [[ $a == "Y" || $a == "y" ]]; then -echo -echo "______________________________________________________________" -echo "Notarize zip tarball:" - -xcrun notarytool submit "build-aux/mac-osx/${APPNAME}-$VERSION-r$HEAD-arm64.zip" --keychain-profile "org.qelectrotech" --wait + echo + echo "______________________________________________________________" + echo "Notarizing:" + xcrun notarytool submit "$NOTARIZE_ZIP" --keychain-profile "org.qelectrotech" --wait else -echo -e "\033[1;33mExit.\033[m" + echo -e "\033[1;33mExit.\033[m" fi -### Clean up zip used for notarization ######################################## -echo 'Cleaning up notarization zip...' -rm "build-aux/mac-osx/${APPNAME}-$VERSION-r$HEAD-arm64.zip" +# Clean up temporary notarization zip +echo "Cleaning up temporary notarization zip..." +rm -f "$NOTARIZE_ZIP" -### Staple the notarization ticket to the .app ################################ -echo -e "\033[1;31mWould you like to staple the app MacOS packages "${APPNAME}"-"$VERSION"-"r$HEAD", n/Y?.\033[m" +### Staple ########################################################## + +echo -e "\033[1;31mWould you like to staple the app \"${APPNAME}-${VERSION}-r${HEAD}\", n/Y?\033[m" read a if [[ $a == "Y" || $a == "y" ]]; then -xcrun stapler staple -v $BUNDLE + xcrun stapler staple -v $BUNDLE + # Verify staple is correctly applied + echo "Verifying staple..." + xcrun stapler validate -v $BUNDLE + spctl -a -vv $BUNDLE else -echo -e "\033[1;33mExit.\033[m" + echo -e "\033[1;33mExit.\033[m" fi -### Re-create final zip tarball (without --sequesterRsrc so Gatekeeper works with Chrome) ### +### Create final DMG ################################################ +# A DMG is used instead of a ZIP because it correctly preserves the +# Gatekeeper staple when downloaded via Chrome or any other browser. +# ZIP extraction via Archive Utility can strip extended attributes, +# causing Gatekeeper to block the app with an "unverified developer" +# warning. A signed and notarized DMG does not have this issue. + echo echo "______________________________________________________________" -echo "Re-create final zip tarball (stapled, Gatekeeper-compatible):" +echo "Create final DMG (Gatekeeper-compatible with Chrome and Safari):" -# Do NOT use --sequesterRsrc: it breaks extended attributes extraction -# in Chrome / Archive Utility, causing Gatekeeper to block the app. -# ditto without --sequesterRsrc preserves the staple correctly. -/usr/bin/ditto -c -k --keepParent $BUNDLE "build-aux/mac-osx/${APPNAME}-$VERSION-r$HEAD-arm64.zip" +mkdir -p "build-aux/mac-osx" -### Clean up bundle ####################################################### -echo 'Cleaning up bundle...' +# Create a temporary writable DMG from the stapled .app bundle +hdiutil create \ + -volname "QElectroTech $VERSION" \ + -srcfolder "$BUNDLE" \ + -ov \ + -format UDRW \ + -fs HFS+ \ + "/tmp/qet_tmp.dmg" + +# Convert to compressed read-only DMG +hdiutil convert "/tmp/qet_tmp.dmg" \ + -format UDZO \ + -o "$DMG_PATH" + +rm -f "/tmp/qet_tmp.dmg" + +# Sign the DMG itself +codesign \ + --sign "Developer ID Application: Laurent TRINQUES (Y73WZ6WZ5X)" \ + --timestamp \ + "$DMG_PATH" + +echo "DMG created and signed: $DMG_PATH" + +### Notarize the DMG ################################################ + +echo -e "\033[1;31mWould you like to notarize the DMG \"${DMG_NAME}\", n/Y?\033[m" +read a +if [[ $a == "Y" || $a == "y" ]]; then + echo + echo "______________________________________________________________" + echo "Notarizing DMG:" + xcrun notarytool submit "$DMG_PATH" --keychain-profile "org.qelectrotech" --wait + + echo "Stapling notarization ticket to DMG..." + xcrun stapler staple "$DMG_PATH" + echo "DMG notarized and stapled OK." +else + echo -e "\033[1;33mExit.\033[m" +fi + +### Clean up bundle ################################################# + +echo "Cleaning up bundle..." rm -rf $BUNDLE -### The end, process is done ########################################## +### The end ######################################################### echo echo "______________________________________________________________" -echo "The process of creating deployable application zip is done." -echo "The zip is in the folder 'build-aux/mac-osx'." +echo "The process is done." +echo "DMG is in the folder 'build-aux/mac-osx'." -#rsync to TF DMG builds -echo -e "\033[1;31mWould you like to upload MacOS packages "${APPNAME}"-"$VERSION"-"r$HEAD-arm64.zip", n/Y?.\033[m" +### Upload via rsync ################################################ + +echo -e "\033[1;31mWould you like to upload MacOS package \"${DMG_NAME}\", n/Y?\033[m" read a if [[ $a == "Y" || $a == "y" ]]; then -cp -Rf "build-aux/mac-osx/${APPNAME}-$VERSION-r$HEAD-arm64.zip" /Users/laurent/MAC_OS_X/ -rsync -e ssh -av --delete-after --no-owner --no-g --chmod=g+w --progress --exclude='.DS_Store' /Users/laurent/MAC_OS_X/ server:download.qelectrotech.org/qet/builds/MAC_OS_X/arm64/ -if [ $? != 0 ]; then -{ -echo "RSYNC ERROR: problem syncing ${APPNAME}-$VERSION-r$HEAD-arm64.zip" -rsync -e ssh -av --delete-after --no-owner --no-g --chmod=g+w --progress --exclude='.DS_Store' /Users/laurent/MAC_OS_X/ server:download.qelectrotech.org/qet/builds/MAC_OS_X/arm64/ -} fi + cp -Rf "$DMG_PATH" /Users/laurent/MAC_OS_X/ + rsync -e ssh -av --delete-after --no-owner --no-g --chmod=g+w \ + --progress --exclude='.DS_Store' \ + /Users/laurent/MAC_OS_X/ \ + server:download.qelectrotech.org/qet/builds/MAC_OS_X/arm64/ + if [ $? != 0 ]; then + echo "RSYNC ERROR: problem syncing ${DMG_NAME}, retrying..." + rsync -e ssh -av --delete-after --no-owner --no-g --chmod=g+w \ + --progress --exclude='.DS_Store' \ + /Users/laurent/MAC_OS_X/ \ + server:download.qelectrotech.org/qet/builds/MAC_OS_X/arm64/ + fi else -echo -e "\033[1;33mExit.\033[m" + echo -e "\033[1;33mExit.\033[m" fi