diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0fb452c8..b7e557b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,5 @@ stages: - build - - sign - check .base_windows_build: @@ -50,9 +49,7 @@ standalone_osx: tags: - osx script: - - python3 Tools/build.py -type release -use-aqt -deploy-version -architecture x64 - - python3 Tools/build.py -type release -use-aqt -deploy-version -architecture arm64 - - python3 Tools/macos_lipo.py + - python3 Tools/build.py -type release -use-aqt -deploy-version -sign_osx artifacts: expire_in: "2 weeks" paths: @@ -93,37 +90,7 @@ steam_osx: tags: - osx script: - - python3 Tools/build.py -type release -steam -use-aqt -deploy-version -architecture x64 - - python3 Tools/build.py -type release -steam -use-aqt -deploy-version -architecture arm64 - - python3 Tools/macos_lipo.py - artifacts: - expire_in: "2 weeks" - paths: - - build-universal-osx-release/bin/ - -sign_osx: - stage: sign - needs: ["standalone_osx"] - only: - - release - tags: - - osx - script: - - python3 Tools/macos_sign.py - artifacts: - expire_in: "2 weeks" - paths: - - build-universal-osx-release/bin/ - -sign_osx_steam: - stage: sign - needs: ["steam_osx"] - only: - - release - tags: - - osx - script: - - python3 Tools/macos_sign.py + - python3 Tools/build.py -type release -steam -use-aqt -deploy-version -sign_osx artifacts: expire_in: "2 weeks" paths: diff --git a/.vscode/launch.json b/.vscode/launch.json index 082461d9..fbc77d50 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,3 +1,4 @@ + { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. @@ -5,146 +6,27 @@ "version": "0.2.0", "configurations": [ { - "name": "ScreenPlay Debug", + "name": "Launch Qt 6.5.0", + "type": "cppvsdbg", "request": "launch", - "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], + "program": "${command:cmake.launchTargetPath}", + "args": [], + "cwd": "${command:cmake.buildDirectory}/bin", + "preLaunchTask": "CMake: build", "internalConsoleOptions": "openOnSessionStart", + "environment": [ + { + "name": "Path", + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;${workspaceFolder}\\..\\vcpkg\\installed\\x64-windows\\debug\\bin;" + } + ], "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", - "showDisplayString": true, - "windows": { - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" - } - ], - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlay.exe" - }, "osx": { "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", "type": "lldb" }, "linux": { "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug/bin/ScreenPlay", - "type": "lldb" - } - }, - { - "name": "ScreenPlay RelWithDebInfo", - "request": "launch", - "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "internalConsoleOptions": "openOnSessionStart", - "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", - "showDisplayString": true, - "windows": { - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" - } - ], - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_RelWithDebInfo/bin/ScreenPlay.exe" - }, - "osx": { - "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_RelWithDebInfo/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", - "type": "lldb" - }, - "linux": { - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_RelWithDebInfo/bin/ScreenPlay", - "type": "lldb" - } - }, - { - "name": "ScreenPlayWallpaper Debug", - "request": "launch", - "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "internalConsoleOptions": "openOnSessionStart", - "windows": { - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" - } - ], - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlayWallpaper.exe" - }, - "osx": { - "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", - "type": "lldb" - }, - "linux": { - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug/bin/ScreenPlayWallpaper", - "type": "lldb" - } - }, - { - "name": "ScreenPlayWallpaper RelWithDebInfo", - "request": "launch", - "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "internalConsoleOptions": "openOnSessionStart", - "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", - "showDisplayString": true, - "windows": { - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" - } - ], - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_RelWithDebInfo/bin/ScreenPlayWallpaper.exe" - }, - "osx": { - "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_RelWithDebInfo/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", - "type": "lldb" - }, - "linux": { - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_RelWithDebInfo/bin/ScreenPlayWallpaper", - "type": "lldb" - } - }, - { - "name": "ScreenPlayWidget Debug", - "request": "launch", - "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "internalConsoleOptions": "openOnSessionStart", - "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", - "showDisplayString": true, - "windows": { - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" - } - ], - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlayWidget.exe" - }, - "osx": { - "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget", - "type": "lldb" - }, - "linux": { - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug/bin/ScreenPlayWidget", "type": "lldb" } } diff --git a/CMakeLists.txt b/CMakeLists.txt index 5acec052..7b20f296 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_CXX_STANDARD 20) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) +option(OSX_BUNDLE "Enable distribution macOS bundle" OFF) + # This is needed for OSX: Because we bundle ScreenPlay and ScreenPlayWallpaper into .app they both need other QML dependencies like # ScreenPlayUtil. The fastest way is to use a shared QML module path for development and add this path to the qml engines import pah. For # the SCREENPLAY_DEPLOY we copy them into the matching dirs via the build.py @@ -42,6 +44,11 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) # This subdirectoy is needed for OSX and Linux to fix linker errors because we would have ScreenPlayApp executable and folder for the qml # files in the same directory. set(SCREENPLAY_QML_MODULES_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qml") + +if(APPLE) + set(SCREENPLAY_QML_MODULES_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ScreenPlay.app/Contents/MacOS/qml") +endif() + # Adds the qml import path so QtCreator can find them list(APPEND QML_DIRS "${SCREENPLAY_QML_MODULES_PATH}") set(QML_IMPORT_PATH @@ -113,6 +120,7 @@ if(UNIX AND NOT APPLE) endif() include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/FetchContentThirdParty.cmake) + add_subdirectory(CMake) add_subdirectory(ScreenPlay) add_subdirectory(ScreenPlaySDK) @@ -138,7 +146,7 @@ if(WIN32) add_subdirectory(ScreenPlaySysInfo) endif() -if(${SCREENPLAY_INSTALLER}) +if(${SCREENPLAY_INSTALLER} AND NOT APPLE) include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CreateIFWInstaller.cmake) endif() diff --git a/Docs/macOSSigning.md b/Docs/macOSSigning.md index ab71059c..b5e37d59 100644 --- a/Docs/macOSSigning.md +++ b/Docs/macOSSigning.md @@ -49,14 +49,55 @@ xcrun notarytool store-credentials ``` 1. Profile name: - - Profile name: tachiom + - Profile name: ScreenPlay 2. Path to App Store Connect API private key: - - `/Users/eliassteurer/Documents/AuthKey_xxxxxxx.p8` -3. App Store Connect API Key ID: - - KEY ID at: https://appstoreconnect.apple.com/access/api -4. App Store Connect API Issuer ID: - - USER ID at: https://appstoreconnect.apple.com/access/api + - Path to App Store Connect API private key: `/Users/eliassteurer/Documents/AuthKey_xxxxxxx.p8` +3. App Store go to : https://appstoreconnect.apple.com/access/api + - Klick Keys in the top menu. Then you can answer the next two questions: + - App Store Connect API Key ID: There is a list of `Active` names, generated by. Use this `KEY ID` + - App Store Connect API Issuer ID: Then copy the `Issuer ID` above it + - __IMPORTANT__: The Profile name must match the one set in: + ```xcrun notarytool submit ScreenPlay.app.zip --keychain-profile 'ScreenPlay' --wait``` +Example output: +``` +eliassteurer@Eliass-Mac-mini Tools % xcrun notarytool store-credentials + +This process stores your credentials securely in the Keychain. You reference these credentials later using a profile name. + +Profile name: +xxxxxxx +We recommend using App Store Connect API keys for authentication. If you'd like to authenticate with an Apple ID and app-specific password instead, leave this unspecified. + +Path to App Store Connect API private key: +/Users/xxxxxxxxxx/Documents/AuthKey_xxxxxxxxxxx.p8 +App Store Connect API Key ID: +ScreenPlay +App Store Connect API Issuer ID: +xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +Validating your credentials... +Success. Credentials validated. +Credentials saved to Keychain. +To use them, specify `--keychain-profile "xxxxxxx"` +eliassteurer@Eliass-Mac-mini Tools % --keychain-profile "ScreenPlay" +``` + +## Add your credentials to the system: +See: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow +``` +xcrun notarytool store-credentials "ScreenPlay" + --apple-id "AC_USERNAME" + --team-id + --password +``` +- `AC_USERNAME` = Your email or something you set at AppleID (email): https://appleid.apple.com/account/manage/section/security +https://stackoverflow.com/questions/56890749/macos-notarize-in-script +- `WWDRTeamID` = Go to https://appstoreconnect.apple.com/access/users click on your listed user and copy the `xxxxxxx` from: +``` +Team ID +XXXXXXXXXX View Membership Details +``` +- `password` = Go to https://appleid.apple.com/account/manage/section/security then to `App-specific passwords` and use this password. This will not display you the password, but you can simply remove it, generate a new under the same name and copy the displayed password. ## Get an App-Specific Password https://stackoverflow.com/questions/56890749/macos-notarize-in-script @@ -64,15 +105,11 @@ https://stackoverflow.com/questions/56890749/macos-notarize-in-script security add-generic-password -a "kelteseth@gmail.com" -w "xxxx-xxx-xxx-xxx" -s "Developer ID Application: Elias Steurer (V887LHYKRH)" ``` -## Upload to apple for notization -We use [xcnotary](https://github.com/akeru-inc/xcnotary) tools for fast automatic upload. Install it via brew: - -`brew install akeru-inc/tap/xcnotary` - -Then run it with the -- `*.app` name -- `-d` the developer account email and -- `-k` command is here the keychain name that contains your password from the app password step above! - -`xcnotary notarize ScreenPlay.app -d yourDeveloperAccountEmail@example.com -k ScreenPlay` - +## Troubleshooting +``` +Processing complete +id: xxxxxx-xxxxxx-xxxx-xxxxx-xxxxx +status: Invalid +``` +Run the follwoing if you get an signing error: +`xcrun notarytool log --apple-id "xxxxx@xxxx.com" --password "xxxx-xxxx-xxxx-xxxx" --team-id "xxxxxxxxxxx" ` diff --git a/ScreenPlay/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index fbed1fe5..9c9adc26 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -97,7 +97,8 @@ set(QML qml/Settings/SettingsHeader.qml qml/Settings/SettingsHorizontalSeperator.qml qml/Settings/SettingsPage.qml - qml/Workshop/Workshop.qml) + qml/Workshop/Workshop.qml + qml/TrayIcon.qml) set(TS_FILES # cmake-format: sort @@ -320,7 +321,7 @@ if(${SCREENPLAY_TESTS}) endif() endif() -if(APPLE) +if(APPLE AND NOT OSX_BUNDLE) set_source_files_properties( ${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}.app/Contents/Resources/translations") else() @@ -371,7 +372,31 @@ if(WIN32) endif() -if(APPLE) +if(APPLE AND OSX_BUNDLE) + # Set the installation destination + install(TARGETS "ScreenPlay" DESTINATION /Applications) + + include(InstallRequiredSystemLibraries) + set(CPACK_GENERATOR "Bundle") + set(CPACK_BINARY_DRAGNDROP ON) + set(CPACK_BUNDLE_NAME "ScreenPlay") + set(CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/app.ico") + set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/app.ico") + set(CPACK_BUNDLE_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist") + set(CPACK_BUNDLE_APPLE_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/entitlements.plist") + set(CPACK_PACKAGE_FILE_NAME "ScreenPlay-0.15") + include(CPack) + +# Install all files from /bin +install( + DIRECTORY "${CMAKE_BINARY_DIR}/bin/" + COMPONENT ScreenPlay + DESTINATION "./") + +endif() + + +if(APPLE AND NOT OSX_BUNDLE) # Creates a ScreenPlay.app set_target_properties( ${PROJECT_NAME} diff --git a/ScreenPlay/main.qml b/ScreenPlay/main.qml index 057e0fe5..fffef03f 100644 --- a/ScreenPlay/main.qml +++ b/ScreenPlay/main.qml @@ -14,6 +14,7 @@ import "qml/Monitors" as Monitors import "qml/Installed" as Installed import "qml/Navigation" as Navigation import "qml/Community" as Community +import "qml" ApplicationWindow { id: root @@ -123,7 +124,7 @@ ApplicationWindow { id: monitors modalSource: content } - Util.TrayIcon { + TrayIcon { window: root } } diff --git a/ScreenPlayUtil/qml/TrayIcon.qml b/ScreenPlay/qml/TrayIcon.qml similarity index 100% rename from ScreenPlayUtil/qml/TrayIcon.qml rename to ScreenPlay/qml/TrayIcon.qml diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index 79ff86ca..0985af04 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -200,14 +200,6 @@ void App::init() qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "App", this); m_mainWindowEngine->addImportPath(guiAppInst->applicationDirPath() + "/qml"); -#if defined(Q_OS_OSX) - QDir workingDir(guiAppInst->applicationDirPath()); - workingDir.cdUp(); - workingDir.cdUp(); - workingDir.cdUp(); - // OSX Development workaround: - m_mainWindowEngine->addImportPath(workingDir.path() + "/qml"); -#endif guiAppInst->addLibraryPath(guiAppInst->applicationDirPath() + "/qml"); if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) { diff --git a/ScreenPlay/src/settings.cpp b/ScreenPlay/src/settings.cpp index 36c37689..5ed4bcd3 100644 --- a/ScreenPlay/src/settings.cpp +++ b/ScreenPlay/src/settings.cpp @@ -172,8 +172,8 @@ void Settings::setupWidgetAndWindowPaths() workingDir.cdUp(); } - m_globalVariables->setWidgetExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget").toLocalFile()); - m_globalVariables->setWallpaperExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper").toLocalFile()); + m_globalVariables->setWidgetExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlay.app/Contents/MacOS/ScreenPlayWidget").toLocalFile()); + m_globalVariables->setWallpaperExecutablePath(QUrl::fromUserInput(workingDir.path() + "/ScreenPlay.app/Contents/MacOS/ScreenPlayWallpaper").toLocalFile()); #endif diff --git a/ScreenPlayUtil/CMakeLists.txt b/ScreenPlayUtil/CMakeLists.txt index e094986a..29d23b33 100644 --- a/ScreenPlayUtil/CMakeLists.txt +++ b/ScreenPlayUtil/CMakeLists.txt @@ -36,8 +36,7 @@ set(QML qml/Slider.qml qml/Tag.qml qml/TagSelector.qml - qml/TextField.qml - qml/TrayIcon.qml) + qml/TextField.qml) set(SOURCES # cmake-format: sort diff --git a/ScreenPlayWallpaper/CMakeLists.txt b/ScreenPlayWallpaper/CMakeLists.txt index ed8ca604..fab78551 100644 --- a/ScreenPlayWallpaper/CMakeLists.txt +++ b/ScreenPlayWallpaper/CMakeLists.txt @@ -91,15 +91,18 @@ if(UNIX AND NOT APPLE) endif() if(APPLE) - set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa") - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/${PROJECT_NAME}.app/Contents/MacOS/) - add_custom_command( - TARGET ${PROJECT_NAME} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/index.html - ${CMAKE_BINARY_DIR}/bin/${PROJECT_NAME}.app/Contents/MacOS/) - + if(NOT OSX_BUNDLE) + add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/index.html + ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/) + set_target_properties(${PROJECT_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/" + ) + endif() endif() if(WIN32) diff --git a/ScreenPlayWallpaper/Info.plist b/ScreenPlayWallpaper/Info.plist deleted file mode 100644 index b214e4cb..00000000 --- a/ScreenPlayWallpaper/Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ScreenPlayWallpaper - CFBundleIconFile - - CFBundleIdentifier - app.screen-play.wallpaper - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ScreenPlayWallpaper - CFBundlePackageType - APPL - CFBundleDisplayName - ScreenPlayWallpaper - CFBundleVersion - 0.15 - CFBundleShortVersionString - 0.15 - NSUIElement - 1 - LSUIElement - 1 - - diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 5e22ae6e..d486146d 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -24,7 +24,7 @@ int main(int argc, char* argv[]) { #if !defined(Q_OS_LINUX) - qputenv("QT_MEDIA_BACKEND", "windows"); + qputenv("QT_MEDIA_BACKEND", "ffmpeg"); #endif QGuiApplication::setAttribute(Qt::AA_ShareOpenGLContexts); diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 570d9657..f554aeae 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -1,10 +1,13 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "macwindow.h" +#include "ScreenPlayUtil/macutils.h" #include ScreenPlay::WallpaperExitCode MacWindow::start() { + + MacUtils::showDockIcon(false); auto* screen = QGuiApplication::screens().at(activeScreensList().at(0)); m_window.setGeometry(screen->geometry()); @@ -14,14 +17,10 @@ ScreenPlay::WallpaperExitCode MacWindow::start() connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &MacWindow::destroyThis); } - QDir workingDir(QGuiApplication::instance()->applicationDirPath()); - workingDir.cdUp(); - workingDir.cdUp(); - workingDir.cdUp(); // OSX Development workaround: // This folder needs then to be copied into the .app/Contents/MacOS/ // for the deploy version. - m_window.engine()->addImportPath(workingDir.path() + "/qml"); + m_window.engine()->addImportPath(QGuiApplication::instance()->applicationDirPath()+ "/qml"); // WARNING: Setting Window flags must be called *here*! Qt::WindowFlags flags = m_window.flags(); diff --git a/ScreenPlayWidget/CMakeLists.txt b/ScreenPlayWidget/CMakeLists.txt index 1dbbb37b..25d80238 100644 --- a/ScreenPlayWidget/CMakeLists.txt +++ b/ScreenPlayWidget/CMakeLists.txt @@ -76,6 +76,9 @@ if(WIN32) set_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true) endif() -if(APPLE) - set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) -endif() +if(APPLE AND NOT OSX_BUNDLE) + set_target_properties(${PROJECT_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/" + ) +endif() \ No newline at end of file diff --git a/ScreenPlayWidget/Info.plist b/ScreenPlayWidget/Info.plist deleted file mode 100644 index d211bca3..00000000 --- a/ScreenPlayWidget/Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ScreenPlayWidget - CFBundleIconFile - - CFBundleIdentifier - app.screen-play.widget - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ScreenPlayWidget - CFBundlePackageType - APPL - CFBundleDisplayName - ScreenPlayWidget - CFBundleVersion - 0.15 - CFBundleShortVersionString - 0.15 - NSUIElement - 1 - LSUIElement - 1 - - diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index 49f9590a..081beea6 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -10,6 +10,9 @@ #if defined(Q_OS_WIN) Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin) #endif +#if defined(Q_OS_OSX) +#include "ScreenPlayUtil/macutils.h" +#endif Q_IMPORT_QML_PLUGIN(ScreenPlayWeatherPlugin) @@ -57,6 +60,8 @@ int main(int argc, char* argv[]) argumentList.at(2), // AppID argumentList.at(3), // Type QPoint { positionX, positionY }); - +#if defined(Q_OS_OSX) + MacUtils::showDockIcon(false); +#endif return app.exec(); } diff --git a/ScreenPlayWorkshop/CMakeLists.txt b/ScreenPlayWorkshop/CMakeLists.txt index a04385c0..b7981fa6 100644 --- a/ScreenPlayWorkshop/CMakeLists.txt +++ b/ScreenPlayWorkshop/CMakeLists.txt @@ -122,7 +122,7 @@ qt_add_qml_module( ${RESOURCES}) if(${SCREENPLAY_STEAM}) - if(APPLE) + if(APPLE AND NOT OSX_BUNDLE) set(MACOS_FRAMEWORKS_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ScreenPlay.app/Contents/MacOS/) file(MAKE_DIRECTORY ${MACOS_FRAMEWORKS_DIR}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${MACOS_FRAMEWORKS_DIR} COPYONLY) diff --git a/Tools/build.py b/Tools/build.py index 6129289d..3eed883f 100755 --- a/Tools/build.py +++ b/Tools/build.py @@ -11,15 +11,15 @@ import defines from typing import Tuple from shutil import copytree from pathlib import Path -from util import sha256, cd_repo_root_path, zipdir, run, get_vs_env_dict +from macos_lipo import run_lipo, check_fat_binary +import macos_sign +from util import sha256, cd_repo_root_path,repo_root_path, zipdir, run, get_vs_env_dict from sys import stdout stdout.reconfigure(encoding='utf-8') def clean_build_dir(build_dir): - if isinstance(build_dir, str): - build_dir = Path(build_dir) if build_dir.exists(): print(f"Remove previous build folder: {build_dir}") # ignore_errors removes also not empty folders... @@ -49,6 +49,7 @@ class BuildConfig: cmake_osx_architectures: str cmake_target_triplet: str package: bool + osx_bundle: str package_command: str executable_file_ending: str # qt_* use either aqt or from the maintenance tool @@ -71,6 +72,7 @@ class BuildConfig: build_type: str build_architecture: str create_installer: str + sign_osx: bool def execute( @@ -80,12 +82,13 @@ def execute( # Make sure the script is always started from the same folder build_config.root_path = cd_repo_root_path() - build_result = BuildResult() + if platform.system() == "Darwin": + build_config.build_architecture = "x64" + build_config.cmake_target_triplet = "x64-osx" + build_config.cmake_osx_architectures = "-DCMAKE_OSX_ARCHITECTURES=x86_64" # Sets all platform spesific paths, arguments etc. - setup_tuple = setup(build_config, build_result) - build_config = setup_tuple[0] - build_result = setup_tuple[1] + [build_config, build_result] = setup(build_config) build_result.build = Path(build_config.build_folder) build_result.bin = Path(build_config.bin_dir) @@ -94,13 +97,40 @@ def execute( # 3rd party tools like the crashreporter create local # temporary files in the build directory. clean_build_dir(build_config.build_folder) - - + # Runs cmake configure and cmake build step_time = time.time() build_result = build(build_config, build_result) build_duration = time.time() - step_time - print(f"⏱️ build_duration: {build_duration}s") + print(f"⏱️ build_duration (for {build_config.build_architecture}): {build_duration}s") + + if platform.system() == "Darwin": + # Make sure the script is always started from the same folder + build_config.root_path = cd_repo_root_path() + + # Swap the architecture for the second build + build_config.build_architecture = "arm64" + build_config.cmake_target_triplet = "arm64-osx" + build_config.cmake_osx_architectures = "-DCMAKE_OSX_ARCHITECTURES=arm64" + + # Sets all platform spesific paths, arguments etc. + [build_config, build_result] = setup(build_config) + + build_result.build = Path(build_config.build_folder) + build_result.bin = Path(build_config.bin_dir) + + + # Make sure to always delete everything first. + # 3rd party tools like the crashreporter create local + # temporary files in the build directory. + clean_build_dir(build_config.build_folder) + + step_time = time.time() + build_result = build(build_config, build_result) + build_duration = time.time() - step_time + print(f"⏱️ Second build_duration (for {build_config.build_architecture}): {build_duration}s") + + # Copies all needed libraries and assets into the bin folder step_time = time.time() @@ -108,6 +138,7 @@ def execute( package_duration = time.time() - step_time print(f"⏱️ package_duration: {package_duration}s") + # Creates a Qt InstallerFrameWork (IFW) installer if build_config.create_installer == "ON": step_time = time.time() @@ -134,8 +165,8 @@ def execute( return build_result -def setup(build_config: BuildConfig, build_result: BuildResult) -> Tuple[BuildConfig, BuildResult]: - +def setup(build_config: BuildConfig) -> Tuple[BuildConfig, BuildResult]: + build_result = BuildResult() build_config.qt_path = defines.QT_PATH if not build_config.qt_path.exists(): @@ -143,11 +174,9 @@ def setup(build_config: BuildConfig, build_result: BuildResult) -> Tuple[BuildCo exit(2) build_config.qt_bin_path = Path(build_config.qt_path).joinpath(f"{build_config.qt_version}/{defines.QT_PLATFORM}").resolve() build_config.ifw_root_path = Path(f"{build_config.qt_path}/Tools/QtInstallerFramework/{build_config.qt_ifw_version}").resolve() - - # Set default to empty for linux and windows, because it is only used on mac - build_config.cmake_osx_architectures = "" if platform.system() == "Windows": + build_config.cmake_osx_architectures = "" build_config.cmake_target_triplet = "x64-windows" build_config.executable_file_ending = ".exe" env_dict = get_vs_env_dict() @@ -162,22 +191,14 @@ def setup(build_config: BuildConfig, build_result: BuildResult) -> Tuple[BuildCo build_config.aqt_install_tool_packages = "windows desktop tools_ifw" elif platform.system() == "Darwin": - if(build_config.build_architecture == "arm64"): - build_config.cmake_target_triplet = "arm64-osx" - build_config.cmake_osx_architectures = "-DCMAKE_OSX_ARCHITECTURES=arm64" - elif(build_config.build_architecture == "x64"): - build_config.cmake_target_triplet = "x64-osx" - build_config.cmake_osx_architectures = "-DCMAKE_OSX_ARCHITECTURES=x86_64" - else: - print("MISSING BUILD ARCH: SET arm64 or x64") - exit(1) build_config.executable_file_ending = ".app" # NO f string we fill it later! - build_config.package_command = "{prefix_path}/bin/macdeployqt {app}.app -qmldir=../../{app}/qml -executable={app}.app/Contents/MacOS/{app} -appstore-compliant" + #build_config.package_command = "{prefix_path}/bin/macdeployqt ScreenPlay.app -qmldir=../../{app}/qml -executable=ScreenPlay.app/Contents/MacOS/{app} -appstore-compliant -timestamp -hardened-runtime" build_config.aqt_install_qt_packages = f"mac desktop {build_config.qt_version} clang_64 -m all" build_config.aqt_install_tool_packages = "mac desktop tools_ifw" elif platform.system() == "Linux": + build_config.cmake_osx_architectures = "" build_config.cmake_target_triplet = "x64-linux" build_config.executable_file_ending = "" build_config.aqt_install_qt_packages = f"linux desktop {build_config.qt_version} gcc_64 -m all" @@ -192,21 +213,16 @@ def setup(build_config: BuildConfig, build_result: BuildResult) -> Tuple[BuildCo print(f"Starting build with type {build_config.build_type}.") print(f"Qt Version: {build_config.qt_version}. Root path: {build_config.root_path}") - # Remove old build folder to before configuring to get rid of - # all cmake chaches - build_config.build_folder = build_config.root_path.joinpath( - f"build-{build_config.cmake_target_triplet}-{build_config.build_type}") + # Remove old build folder to before configuring to get rid of all cmake chaches + build_config.build_folder = build_config.root_path.joinpath(f"build-{build_config.cmake_target_triplet}-{build_config.build_type}") build_config.bin_dir = build_config.build_folder.joinpath("bin") if platform.system() == "Windows": - build_result.installer = Path(build_config.build_folder).joinpath( - "ScreenPlay-Installer.exe") + build_result.installer = Path(build_config.build_folder).joinpath("ScreenPlay-Installer.exe") elif platform.system() == "Darwin": - build_result.installer = Path(build_config.build_folder).joinpath( - "ScreenPlay-Installer.dmg") + build_result.installer = Path(build_config.build_folder).joinpath("ScreenPlay.dmg") elif platform.system() == "Linux": - build_result.installer = Path(build_config.build_folder).joinpath( - "ScreenPlay-Installer.run") + build_result.installer = Path(build_config.build_folder).joinpath("ScreenPlay-Installer.run") return build_config, build_result @@ -239,7 +255,36 @@ def build(build_config: BuildConfig, build_result: BuildResult) -> BuildResult: def package(build_config: BuildConfig): - if platform.system() == "Windows" or platform.system() == "Darwin": + if platform.system() == "Darwin": + universal_build_dir = Path(os.path.join(repo_root_path(), "build-universal-osx-release")) + if universal_build_dir.exists(): + print(f"Remove previous build folder: {universal_build_dir}") + # ignore_errors removes also not empty folders... + shutil.rmtree(universal_build_dir, ignore_errors=True) + + # Make sure to reset to tools path + os.chdir(repo_root_path()) + # Create universal (fat) binary + run_lipo() + check_fat_binary() + + cmd_raw = "{qt_bin_path}/macdeployqt {build_bin_dir}/ScreenPlay.app -qmldir={repo_root_path}/{app}/qml -executable={build_bin_dir}/ScreenPlay.app/Contents/MacOS/{app} -verbose=1 -appstore-compliant -timestamp -hardened-runtime " # -sign-for-notarization=\"Developer ID Application: Elias Steurer (V887LHYKRH)\" + build_bin_dir = Path(repo_root_path()).joinpath("build-universal-osx-release/bin/") + cwd = Path(repo_root_path()).joinpath("build-universal-osx-release/bin/ScreenPlay.app/Contents/MacOS/") + qt_bin_path = Path(defines.QT_BIN_PATH).resolve() + source_path = Path(repo_root_path()).resolve() + + run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path,repo_root_path=source_path, build_bin_dir=build_bin_dir, app="ScreenPlay"), cwd=cwd) + run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path,repo_root_path=source_path, build_bin_dir=build_bin_dir, app="ScreenPlayWallpaper"), cwd=cwd) + run(cmd=cmd_raw.format(qt_bin_path=qt_bin_path,repo_root_path=source_path, build_bin_dir=build_bin_dir, app="ScreenPlayWidget"), cwd=cwd) + + if(build_config.sign_osx): + build_config.bin_dir = os.path.join(repo_root_path(),'build-universal-osx-release/bin/') + print(f"Sign binary at: {build_config.bin_dir}") + macos_sign.sign(build_config=build_config) + + + if platform.system() == "Windows": print("Executing deploy commands...") run(build_config.package_command.format( type=build_config.build_type, @@ -258,7 +303,8 @@ def package(build_config: BuildConfig): prefix_path=build_config.qt_bin_path, app="ScreenPlayWallpaper", executable_file_ending=build_config.executable_file_ending), cwd=build_config.bin_dir) - else: + + if platform.system() == "Linux": # Copy all .so files from the qt_bin_path lib folder into bin_dir qt_lib_path = build_config.qt_bin_path for file in qt_lib_path.joinpath("lib").glob("*.so"): @@ -294,18 +340,7 @@ def package(build_config: BuildConfig): shutil.copy(str(file), str(build_config.bin_dir)) print("Copied %s" % file) - # Copy qml dir into all .app/Contents/MacOS/ - if platform.system() == "Darwin": - qml_plugins_path = Path.joinpath(build_config.bin_dir, "qml") - copytree(qml_plugins_path, Path.joinpath( - build_config.bin_dir, "ScreenPlay.app/Contents/MacOS/qml")) - copytree(qml_plugins_path, Path.joinpath( - build_config.bin_dir, "ScreenPlayWallpaper.app/Contents/MacOS/qml")) - copytree(qml_plugins_path, Path.joinpath( - build_config.bin_dir, "ScreenPlayWidget.app/Contents/MacOS/qml")) - print(f"Deleting qml plugins path: {qml_plugins_path}") - shutil.rmtree(qml_plugins_path) # Some dlls like openssl do no longer get copied automatically. # Lets just copy all of them into bin. @@ -324,19 +359,7 @@ def package(build_config: BuildConfig): qt6Widgets_path = Path(qt_bin_path).joinpath("Qt6Widgets.dll").resolve() print(f"⚠️WORKAROUND: Copy Qt6Widgets.dll from: {qt6Widgets_path}") shutil.copy2(qt6Widgets_path, build_config.bin_dir) - qt_qml_Qt_plugin_path = Path(qt_bin_path).joinpath("./../qml/Qt").resolve() - qt_qml_Qt_plugin_target_path = Path(build_config.bin_dir).joinpath("Qt").resolve() - print(f"⚠️WORKAROUND: Copy qml folder from: {qt_qml_Qt_plugin_path}, to {qt_qml_Qt_plugin_target_path}") - shutil.copytree(str(qt_qml_Qt_plugin_path), str(qt_qml_Qt_plugin_target_path)) - if platform.system() == "Darwin": - # ⚠️WORKAROUND. REMOVE ME WHEN FIXED: - # https://bugreports.qt.io/browse/QTBUG-110937 - qt_bin_path = defines.QT_BIN_PATH - qt_qml_Qt_plugin_path = Path(qt_bin_path).joinpath("./../qml/Qt").resolve() - qt_qml_Qt_plugin_target_path = Path(build_config.bin_dir).joinpath("ScreenPlay.app/Contents/Resources/qml/Qt").resolve() - print(f"⚠️WORKAROUND: Copy qml folder from: {qt_qml_Qt_plugin_path}, to {qt_qml_Qt_plugin_target_path}") - shutil.copytree(str(qt_qml_Qt_plugin_path), str(qt_qml_Qt_plugin_target_path)) if not platform.system() == "Darwin": file_endings = [".ninja_deps", ".ninja", ".ninja_log", ".lib", ".a", ".exp", @@ -389,7 +412,7 @@ if __name__ == "__main__": help="Overwrites the default Qt version") parser.add_argument('-qt-installer-version', action="store", dest="qt_installer_version_overwrite", help="Overwrites the default Qt installer framework version") - parser.add_argument('-type', action="store", dest="build_type", + parser.add_argument('-type', action="store", dest="build_type", default="release", help="Build type. This is either debug or release.") parser.add_argument('-use-aqt', action="store_true", dest="use_aqt", help="Absolute qt path. If not set the default path is used\Windows: C:\Qt\nLinux & macOS:~/Qt/.") @@ -399,9 +422,11 @@ if __name__ == "__main__": help="Build tests.") parser.add_argument('-installer', action="store_true", dest="create_installer", help="Create a installer.") + parser.add_argument('-sign_osx', action="store_true", dest="sign_osx", default=False, + help="Signs the executable on macOS. This requires a valid Apple Developer ID set up.") parser.add_argument('-deploy-version', action="store_true", dest="build_deploy", help="Create a deploy version of ScreenPlay for sharing with the world. A not deploy version is for local development only!") - parser.add_argument('-architecture', action="store", dest="build_architecture", + parser.add_argument('-architecture', action="store", dest="build_architecture", default="", help="Sets the build architecture. Used to build x86 and ARM osx versions. Currently only works with x86_64 and arm64") args = parser.parse_args() @@ -419,11 +444,6 @@ if __name__ == "__main__": qt_ifw_version = args.qt_installer_version_overwrite print("Using Qt installer framework version {qt_ifw_version}") - if not args.build_type: - parser.print_help() - print("\n\nBuild type argument is missing (release, debug). E.g: python build.py -type release -steam\n\n") - exit(1) - build_type = args.build_type build_steam = "OFF" @@ -455,5 +475,6 @@ if __name__ == "__main__": build_config.build_type = build_type build_config.screenplay_version = screenplay_version build_config.build_architecture = args.build_architecture + build_config.sign_osx = args.sign_osx execute(build_config) diff --git a/Tools/build_and_publish.py b/Tools/build_and_publish.py index 266a9197..4bb18431 100644 --- a/Tools/build_and_publish.py +++ b/Tools/build_and_publish.py @@ -12,7 +12,7 @@ from macos_lipo import run_lipo, check_fat_binary import platform import paramiko import defines -from util import sftp_exists +from util import sftp_exists, run, repo_root_path from sys import stdout stdout.reconfigure(encoding='utf-8') @@ -47,36 +47,14 @@ if __name__ == "__main__": if platform.system() == "Darwin" and not args.skip_build: # We do not yet support a standalone osx installer build_config.create_installer = "OFF" - # OSX builds needs to build for x86 and arm - # and also be signed! # We need to manually package here at the end after - # we run build_config.package = True + build_config.sign_osx = True - # Remove old build-universal-osx-release dir that does not automatically - # deleted because it is not build directly but generated from x64 and arm64 - universal_build_dir = Path(os.path.join(root_path, "build-universal-osx-release")) - if universal_build_dir.exists(): - print(f"Remove previous build folder: {universal_build_dir}") - # ignore_errors removes also not empty folders... - shutil.rmtree(universal_build_dir, ignore_errors=True) - - build_config.build_architecture = "arm64" + # This will build both arm64 and x64 and sign the unversal binary build_result = build.execute(build_config) - build_config.build_architecture = "x64" - build_result = build.execute(build_config) - - # Make sure to reset to tools path - os.chdir(root_path) - # Create universal (fat) binary - run_lipo() - check_fat_binary() - - build_config.bin_dir = os.path.join(build_config.root_path,'build-universal-osx-release/bin/') - print(f"Change binary dir to: {build_config.bin_dir}") - macos_sign.sign(build_config=build_config) if platform.system() == "Windows" and not args.skip_build: build_config.build_architecture = "x64" @@ -117,6 +95,10 @@ if __name__ == "__main__": print("Skip publishing.") sys.exit(0) + if args.steam_password is None: + print("Steam password is required.") + sys.exit(1) + # Make sure to reset to tools path os.chdir(tools_path) steam_publish.publish( diff --git a/Tools/defines.py b/Tools/defines.py index ae370ee3..58611333 100644 --- a/Tools/defines.py +++ b/Tools/defines.py @@ -3,6 +3,7 @@ import sys from pathlib import Path from sys import stdout +import os stdout.reconfigure(encoding='utf-8') @@ -18,7 +19,7 @@ elif sys.platform == "linux": QT_PLATFORM = "gcc_64" SCREENPLAY_VERSION = "0.15.0-RC5" -QT_PATH = Path.cwd().parent.parent.joinpath("aqt") +QT_PATH = path = Path(os.path.join(os.path.realpath(__file__), "../../../aqt")).resolve() QT_VERSION = "6.5.0" QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin") QT_TOOLS_PATH = QT_PATH.joinpath("Tools/") diff --git a/Tools/macos_lipo.py b/Tools/macos_lipo.py index e6f4035f..617cc54b 100644 --- a/Tools/macos_lipo.py +++ b/Tools/macos_lipo.py @@ -36,9 +36,9 @@ def run_lipo() : apps = ["ScreenPlay","ScreenPlayWallpaper", "ScreenPlayWidget"] for app in apps: - arm64_dir = str(Path.joinpath(root_path, f"build-arm64-osx-release/bin/{app}.app/Contents/MacOS/{app}")) - x64_dir = str(Path.joinpath(root_path, f"build-x64-osx-release/bin/{app}.app/Contents/MacOS/{app}")) - universal_dir = str(Path.joinpath(root_path, f"build-universal-osx-release/bin/{app}.app/Contents/MacOS/{app}")) + arm64_dir = str(Path.joinpath(root_path, f"build-arm64-osx-release/bin/ScreenPlay.app/Contents/MacOS/{app}")) + x64_dir = str(Path.joinpath(root_path, f"build-x64-osx-release/bin/ScreenPlay.app/Contents/MacOS/{app}")) + universal_dir = str(Path.joinpath(root_path, f"build-universal-osx-release/bin/ScreenPlay.app/Contents/MacOS/{app}")) run(f"lipo -create {arm64_dir} {x64_dir} -output {universal_dir}") run(f"lipo -info {universal_dir}") diff --git a/Tools/macos_sign.py b/Tools/macos_sign.py index e521b915..6a1f9ab3 100644 --- a/Tools/macos_sign.py +++ b/Tools/macos_sign.py @@ -3,55 +3,46 @@ from build import BuildConfig from util import run from sys import stdout +import time stdout.reconfigure(encoding='utf-8') def sign(build_config: BuildConfig): print("Run codedesign") - run("codesign --deep -f -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --timestamp --options \"runtime\" -f --entitlements \"../../ScreenPlay/entitlements.plist\" --deep \"ScreenPlay.app/\"", - cwd=build_config.bin_dir) - run("codesign --deep -f -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --timestamp --options \"runtime\" -f --deep \"ScreenPlayWallpaper.app/\"", - cwd=build_config.bin_dir) - run("codesign --deep -f -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --timestamp --options \"runtime\" -f --deep \"ScreenPlayWidget.app/\"", + #run("codesign -f -s 'Developer ID Application: Elias Steurer (V887LHYKRH)' --verbose --force --timestamp --options 'runtime' -f --entitlements '../../ScreenPlay/entitlements.plist' 'ScreenPlay.app/' ", + # cwd=build_config.bin_dir) + # Do not use --deep https://developer.apple.com/forums/thread/129980 + # base_sign_command = "codesign -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --verbose --force --timestamp --options \"runtime\" \"ScreenPlay.app/Contents/MacOS/{app}\"" + # run(base_sign_command.format(app="ffmpeg"), cwd=build_config.bin_dir) + # run(base_sign_command.format(app="ffprobe"), cwd=build_config.bin_dir) + run("codesign --deep -s \"Developer ID Application: Elias Steurer (V887LHYKRH)\" --verbose --force --timestamp --options \"runtime\" --entitlements \"../../ScreenPlay/entitlements.plist\" \"ScreenPlay.app/\"", cwd=build_config.bin_dir) print("Run codedesign verify") - run("codesign --verify --verbose=4 \"ScreenPlay.app/\"", - cwd=build_config.bin_dir) - run("codesign --verify --verbose=4 \"ScreenPlayWallpaper.app/\"", - cwd=build_config.bin_dir) - run("codesign --verify --verbose=4 \"ScreenPlayWidget.app/\"", + run("codesign --verify --verbose=4 'ScreenPlay.app/'", cwd=build_config.bin_dir) - # TODO: Replace with https://github.com/akeru-inc/xcnotary/issues/22#issuecomment-1179170957 - # ditto -c -k --keepParent "ScreenPlay.app" "ScreenPlay.app.zip" # Note the profile is the one name of the first step of (App Store Connect API) in the macOSSigning.md # xcrun notarytool submit "ScreenPlay.app.zip" --keychain-profile "ScreenPlay" --wait # xcrun stapler staple "ScreenPlay.app" print("Packing .apps for upload") run("ditto -c -k --keepParent 'ScreenPlay.app' 'ScreenPlay.app.zip'", cwd=build_config.bin_dir) - run("ditto -c -k --keepParent 'ScreenPlayWallpaper.app' 'ScreenPlayWallpaper.app.zip'", cwd=build_config.bin_dir) - run("ditto -c -k --keepParent 'ScreenPlayWidget.app' 'ScreenPlayWidget.app.zip'", cwd=build_config.bin_dir) - + + # run this if you get an error: + # `xcrun notarytool log --apple-id "xxxxx@xxxx.com" --password "xxxx-xxxx-xxxx-xxxx" --team-id "xxxxxxxxxxx" ` + # Processing complete + # id: xxxxxx-xxxxxx-xxxx-xxxxx-xxxxx + # status: Invalid print("Run xcnotary submit") - run("xcrun notarytool submit ScreenPlay.app.zip --keychain-profile 'ScreenPlay' --wait", cwd=build_config.bin_dir) - run("xcrun notarytool submit ScreenPlayWallpaper.app.zip --keychain-profile 'ScreenPlay' --wait", cwd=build_config.bin_dir) - run("xcrun notarytool submit ScreenPlayWidget.app.zip --keychain-profile 'ScreenPlay' --wait", cwd=build_config.bin_dir) + run("xcrun notarytool submit --keychain-profile 'ScreenPlay' ScreenPlay.app.zip --wait", cwd=build_config.bin_dir) print("Run stapler staple") run("xcrun stapler staple ScreenPlay.app", cwd=build_config.bin_dir) - run("xcrun stapler staple ScreenPlayWallpaper.app", cwd=build_config.bin_dir) - run("xcrun stapler staple ScreenPlayWidget.app", cwd=build_config.bin_dir) - print("Run spctl assess") - run("spctl --assess --verbose \"ScreenPlay.app/\"", cwd=build_config.bin_dir) - run("spctl --assess --verbose \"ScreenPlayWallpaper.app/\"", cwd=build_config.bin_dir) - run("spctl --assess --verbose \"ScreenPlayWidget.app/\"", cwd=build_config.bin_dir) + run("spctl --assess --verbose 'ScreenPlay.app/'", cwd=build_config.bin_dir) print("Remove *.app.zip files.") run("rm ScreenPlay.app.zip", cwd=build_config.bin_dir) - run("rm ScreenPlayWallpaper.app.zip", cwd=build_config.bin_dir) - run("rm ScreenPlayWidget.app.zip", cwd=build_config.bin_dir) # We also need to sign the installer in osx: diff --git a/Tools/steam_publish.py b/Tools/steam_publish.py index 05bfec4b..2385cc92 100644 --- a/Tools/steam_publish.py +++ b/Tools/steam_publish.py @@ -82,6 +82,7 @@ def publish( tmp_steam_config_dir = os.path.abspath(os.path.join(tools_path,tmp_steam_config_foldername)) if os.path.isdir(tmp_steam_config_dir): + print(f"Deleting tmp config {tmp_steam_config_dir}") shutil.rmtree(tmp_steam_config_dir) os.mkdir(tmp_steam_config_dir)