mirror of
https://github.com/nextcloud/desktop.git
synced 2024-12-19 04:11:50 +03:00
83 lines
3.1 KiB
Python
83 lines
3.1 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
import sys
|
||
|
import os
|
||
|
import subprocess
|
||
|
|
||
|
|
||
|
# A general note: We first produce a x86_64 and a arm64 app package
|
||
|
# and then merge them together instead of compiling the desktop client
|
||
|
# with the CMake option CMAKE_OSX_ARCHITECTURES="x86_64;arm64" because
|
||
|
# macdeployqt can not handle universal binaries well. In the future
|
||
|
# with Qt6 this might change and this script will become obsolete.
|
||
|
|
||
|
|
||
|
def usage(program_name):
|
||
|
print("Creates a universal app package from a x86_64 and a arm64 app package.")
|
||
|
print("Usage: {} x86_64_app_file arm64_app_file output_directory".format(program_name))
|
||
|
print("Example: {} some_dir/Nextcloud.app some_other_dir/Nextcloud.app output_dir".format(program_name))
|
||
|
|
||
|
|
||
|
def execute(command):
|
||
|
return subprocess.check_output(command)
|
||
|
|
||
|
|
||
|
def path_relative_to_package(app_package_file_path, file_path):
|
||
|
if file_path.startswith(app_package_file_path):
|
||
|
relative_path = file_path[len(app_package_file_path):]
|
||
|
if relative_path.startswith("/"):
|
||
|
return relative_path[1:]
|
||
|
return relative_path
|
||
|
return file_path
|
||
|
|
||
|
|
||
|
def is_executable(file_path):
|
||
|
output = str(execute(["file", file_path]))
|
||
|
if (("Mach-O 64-bit dynamically linked shared library" in output)
|
||
|
or ("Mach-O 64-bit executable" in output)):
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
if len(sys.argv) != 4:
|
||
|
usage(sys.argv[0])
|
||
|
sys.exit(1)
|
||
|
|
||
|
x86_64_app_file = sys.argv[1]
|
||
|
if not os.path.exists(x86_64_app_file):
|
||
|
print("Can't create universal: Path {} already exists".format(x86_64_app_file))
|
||
|
sys.exit(1)
|
||
|
arm64_app_file = sys.argv[2]
|
||
|
if not os.path.exists(arm64_app_file):
|
||
|
print("Can't create universal: Path {} already exists".format(arm64_app_file))
|
||
|
sys.exit(1)
|
||
|
output_dir = sys.argv[3]
|
||
|
|
||
|
# Copy the Arm64 variant to the output location if possible
|
||
|
if not os.path.exists(output_dir):
|
||
|
os.makedirs(output_dir)
|
||
|
app_file_name = os.path.basename(arm64_app_file)
|
||
|
universal_app_file = os.path.join(output_dir, app_file_name)
|
||
|
if os.path.exists(universal_app_file):
|
||
|
print("Can't create universal: Path {} already exists".format(universal_app_file))
|
||
|
sys.exit(1)
|
||
|
|
||
|
execute(["cp", "-a", arm64_app_file, output_dir])
|
||
|
|
||
|
# Now walk through the copied arm64 version and replace the binaries
|
||
|
for root, dirs, files in os.walk(universal_app_file):
|
||
|
for f in files:
|
||
|
absoulte_file_path = os.path.join(root, f)
|
||
|
root_relative = path_relative_to_package(universal_app_file, root)
|
||
|
x86_64_absolute_path = os.path.join(x86_64_app_file, root_relative, f)
|
||
|
arm64_absolute_path = os.path.join(arm64_app_file, root_relative, f)
|
||
|
if os.path.islink(absoulte_file_path) or not is_executable(absoulte_file_path):
|
||
|
continue
|
||
|
try:
|
||
|
execute(["lipo", "-create", "-output", absoulte_file_path, arm64_absolute_path, x86_64_absolute_path])
|
||
|
except:
|
||
|
print("Could not merge {} with {} into {}!".format(arm64_absolute_path, x86_64_absolute_path, absoulte_file_path))
|
||
|
|
||
|
print("Finished :)")
|