1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-05 10:32:28 +01:00

Update macos build scripts

This commit is contained in:
Elias Steurer 2022-07-22 13:21:30 +02:00
parent 376e96f96c
commit 3a917c18c4
7 changed files with 198 additions and 59 deletions

View File

@ -11,10 +11,15 @@
- Select `Developer ID Application`
- _This certificate is used to code sign your app for distribution outside of the Mac App Store._
## Adding an existing certificate
1. Go to https://developer.apple.com/account/resources/certificates/download
1. Download `Developer ID Application`
2. Add certificate `System`
## Sign the app locally with codesign
We need to sign every single file in the .app file. For this we use the name from the installed cert. This can be copied from the `Keychain Access.app`.
`codesign --deep -f -s "Developer ID Application: Elias Steurer (AAABCXYZAA)" --options "runtime" "ScreenPlay.app/"`
`codesign --deep -f -s "Developer ID Application: Elias Steurer (V887LHYKRH)" --options "runtime" "ScreenPlay.app/"`
## Upload to apple for notization
We use [xcnotary](https://github.com/akeru-inc/xcnotary) tools for fast automatic upload. Install it via brew:

View File

@ -110,6 +110,7 @@ def build(
deploy_command: str = ""
executable_file_ending: str = ""
qt_path: str = ""
qt_bin_path: str = ""
aqt_install_qt_packages: str = ""
aqt_install_tool_packages: str = ""
cmake_target_triplet: str = ""
@ -120,11 +121,12 @@ def build(
cmake_target_triplet = "x64-windows"
windows_msvc = "msvc2019_64"
executable_file_ending = ".exe"
qt_path = aqt_path.joinpath(qt_version).joinpath(
qt_path = aqt_path if use_aqt else Path("C:/Qt")
qt_bin_path = aqt_path.joinpath(qt_version).joinpath(
windows_msvc) if use_aqt else Path(f"C:/Qt/{qt_version}/{windows_msvc}")
vs_env_dict = get_vs_env_dict()
vs_env_dict["PATH"] = vs_env_dict["PATH"] + \
";" + str(qt_path) + "\\bin"
";" + str(qt_bin_path) + "\\bin"
os.environ.update(vs_env_dict)
deploy_command = "windeployqt.exe --{type} --qmldir ../../{app}/qml {app}{executable_file_ending}"
@ -134,10 +136,13 @@ def build(
elif platform.system() == "Darwin":
if(build_architecture == "arm64"):
cmake_target_triplet = "arm64-osx"
else:
elif(build_architecture == "x64"):
cmake_target_triplet = "x64-osx"
qt_path = aqt_path.joinpath(
else:
print("MISSING BUILD ARCH: SET arm64 or x64")
exit(1)
qt_path = aqt_path if use_aqt else Path("~/Qt/")
qt_bin_path = aqt_path.joinpath(
f"{qt_version}/macos") if use_aqt else Path(f"~/Qt/{qt_version}/macos")
deploy_command = "{prefix_path}/bin/macdeployqt {app}.app -qmldir=../../{app}/qml -executable={app}.app/Contents/MacOS/{app}"
@ -146,7 +151,8 @@ def build(
elif platform.system() == "Linux":
cmake_target_triplet = "x64-linux"
qt_path = aqt_path.joinpath(
qt_path = aqt_path if use_aqt else Path("~/Qt/")
qt_bin_path = aqt_path.joinpath(
f"{qt_version}/gcc_64") if use_aqt else Path(f"~/Qt/{qt_version}/gcc_64")
aqt_install_qt_packages = f"linux desktop {qt_version} gcc_64 -m all"
aqt_install_tool_packages = "linux desktop tools_ifw"
@ -155,7 +161,7 @@ def build(
else:
print("cqtdeployer not available, build may be incomplete and incompatible with some distro (typically Ubuntu)")
home_path = str(Path.home())
qt_path = aqt_path.joinpath(
qt_bin_path = aqt_path.joinpath(
f"{qt_version}/gcc_64") if use_aqt else Path(f"{home_path}/Qt/{qt_version}/gcc_64")
else:
raise NotImplementedError(
@ -163,7 +169,7 @@ def build(
# Default to QtMaintainance installation.
if use_aqt:
print(f"qt_path: {qt_path}.")
print(f"qt_bin_path: {qt_bin_path}.")
if not Path(aqt_path).exists():
print(
f"aqt path does not exist at {aqt_path}. Installing now into...")
@ -173,11 +179,18 @@ def build(
# Prepare
cmake_toolchain_file = f"'{root_path}/../ScreenPlay-vcpkg/scripts/buildsystems/vcpkg.cmake'"
ifw_root_path = f"{qt_path}\\Tools\\QtInstallerFramework\\{qt_ifw_version}"
ifw_root_path = f"{qt_path}/Tools/QtInstallerFramework/{qt_ifw_version}"
print(f"cmake_toolchain_file: {cmake_toolchain_file}")
print(
f"Starting build with type {build_type}. Qt Version: {qt_version}. Root path: {root_path}")
# Remove old build folder to before configuring to get rid of
# all cmake chaches
build_folder = root_path.joinpath(
f"build-{cmake_target_triplet}-{build_type}")
clean_build_dir(build_folder)
CMAKE_OSX_ARCHITECTURES: str = ""
# The entire parameter should be optional. We need this to explicity build
# x84 and arm version seperat, only because we cannot compile two at once with vcpkg
@ -186,7 +199,7 @@ def build(
cmake_configure_command = f'cmake ../ \
{CMAKE_OSX_ARCHITECTURES} \
-DCMAKE_PREFIX_PATH={qt_path} \
-DCMAKE_PREFIX_PATH={qt_bin_path} \
-DCMAKE_BUILD_TYPE={build_type} \
-DVCPKG_TARGET_TRIPLET={cmake_target_triplet} \
-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file} \
@ -198,9 +211,6 @@ def build(
-G "CodeBlocks - Ninja" \
-B.'
build_folder = root_path.joinpath(
f"build-{cmake_target_triplet}-{build_type}")
clean_build_dir(build_folder)
# Build
start_time = time.time()
@ -215,56 +225,56 @@ def build(
print("Executing deploy commands...")
run(deploy_command.format(
type=build_type,
prefix_path=qt_path,
prefix_path=qt_bin_path,
app="ScreenPlay",
executable_file_ending=executable_file_ending), cwd=bin_dir)
run(deploy_command.format(
type=build_type,
prefix_path=qt_path,
prefix_path=qt_bin_path,
app="ScreenPlayWidget",
executable_file_ending=executable_file_ending), cwd=bin_dir)
run(deploy_command.format(
type=build_type,
prefix_path=qt_path,
prefix_path=qt_bin_path,
app="ScreenPlayWallpaper",
executable_file_ending=executable_file_ending), cwd=bin_dir)
else:
# just copy the folders and be done with it
if platform.system() == "Linux":
# Copy all .so files from the qt_path lib folder into bin_dir
qt_lib_path = qt_path
# Copy all .so files from the qt_bin_path lib folder into bin_dir
qt_lib_path = qt_bin_path
for file in qt_lib_path.joinpath("lib").glob("*.so"):
shutil.copy(str(file), str(bin_dir))
# Copy qt_qml_path folder content into bin_dir
qt_qml_path = qt_path
qt_qml_path = qt_bin_path
for folder in qt_qml_path.joinpath("qml").iterdir():
if not folder.is_file():
shutil.copytree(str(folder), str(
bin_dir.joinpath(folder.name)))
print("Copied %s" % folder)
# Copy all plugin folder from qt_path plugins subfolder into bin_dir
qt_plugins_path = qt_path
for folder in qt_path.joinpath("plugins").iterdir():
# Copy all plugin folder from qt_bin_path plugins subfolder into bin_dir
qt_plugins_path = qt_bin_path
for folder in qt_bin_path.joinpath("plugins").iterdir():
if not folder.is_file():
shutil.copytree(str(folder), str(
bin_dir.joinpath(folder.name)))
print("Copied %s" % folder)
# Copy all folder from qt_path translation files into bin_dir translation folder
qt_translations_path = qt_path
# Copy all folder from qt_bin_path translation files into bin_dir translation folder
qt_translations_path = qt_bin_path
for folder in qt_translations_path.joinpath("translations").iterdir():
if not folder.is_file():
shutil.copytree(str(folder), str(
bin_dir.joinpath("translations").joinpath(folder.name)))
print("Copied %s" % folder)
# Copy all filesfrom qt_path resources folder into bin_dir folder
qt_resources_path = qt_path
for file in qt_path.joinpath("resources").glob("*"):
# Copy all filesfrom qt_bin_path resources folder into bin_dir folder
qt_resources_path = qt_bin_path
for file in qt_bin_path.joinpath("resources").glob("*"):
shutil.copy(str(file), str(bin_dir))
print("Copied %s" % file)

View File

@ -1,8 +1,10 @@
import build
from build import build
import steam_publish
import argparse
import os
from pathlib import Path
from macos_lipo import run_lipo, check_fat_binary
import platform
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Build and Package ScreenPlay')
@ -12,21 +14,57 @@ if __name__ == "__main__":
# Script needs to run in the tools folder
tools_path = Path.cwd()
os.chdir(tools_path)
build(
qt_version="6.4.0",
qt_ifw_version="4.4",
build_steam="ON",
build_tests="OFF",
build_release="ON",
create_installer="ON",
build_type="release",
sign_build=False,
use_aqt=False
)
root_path = tools_path.parent
print(f"Set root directory to: {root_path}")
if platform.system() == "Darwin":
# OSX builds needs to build for x86 and arm
# and also be signed!
build(
qt_version="6.4.0",
qt_ifw_version="4.4",
build_steam="ON",
build_tests="OFF",
build_release="ON",
create_installer="ON",
build_type="release",
sign_build=True,
use_aqt=False,
build_architecture = "arm64"
)
build(
qt_version="6.4.0",
qt_ifw_version="4.4",
build_steam="ON",
build_tests="OFF",
build_release="ON",
create_installer="OFF",
build_type="release",
sign_build=True,
use_aqt=False,
build_architecture = "x64"
)
# Make sure to reset to tools path
os.chdir(root_path)
# Create universal (fat) binary
run_lipo()
check_fat_binary()
else:
build(
qt_version="6.4.0",
qt_ifw_version="4.4",
build_steam="ON",
build_tests="OFF",
build_release="ON",
create_installer="OFF",
build_type="release",
sign_build=False,
use_aqt=False
)
# Make sure to reset to tools path
os.chdir(tools_path)
steam_publish(
steam_username="tachiom",
steam_password=args.steam_password,
set_live_branch_name="internal"
)
#steam_publish(
# steam_username="tachiom",
# steam_password=args.steam_password,
# set_live_branch_name="internal"
#)

88
Tools/macos_lipo.py Normal file
View File

@ -0,0 +1,88 @@
#!/usr/bin/python3
import platform
import os
import subprocess
import shutil
import argparse
import time
import zipfile
from shutil import copytree
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
from util import run
def listfiles(path):
files = []
extensions = ('.dylib', '.so','')
ignored = ('qmldir')
print(f"WALK: {path}")
for dirName, subdirList, fileList in os.walk(path):
dir = dirName.replace(path, '')
for fname in fileList:
if Path(fname).suffix in extensions and not fname in ignored:
file = path + os.path.join(dir, fname)
if(os.path.isfile(file)):
print(file)
files.append(file)
return files
def create_fat_binary():
# Make sure the script is always started from the same folder
root_path = Path.cwd()
if root_path.name == "Tools":
root_path = root_path.parent
print(f"Change root directory to: {root_path}")
os.chdir(root_path)
arm64_dir = 'build-arm64-osx-release/bin/ScreenPlay.app'
x64_dir = "build-x64-osx-release/bin/ScreenPlay.app"
arm64_files = listfiles(
str(Path.joinpath(root_path, arm64_dir)))
x64_files = listfiles(str(Path.joinpath(root_path, x64_dir)))
for file in arm64_files:
run(f"lipo -info {file}")
# print(arm64_files)
# print(x64_files)
def run_lipo():
# Make sure the script is always started from the same folder
root_path = Path.cwd()
if root_path.name == "Tools":
root_path = root_path.parent
print(f"Change root directory to: {root_path}")
os.chdir(root_path)
shutil.copytree(str(Path.joinpath(root_path, "build-arm64-osx-release/bin/")) ,
str(Path.joinpath(root_path, "build-universal-osx-release/bin/")) )
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}"))
run(f"lipo -create {arm64_dir} {x64_dir} -output {universal_dir}")
run(f"lipo -info {universal_dir}")
def check_fat_binary():
# Make sure the script is always started from the same folder
root_path = Path.cwd()
if root_path.name == "Tools":
root_path = root_path.parent
print(f"Change root directory to: {root_path}")
os.chdir(root_path)
dir = 'build-universal-osx-release/bin/'
files = listfiles(str(Path.joinpath(root_path, dir)))
for file in files:
run(f"lipo -info {file}")
if __name__ == "__main__":
run_lipo()
check_fat_binary()
#create_fat_binary()

View File

@ -5,7 +5,7 @@
// include all files recursively
"FileMapping"
{
"LocalPath" "build-x64-osx-release/bin/*"
"LocalPath" "build-universal-osx-release/bin/*"
"DepotPath" "."
"recursive" "1"
}

View File

@ -1,13 +0,0 @@
"DepotBuildConfig"
{
"DepotID" "672872"
// include all files recursively
"FileMapping"
{
"LocalPath" "build-arm64-osx-release/bin/*"
"DepotPath" "."
"recursive" "1"
}
}

11
Tools/util.py Normal file
View File

@ -0,0 +1,11 @@
from pathlib import Path
import os
import subprocess
def run(cmd, cwd=Path.cwd()):
result = subprocess.run(cmd, shell=True, cwd=cwd)
if result.returncode != 0:
raise RuntimeError(f"Failed to execute {cmd}")