From 4c7a48ec869bcd01f8406be896f6af2b4f989fe8 Mon Sep 17 00:00:00 2001 From: Phoenix / Hotaru Date: Thu, 29 Jun 2023 11:35:24 +0000 Subject: [PATCH] Add Universal2 Support Co-Authored-By: DarthNihilus1 Co-Authored-By: Spotlight --- .github/workflows/actions.yml | 37 ++++++++++++++++++++++---- scripts/macos-universal2/build.sh | 13 +++++++++ scripts/macos-universal2/debloat-qt.py | 30 +++++++++++++++++++++ scripts/macos-universal2/prep-PyQt.sh | 32 ++++++++++++++++++++++ 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 scripts/macos-universal2/build.sh create mode 100644 scripts/macos-universal2/debloat-qt.py create mode 100644 scripts/macos-universal2/prep-PyQt.sh diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index f87ec67..194407b 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -1,11 +1,11 @@ -name: 'Build NSO-RPC' +name: 'Build NSO-RPC - x86_64' on: release: types: [published] jobs: - build: - name: 'Build NSO-RPC' + build-x86_64: + name: 'Build NSO-RPC - x86_64' runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -44,7 +44,7 @@ jobs: run: | cd scripts && python -m pip install pyqt6 && - ./build.sh && + bash ./build.sh && cd ../client/dist && ln -s /Applications "Applications (admin)" && hdiutil create -fs HFS+ -srcfolder . -volname NSO-RPC mac-installer.dmg && @@ -58,9 +58,36 @@ jobs: client/dist/mac-installer.dmg client/dist/mac-portable.zip + build-universal2: + name: 'Build NSO-RPC - Universal2' + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + + # MacOS Build + - name: "Install Python 3.10.11 and build NSO-RPC" + run: | + curl https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg -o python-3.10.11-macos11.pkg + sudo installer -verbose -pkg python-3.10.11-macos11.pkg -target / && + python3.10 -m pip install PyQt6 && + cd scripts/macos-universal2 && + bash ./build.sh && + python3 debloat-qt.py && + cd ../../client/dist && + ln -s /Applications "Applications (admin)" && + hdiutil create -fs HFS+ -srcfolder . -volname NSO-RPC mac-universal2-installer.dmg && + zip -yr mac-universal2-portable.zip NSO-RPC.app/ + + - name: "Upload NSO-RPC Universal2 Build" + uses: softprops/action-gh-release@v0.1.15 + with: + files: | + client/dist/mac-universal2-installer.dmg + client/dist/mac-universal2-portable.zip + get-hashes: runs-on: "ubuntu-latest" - needs: build + needs: ["build-x86_64", "build-universal2"] steps: - name: "Generate checksums.txt" uses: MCJack123/ghaction-generate-release-hashes@v4 diff --git a/scripts/macos-universal2/build.sh b/scripts/macos-universal2/build.sh new file mode 100644 index 0000000..4de02f1 --- /dev/null +++ b/scripts/macos-universal2/build.sh @@ -0,0 +1,13 @@ +#!/bin/bash +python3 -m pip install wheel +bash prep-PyQt.sh +cd ../../client +python3 -m pip install -r requirements.txt py2app +py2applet --make-setup app.py icon.icns "icon.png" "taskbarDark.png" "taskbarLight.png" +# build universal binary +sed -i '' -e "s/)/ name='NSO-RPC')/" setup.py +python3 setup.py py2app -O2 --arch=universal2 +python3 ../scripts/macos-universal2/debloat-qt.py +# arm64 requires codesigning to run +codesign --deep --force --sign - dist/NSO-RPC.app/Contents/MacOS/* +open dist \ No newline at end of file diff --git a/scripts/macos-universal2/debloat-qt.py b/scripts/macos-universal2/debloat-qt.py new file mode 100644 index 0000000..e320581 --- /dev/null +++ b/scripts/macos-universal2/debloat-qt.py @@ -0,0 +1,30 @@ + +import shutil +import os +import sys + +removeFiles = [ + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtQuick3DRuntimeRender.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtQuickParticles.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtSpatialAudio.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtShaderTools.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtQuickTest.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtBluetooth.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtDesigner.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtQuick.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtHelp.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtPdf.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/lib/QtQml.framework", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/plugins/sqldrivers", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/plugins/multimedia", + f"./dist/NSO-RPC.app/Contents/Resources/lib/python{sys.version_info.major}.{sys.version_info.minor}/PyQt6/Qt6/qml", +] + +for file in removeFiles: + try: + rmFile = shutil.rmtree(file) + print(f"Removing: {file}") + except NotADirectoryError: + os.remove(file) + except FileNotFoundError: + pass diff --git a/scripts/macos-universal2/prep-PyQt.sh b/scripts/macos-universal2/prep-PyQt.sh new file mode 100644 index 0000000..df47cbe --- /dev/null +++ b/scripts/macos-universal2/prep-PyQt.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Provided by @spotlightishere on Github +# https://github.com/MCMi460/NSO-RPC/pull/86#issuecomment-1605700512 + +alias python3=python3.10 + +# Download and unpack +python3 -m pip download --only-binary=:all: --platform=macosx_13_0_x86_64 PyQt6_Qt6 +python3 -m pip download --only-binary=:all: --platform=macosx_13_0_arm64 PyQt6_Qt6 +python3 -m wheel unpack PyQt6_*arm64.whl --dest arm64 +python3 -m wheel unpack PyQt6_*x86_64.whl --dest x86_64 + +# We'll use x86_64 as our basis. +# As of writing, PyQt6_Qt6 specifies a minimum of 10.14 for x86_64, and 11.0 for arm64. +# We'll reuse this tag; it should be updated if this ever changes in the future. +python3 -m wheel tags --platform-tag macosx_10_14_universal2 PyQt6_*x86_64.whl +python3 -m wheel unpack PyQt6_*universal2.whl --dest universal + +# https://stackoverflow.com/a/46020381 +merge_frameworks() { + # Remove the leading universal/ from this path. + binary_path="${1##universal/}" + lipo -create -arch x86_64 "x86_64/$binary_path" "arm64/$binary_path" -output "universal/$binary_path" +} +export -f merge_frameworks + +# Iterate through all frameworks and libraries, and lipo together +find universal -perm +111 -type f -exec sh -c 'merge_frameworks "$1"' _ {} \; +python3 -m wheel pack universal/PyQt6_* + +# Finally, install our universal python3.10 -m wheel. +python3 -m pip install PyQt6_*universal2.whl --force-reinstall \ No newline at end of file