Skip to content

Commit c6abdbd

Browse files
committed
bump to 1.11.0
1 parent e2e2adb commit c6abdbd

2 files changed

Lines changed: 93 additions & 1 deletion

File tree

.github/workflows/build.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ jobs:
2222
uses: actions/setup-python@v5
2323
with:
2424
python-version: '3.13'
25+
- name: Clean and strip binaries
26+
run: python3 ci.py
2527
- name: Tag folder
2628
run: touch Universal-Binaries/.signed
2729
- name: Build DMG
@@ -37,7 +39,7 @@ jobs:
3739
with:
3840
files: deploy/*
3941
tag_name: 1.10.1
40-
name: 1.10.0 Tahoe Test
42+
name: 1.11.0
4143
body: ${{ github.event.head_commit.message }}
4244
prerelease: false
4345
generate_release_notes: true

cin.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""
2+
Postprocess binaries on CI
3+
"""
4+
5+
# TODO: We need a proper way to identify and sign bundles. Unfortunately Apple does not make this easy.
6+
7+
import subprocess
8+
import sys
9+
from pathlib import Path
10+
11+
# Configurable options
12+
13+
IDENTITY = "hackdoc"
14+
TARGET_DIR = Path("Universal-Binaries")
15+
UNUSED = [
16+
# Mojave and Catalina non-Metal Patches
17+
# No longer used by us, but nice for reference
18+
"10.13.6-18",
19+
"10.13.6-19",
20+
"10.14.4-18",
21+
"10.14.4-19",
22+
"10.14.6-19",
23+
# Nvidia Web Driver Patches
24+
# Remove .pkg, unused by patcher
25+
"WebDriver-387.10.10.10.40.140/WebDriver-387.10.10.10.40.140.pkg",
26+
"WebDriver-387.10.10.10.40.140/WebDriver-387.10.10.15.15.108.pkg",
27+
]
28+
29+
# Constants
30+
31+
MACHO_MAGIC = {
32+
"MH_MAGIC": b"\xfe\xed\xfa\xce",
33+
"MH_CIGAM": b"\xce\xfa\xed\xfe",
34+
"MH_MAGIC_64": b"\xfe\xed\xfa\xcf",
35+
"MH_CIGAM_64": b"\xcf\xfa\xed\xfe",
36+
"FAT_MAGIC": b"\xbe\xba\xfe\xca",
37+
"FAT_CIGAM": b"\xca\xfe\xba\xbe",
38+
}
39+
40+
41+
def clean_unused():
42+
"""
43+
Remove unused files and folders
44+
"""
45+
46+
for path in UNUSED:
47+
path = TARGET_DIR / path
48+
if path.exists():
49+
print(f"Removing: {path}")
50+
subprocess.check_output(["rm", "-rf", path])
51+
52+
for path in TARGET_DIR.rglob(".DS_Store"):
53+
print(f"Removing: {path}")
54+
path.unlink()
55+
56+
57+
def get_machos(directory=TARGET_DIR):
58+
"""
59+
Get all machos in a directory
60+
"""
61+
62+
machos: dict[Path, bytes] = {}
63+
for file in directory.rglob("*"):
64+
if not file.is_file() or file.is_symlink():
65+
continue
66+
with file.open("rb") as f:
67+
magic = f.read(4)
68+
if magic in MACHO_MAGIC.values():
69+
machos[file] = magic
70+
return dict(sorted(machos.items(), key=lambda item: item[0]))
71+
72+
73+
def thin_macho(file: Path, magic: bytes):
74+
"""
75+
Run lipo to thin a fat macho
76+
"""
77+
78+
if magic in (MACHO_MAGIC["FAT_MAGIC"], MACHO_MAGIC["FAT_CIGAM"]):
79+
subprocess.check_output(["lipo", "-thin", "x86_64", "-output", file, file])
80+
81+
82+
if __name__ == "__main__":
83+
clean_unused()
84+
machos = get_machos()
85+
if not machos:
86+
print("No machos found!")
87+
sys.exit(1)
88+
for macho, magic in machos.items():
89+
thin_macho(macho, magic)
90+
print("Done!")

0 commit comments

Comments
 (0)