Skip to content

Commit d1a4c17

Browse files
committed
fix macos-deploy script
- use pkg-config instead of brew to lookup libdir - bundle zlib if needed - fix libzstd references in lem executable - bundle tree-sitter vterm, and zstd
1 parent 15eb7c4 commit d1a4c17

File tree

2 files changed

+125
-35
lines changed

2 files changed

+125
-35
lines changed

.github/workflows/nightly-builds.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ jobs:
111111
- name: Set up Common Lisp environment
112112
if: steps.diff.outputs.skip != 'true'
113113
run: |
114-
brew install sbcl tree-sitter
114+
brew install sbcl tree-sitter libvterm pkg-config openssl@3
115115
curl -O https://beta.quicklisp.org/quicklisp.lisp
116116
sbcl --non-interactive --load quicklisp.lisp --eval "(quicklisp-quickstart:install)"
117117
curl -L https://qlot.tech/installer | sh

scripts/macos-deploy.bash

Lines changed: 124 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,176 @@
1-
#!/usr/bin/env bash -ex
1+
#!/usr/bin/env bash
22
# scripts/macos-deploy.bash
33

4-
set -o pipefail
4+
set -euxo pipefail
5+
6+
BUILD_DIR=build
7+
BIN_DIR=bin
8+
APP="$BIN_DIR/lem.app"
9+
EXE="$APP/Contents/MacOS/lem"
10+
LIBDIR="$APP/Contents/MacOS"
511

612
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
713
parent_dir="$(dirname "$script_dir")"
814
cd "$parent_dir"
915

10-
# ===== 1) ビルド =====
16+
# ===== 0) クリーンアップ =====
17+
# ===== 0) Cleanup =====
18+
rm -rf "$BUILD_DIR"
19+
rm -rf "$BIN_DIR"
20+
mkdir -p "$BUILD_DIR"
21+
mkdir -p "$BIN_DIR"
22+
23+
# ===== 1) ビルド用SBCLの準備 =====
24+
# ===== 1) Prepare SBCL for building =====
25+
# SBCLはlibzstdに依存しており、実行ファイル(lem)はその共有依存関係を継承します。
26+
# SBCLのダンプ構造のため、実行ファイルに対してinstall_name_toolは機能しません。
27+
# そのため、代わりにSBCL実行ファイルのコピーに対してdylib参照を置換する必要があります。
28+
# SBCL depends on libzstd and the app executable (lem) inherits those shared deps
29+
# `install_name_tool` doesn't work on the app executable because of the SBCL dump structure so
30+
# we have to replace dylib references on a copy of the sbcl executable instead
31+
SBCL_BIN=$(realpath "$(which sbcl)")
32+
SBCL_HOME="$(dirname "$SBCL_BIN")/../lib/sbcl"
33+
# Homebrew uses a shell script so we have to find the real executable
34+
if [[ $(file "$SBCL_BIN") == *"shell script"* ]]; then
35+
SBCL_ROOT="$(dirname "$(dirname "$SBCL_BIN")")"
36+
SBCL_BIN="$SBCL_ROOT/libexec/bin/sbcl"
37+
SBCL_HOME="$SBCL_ROOT/lib/sbcl"
38+
fi
39+
install -m 0755 "$SBCL_BIN" "$BUILD_DIR/sbcl"
40+
export SBCL_HOME
41+
42+
LIBZSTD_DIR="$(pkg-config --variable=libdir libzstd)"
43+
install -m 0755 "$LIBZSTD_DIR/libzstd.1.dylib" "$BUILD_DIR/libzstd.1.dylib"
44+
install_name_tool -id @loader_path/libzstd.1.dylib "$BUILD_DIR/libzstd.1.dylib"
45+
install_name_tool -change "$LIBZSTD_DIR/libzstd.1.dylib" @loader_path/libzstd.1.dylib "$BUILD_DIR/sbcl"
46+
47+
codesign --force --sign - "$BUILD_DIR/libzstd.1.dylib"
48+
codesign --force --sign - --preserve-metadata=entitlements,requirements "$BUILD_DIR/sbcl"
49+
50+
# ===== 2) ビルド =====
51+
# ===== 2) Build =====
1152
qlot install
12-
qlot exec sbcl --eval '(ql:quickload :lem)' --eval '(asdf:make :lem)'
53+
PATH="$PWD/build:$PATH" qlot exec sbcl --eval '(ql:quickload :lem)' --eval '(asdf:make :lem)'
1354

1455
# アイコン(存在しなくても続行)
15-
cp resources/lem.png bin/lem.app/Contents/Resources/ || true
16-
17-
# ===== 2) OpenSSL を同梱し、参照先を @loader_path 化 =====
18-
APP="bin/lem.app"
19-
EXE="$APP/Contents/MacOS/lem"
20-
LIBDIR="$APP/Contents/MacOS"
56+
# Icon (Continue even if it does not exist)
57+
install -m 0644 resources/lem.png "$APP/Contents/Resources/" || true
2158

59+
# ===== 3) OpenSSL を同梱し、参照先を @loader_path 化 =====
60+
# ===== 3) Bundle OpenSSL and convert reference targets to @loader_path =====
2261
if [[ ! -x "$EXE" ]]; then
2362
echo "error: executable not found: $EXE" >&2
2463
exit 1
2564
fi
2665

27-
if ! command -v brew >/dev/null 2>&1; then
28-
echo "error: Homebrew not found. Install brew before packaging." >&2
66+
if ! command -v pkg-config >/dev/null 2>&1; then
67+
echo "error: pkg-config not found. Install pkg-config before packaging." >&2
2968
exit 1
3069
fi
3170

32-
OPENSSL_PREFIX="$(brew --prefix openssl@3)"
33-
OPENSSL_LIB="$OPENSSL_PREFIX/lib"
71+
# deploy によって追加されたライブラリを削除
72+
# Remove libs added by deploy
73+
rm "$LIBDIR"/libtree-sitter.*.dylib || true
74+
rm "$LIBDIR"/libzstd.*.dylib || true
75+
76+
OPENSSL_LIB="$(pkg-config --variable=libdir openssl)"
3477

3578
# Cellar の実体(バージョン付きディレクトリ)を解決
79+
# Resolve the actual path in the Cellar (versioned directory)
3680
LIBCRYPTO_REAL="$(realpath "$OPENSSL_LIB/libcrypto.3.dylib")"
37-
LIBSSL_REAL="$(realpath "$OPENSSL_LIB/libssl.3.dylib")"
3881

3982
# deploy が同名を置いている場合もあるので上書き
40-
cp -f "$OPENSSL_LIB/libssl.3.dylib" "$LIBDIR/libssl.3.dylib"
41-
cp -f "$OPENSSL_LIB/libcrypto.3.dylib" "$LIBDIR/libcrypto.3.dylib"
83+
# Overwrite because deploy may have placed a file with the same name
84+
install -m 0755 "$OPENSSL_LIB/libssl.3.dylib" "$LIBDIR/libssl.3.dylib"
85+
install -m 0755 "$OPENSSL_LIB/libcrypto.3.dylib" "$LIBDIR/libcrypto.3.dylib"
4286

4387
# dylib 自身の ID を @loader_path に揃える
88+
# Align the dylib's own ID to @loader_path
4489
install_name_tool -id @loader_path/libssl.3.dylib "$LIBDIR/libssl.3.dylib"
4590
install_name_tool -id @loader_path/libcrypto.3.dylib "$LIBDIR/libcrypto.3.dylib"
4691

4792
# libssl → libcrypto の参照を絶対パスから置換
93+
# Replace libssl -> libcrypto references from absolute paths
4894
# 1) Cellar 実体パス
95+
# 1) Cellar resolved path
4996
install_name_tool -change "$LIBCRYPTO_REAL" @loader_path/libcrypto.3.dylib "$LIBDIR/libssl.3.dylib" || true
5097
# 2) opt 経由のパス
98+
# 2) Path via opt
5199
install_name_tool -change "$OPENSSL_LIB/libcrypto.3.dylib" @loader_path/libcrypto.3.dylib "$LIBDIR/libssl.3.dylib" || true
52100
# 3) @rpath の場合も @loader_path に寄せる(冪等)
101+
# 3) Also shift @rpath cases to @loader_path (idempotent)
53102
install_name_tool -change @rpath/libcrypto.3.dylib @loader_path/libcrypto.3.dylib "$LIBDIR/libssl.3.dylib" || true
54103

55-
# 互換用シンボリックリンク(無印名で探すケースに備える)
56-
( cd "$LIBDIR" && { ln -sf libssl.3.dylib libssl.dylib; ln -sf libcrypto.3.dylib libcrypto.dylib; } )
104+
# 必要に応じて zlib を同梱 (MacPorts の OpenSSL は zlib に依存するため)
105+
# Bundle zlib if needed (MacPorts OpenSSL depends on zlib)
106+
if otool -L "$LIBDIR/libssl.3.dylib" "$LIBDIR/libcrypto.3.dylib" | grep -q "libz"; then
107+
ZLIB_DIR="$(pkg-config --variable=libdir zlib)"
108+
install -m 0755 "$ZLIB_DIR/libz.1.dylib" "$LIBDIR/libz.1.dylib"
109+
110+
# libz 自身の ID を @loader_path に変更
111+
# Change libz's own ID to @loader_path
112+
install_name_tool -id @loader_path/libz.1.dylib "$LIBDIR/libz.1.dylib"
113+
114+
# libssl/libcrypto からの参照を置換
115+
# Replace references from libssl/libcrypto
116+
install_name_tool -change "$ZLIB_DIR/libz.1.dylib" @loader_path/libz.1.dylib "$LIBDIR/libssl.3.dylib" || true
117+
install_name_tool -change "$ZLIB_DIR/libz.1.dylib" @loader_path/libz.1.dylib "$LIBDIR/libcrypto.3.dylib" || true
118+
fi
119+
120+
# tree-sitter を同梱
121+
# Bundle tree-sitter
122+
LIBTREE_SITTER_DIR="$(pkg-config --variable=libdir tree-sitter)"
123+
install -m 0755 "$LIBTREE_SITTER_DIR/libtree-sitter.0.dylib" "$LIBDIR/libtree-sitter.0.dylib"
124+
125+
# vterm を同梱
126+
# Bundle vterm
127+
VTERM_DIR="$(pkg-config --variable=libdir vterm)"
128+
install -m 0755 "$VTERM_DIR/libvterm.0.dylib" "$LIBDIR/libvterm.0.dylib"
129+
130+
# zstd を同梱
131+
# Bundle zstd
132+
install -m 0755 "$BUILD_DIR/libzstd.1.dylib" "$LIBDIR/libzstd.1.dylib"
133+
134+
# dylib の自認パス (ID) を @loader_path に変更
135+
# Change dylib IDs to @loader_path
136+
install_name_tool -id @loader_path/libtree-sitter.0.dylib "$LIBDIR/libtree-sitter.0.dylib"
137+
install_name_tool -id @loader_path/libts-wrapper.dylib "$LIBDIR/libts-wrapper.dylib"
138+
install_name_tool -id @loader_path/libvterm.0.dylib "$LIBDIR/libvterm.0.dylib"
139+
install_name_tool -id @loader_path/libwebview.0.12.dylib "$LIBDIR/libwebview.dylib"
140+
install_name_tool -id @loader_path/terminal.so "$LIBDIR/terminal.so"
141+
142+
# dylib の参照先を @loader_path に変更
143+
# Change dylib references to @loader_path
144+
install_name_tool -change /opt/homebrew/opt/tree-sitter/lib/libtree-sitter.0.26.dylib @loader_path/libtree-sitter.0.dylib "$LIBDIR/libts-wrapper.dylib"
145+
install_name_tool -change /opt/homebrew/opt/libvterm/lib/libvterm.0.dylib @loader_path/libvterm.0.dylib "$LIBDIR/terminal.so"
57146

58147
# 実行ファイル(lem)は SBCL のダンプ構造のため install_name_tool は当てない
148+
# Do not apply install_name_tool to the executable (lem) because of the SBCL dump structure
59149

60-
# ===== 3) 署名(必須ではないが念のため。失敗しても続行) =====
61-
codesign --force --sign - --timestamp=none "$LIBDIR/libcrypto.3.dylib" || true
62-
codesign --force --sign - --timestamp=none "$LIBDIR/libssl.3.dylib" || true
63-
codesign --force --deep --sign - --timestamp=none "$APP" || true
150+
# ===== 4) 署名(必須ではないが念のため。失敗しても続行) =====
151+
# ===== 4) Signing (Not required, but just in case. Continue even if it fails) =====
152+
codesign --force --sign - "$LIBDIR/libcrypto.3.dylib" || true
153+
codesign --force --sign - "$LIBDIR/libssl.3.dylib" || true
154+
codesign --force --deep --sign - "$APP" || true
64155

65-
# ===== 4) 検査(絶対パスが残っていないか) =====
66-
echo "== otool -L libssl.3.dylib =="
67-
otool -L "$LIBDIR/libssl.3.dylib" | sed 's/^/ /'
68-
echo "== otool -L libcrypto.3.dylib =="
69-
otool -L "$LIBDIR/libcrypto.3.dylib" | sed 's/^/ /'
156+
# ===== 5) 検査(絶対パスが残っていないか) =====
157+
# ===== 5) Inspection (Check if any absolute paths remain) =====
158+
echo "== otool -L * =="
159+
otool -L "$LIBDIR"/* | sed 's/^/ /'
70160

71-
if otool -L "$LIBDIR/libssl.3.dylib" | grep -q '/opt/homebrew' \
72-
|| otool -L "$LIBDIR/libcrypto.3.dylib" | grep -q '/opt/homebrew'; then
73-
echo "error: absolute Homebrew paths remain in libssl/libcrypto. Fixing failed." >&2
161+
if otool -L "$LIBDIR"/* | grep -q '/opt'; then
162+
echo "error: absolute paths remain in lem executable or bundled dylibs. Fixing failed." >&2
74163
exit 1
75164
fi
76165

77-
# ===== 5) 配布用 ZIP =====
166+
# ===== 6) 配布用 ZIP =====
167+
# ===== 6) ZIP for distribution =====
78168
README_PATH="bin/README.md"
79-
echo "The following command must be executed for lem.app to start.
169+
echo 'The following command must be executed for lem.app to start.
80170
```
81171
xattr -dr com.apple.quarantine lem.app/
82172
```
83-
" > "$README_PATH"
173+
' > "$README_PATH"
84174

85175
rm -f lem-macos.zip
86176
(

0 commit comments

Comments
 (0)