-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
114 lines (104 loc) · 5.57 KB
/
Copy pathMakefile
File metadata and controls
114 lines (104 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
APP_NAME = HushType
BUILD_DIR = .build/release
BUNDLE_DIR = $(APP_NAME).app
# OpenCC paths (Homebrew on Apple Silicon)
OPENCC_BIN = /opt/homebrew/bin/opencc
OPENCC_LIB_DIR = /opt/homebrew/lib
OPENCC_DATA_DIR = /opt/homebrew/share/opencc
MARISA_LIB_DIR = /opt/homebrew/opt/marisa/lib
.PHONY: build run bundle bundle-opencc install uninstall dmg clean
build:
swift build -c release --disable-sandbox
bash scripts/build_mlx_metallib.sh release
@echo "Build complete: $(BUILD_DIR)/$(APP_NAME)"
run: build
$(BUILD_DIR)/$(APP_NAME)
bundle: build
@mkdir -p "$(BUNDLE_DIR)/Contents/MacOS"
@mkdir -p "$(BUNDLE_DIR)/Contents/Resources"
@cp "$(BUILD_DIR)/$(APP_NAME)" "$(BUNDLE_DIR)/Contents/MacOS/"
@cp "$(BUILD_DIR)/mlx.metallib" "$(BUNDLE_DIR)/Contents/MacOS/" 2>/dev/null || true
@cp Resources/Info.plist "$(BUNDLE_DIR)/Contents/"
@cp Resources/HushType.icns "$(BUNDLE_DIR)/Contents/Resources/" 2>/dev/null || true
@cp scripts/ios_server.py "$(BUNDLE_DIR)/Contents/Resources/" 2>/dev/null || true
@# Strip debug symbols + scrub developer-path leakage from the binary
@# before signing. Two distinct fixes:
@# (a) `strip -S` removes debug symbols.
@# (b) `__FILE__` macro expansions inside Cmlx (MLX's C++ shim) bake
@# absolute paths from the build worktree into the data segment —
@# these survive `strip` because they're runtime-accessible string
@# literals, not debug info. The python step does a length-preserving
@# binary patch: replaces the user-home prefix with `/redacted` + null
@# padding so `strings` returns nothing identifying the developer.
@# Both happen BEFORE codesign because modifying the binary invalidates
@# the signature.
@strip -S "$(BUNDLE_DIR)/Contents/MacOS/$(APP_NAME)" 2>/dev/null || true
@python3 -c "import sys, pathlib; \
binary = pathlib.Path('$(BUNDLE_DIR)/Contents/MacOS/$(APP_NAME)'); \
prefix = b'$(PWD)'; \
data = binary.read_bytes(); \
count = data.count(prefix); \
replacement = b'/redacted' + b'\x00' * (len(prefix) - 9); \
binary.write_bytes(data.replace(prefix, replacement)) if count else None; \
print(f' Scrubbed {count} dev-path occurrence(s) from binary')"
@$(MAKE) bundle-opencc
@# Sign the entire bundle with an explicit stable identifier so macOS TCC
@# tracks accessibility permission by identifier (constant across builds)
@# instead of cdhash (which changes every build). Without this, every
@# `make install` revokes the user's previously-granted permission.
@# --deep is required because Mach-O binaries inside a bundle can't be
@# signed independently — codesign always treats them as part of the
@# enclosing bundle.
@codesign --force --deep --sign - --identifier "com.felix.hushtype" "$(BUNDLE_DIR)"
@echo "Bundle created: $(BUNDLE_DIR) (signed as com.felix.hushtype, debug symbols stripped)"
bundle-opencc:
@echo "Bundling OpenCC..."
@mkdir -p "$(BUNDLE_DIR)/Contents/MacOS/opencc_data"
@# Copy opencc binary
@cp "$(OPENCC_BIN)" "$(BUNDLE_DIR)/Contents/MacOS/opencc"
@# Copy dylibs
@cp "$(OPENCC_LIB_DIR)/libopencc.1.2.dylib" "$(BUNDLE_DIR)/Contents/MacOS/"
@cp "$(MARISA_LIB_DIR)/libmarisa.0.dylib" "$(BUNDLE_DIR)/Contents/MacOS/"
@# Copy data files (dictionaries + configs)
@cp "$(OPENCC_DATA_DIR)"/*.json "$(BUNDLE_DIR)/Contents/MacOS/opencc_data/"
@cp "$(OPENCC_DATA_DIR)"/*.ocd2 "$(BUNDLE_DIR)/Contents/MacOS/opencc_data/"
@# Rewrite dylib paths to use @executable_path
@install_name_tool -change "@rpath/libopencc.1.2.dylib" "@executable_path/libopencc.1.2.dylib" "$(BUNDLE_DIR)/Contents/MacOS/opencc"
@install_name_tool -change "/opt/homebrew/opt/marisa/lib/libmarisa.0.dylib" "@executable_path/libmarisa.0.dylib" "$(BUNDLE_DIR)/Contents/MacOS/opencc"
@install_name_tool -change "/opt/homebrew/opt/marisa/lib/libmarisa.0.dylib" "@executable_path/libmarisa.0.dylib" "$(BUNDLE_DIR)/Contents/MacOS/libopencc.1.2.dylib"
@# Fix libopencc's own id
@install_name_tool -id "@executable_path/libopencc.1.2.dylib" "$(BUNDLE_DIR)/Contents/MacOS/libopencc.1.2.dylib"
@install_name_tool -id "@executable_path/libmarisa.0.dylib" "$(BUNDLE_DIR)/Contents/MacOS/libmarisa.0.dylib"
@# Re-sign after install_name_tool — modifying load commands invalidates the
@# original Homebrew adhoc signature, and macOS Sequoia kills processes with
@# invalid signatures (SIGKILL, no error). Without this step, the bundled
@# opencc fails silently and ChineseConverter falls back to returning the
@# input unchanged. Both `make install` and `make dmg` need this.
@codesign --force --sign - "$(BUNDLE_DIR)/Contents/MacOS/libmarisa.0.dylib"
@codesign --force --sign - "$(BUNDLE_DIR)/Contents/MacOS/libopencc.1.2.dylib"
@codesign --force --sign - "$(BUNDLE_DIR)/Contents/MacOS/opencc"
@echo "OpenCC bundled (binary + dylibs + data files, re-signed)"
install: bundle
@killall $(APP_NAME) 2>/dev/null || true
@rm -rf /Applications/$(BUNDLE_DIR)
@cp -R "$(BUNDLE_DIR)" /Applications/
@echo "Installed to /Applications/$(BUNDLE_DIR)"
@echo "You can now launch HushType from Spotlight (Cmd+Space → HushType)"
uninstall:
@killall $(APP_NAME) 2>/dev/null || true
@rm -rf /Applications/$(BUNDLE_DIR)
@echo "Uninstalled from /Applications"
dmg: bundle
@# OpenCC binaries are already signed in bundle-opencc; just sign the outer bundle.
@echo "Signing app bundle..."
@codesign --force --deep --sign - "$(BUNDLE_DIR)"
@rm -f $(APP_NAME).dmg
@mkdir -p dmg_staging
@cp -R "$(BUNDLE_DIR)" dmg_staging/
@ln -s /Applications dmg_staging/Applications
@hdiutil create -volname "$(APP_NAME)" -srcfolder dmg_staging -ov -format UDZO "$(APP_NAME).dmg"
@rm -rf dmg_staging
@echo "Created $(APP_NAME).dmg"
clean:
swift package clean
rm -rf $(BUNDLE_DIR) $(APP_NAME).dmg