aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicah Lee <micah@micahflee.com>2023-10-17 15:45:14 -0700
committerMicah Lee <micah@micahflee.com>2023-10-17 15:45:14 -0700
commitf3419e91222cfb29e6cfa788bc10b1c88bba9abd (patch)
tree2226511de76504f834262d15fb58af0eac536b76
parent4936016fd4e2a13ceaf4435b564a78e80610efd7 (diff)
downloadonionshare-f3419e91222cfb29e6cfa788bc10b1c88bba9abd.tar.gz
onionshare-f3419e91222cfb29e6cfa788bc10b1c88bba9abd.zip
Add script to merge Intel and ARM64 Mac app bundles into a universal2 app bundle
-rwxr-xr-xdesktop/scripts/macos-merge-universal.py73
1 files changed, 73 insertions, 0 deletions
diff --git a/desktop/scripts/macos-merge-universal.py b/desktop/scripts/macos-merge-universal.py
new file mode 100755
index 00000000..1c9af52f
--- /dev/null
+++ b/desktop/scripts/macos-merge-universal.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+import os
+import shutil
+import click
+import subprocess
+
+
+def get_binary_arches(app_dir):
+ universal = []
+ silicon = []
+ intel = []
+ for dirpath, dirnames, filenames in os.walk(app_dir):
+ for basename in filenames:
+ filename = os.path.join(dirpath, basename)
+ if os.path.isfile(filename):
+ out = subprocess.check_output(["file", filename]).decode("utf-8")
+ if (
+ "Mach-O 64-bit executable" in out
+ or "Mach-O 64-bit dynamically linked shared library" in out
+ ):
+ arm64, x86 = False, False
+ if "arm64" in out:
+ arm64 = True
+ if "x86_64" in out:
+ x86 = True
+
+ if arm64 and x86:
+ universal.append(filename)
+ elif arm64:
+ silicon.append(filename)
+ elif x86:
+ intel.append(filename)
+
+ return universal, silicon, intel
+
+
+@click.command()
+@click.argument("intel_app", type=click.Path(exists=True))
+@click.argument("silicon_app", type=click.Path(exists=True))
+@click.argument("output_app", type=click.Path(exists=False))
+def main(intel_app, silicon_app, output_app):
+ # Get the list of binaries in each app
+ print("Looking up binaries from Intel app:", intel_app)
+ intel_universal, intel_silicon, intel_intel = get_binary_arches(intel_app)
+ print("Looking up binaries from Silicon app:", silicon_app)
+ silicon_universal, silicon_silicon, silicon_intel = get_binary_arches(silicon_app)
+
+ # Find which binaries should be merged
+ intel_intel_filenames = [i[len(intel_app) + 1 :] for i in intel_intel]
+ silicon_silicon_filenames = [i[len(silicon_app) + 1 :] for i in silicon_silicon]
+ intersection = set(intel_intel_filenames).intersection(
+ set(silicon_silicon_filenames)
+ )
+
+ # Copy the Silicon app to the output app
+ print("Copying the app bundle for the output app")
+ shutil.copytree(silicon_app, output_app, symlinks=True)
+
+ # Merge them
+ for filename in intersection:
+ print(f"Merging {filename}")
+ intel_binary = os.path.join(intel_app, filename)
+ silicon_binary = os.path.join(silicon_app, filename)
+ output_binary = os.path.join(output_app, filename)
+ subprocess.run(
+ ["lipo", "-create", intel_binary, silicon_binary, "-output", output_binary]
+ )
+
+ print(f"Merge complete: {output_app}")
+
+
+if __name__ == "__main__":
+ main()