157 lines
3.7 KiB
Bash
157 lines
3.7 KiB
Bash
#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
TARGET_ARCH=$(uname -m)
|
|
FFMPEG_SOURCE=${FFMPEG_SOURCE_PATH:-$(command -v ffmpeg)}
|
|
VENDOR_ROOT="$ROOT_DIR/src-tauri/vendor/ffmpeg/macos-$TARGET_ARCH"
|
|
BIN_DIR="$VENDOR_ROOT/bin"
|
|
LIB_DIR="$VENDOR_ROOT/lib"
|
|
MARK_DIR="$VENDOR_ROOT/.processed"
|
|
|
|
rm -rf "$VENDOR_ROOT"
|
|
mkdir -p "$BIN_DIR" "$LIB_DIR" "$MARK_DIR"
|
|
|
|
copy_binary() {
|
|
src_path=$1
|
|
dest_path=$2
|
|
cp -fL "$src_path" "$dest_path"
|
|
chmod 755 "$dest_path"
|
|
}
|
|
|
|
resolve_dep_source() {
|
|
file_path=$1
|
|
dep_path=$2
|
|
|
|
case "$dep_path" in
|
|
/System/*|/usr/lib/*)
|
|
return 1
|
|
;;
|
|
/*)
|
|
if [ -f "$dep_path" ]; then
|
|
printf '%s\n' "$dep_path"
|
|
return 0
|
|
fi
|
|
;;
|
|
@loader_path/*)
|
|
candidate="$(dirname "$file_path")/$(basename "$dep_path")"
|
|
if [ -f "$candidate" ]; then
|
|
printf '%s\n' "$candidate"
|
|
return 0
|
|
fi
|
|
;;
|
|
@executable_path/*)
|
|
candidate="$LIB_DIR/$(basename "$dep_path")"
|
|
if [ -f "$candidate" ]; then
|
|
printf '%s\n' "$candidate"
|
|
return 0
|
|
fi
|
|
;;
|
|
@rpath/*)
|
|
dep_name=$(basename "$dep_path")
|
|
for candidate in \
|
|
"$LIB_DIR/$dep_name" \
|
|
"/opt/homebrew/lib/$dep_name" \
|
|
$(find /opt/homebrew/Cellar -path "*/lib/$dep_name" -print 2>/dev/null)
|
|
do
|
|
if [ -n "$candidate" ] && [ -f "$candidate" ]; then
|
|
printf '%s\n' "$candidate"
|
|
return 0
|
|
fi
|
|
done
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
}
|
|
|
|
marker_path() {
|
|
printf '%s' "$1" | shasum -a 1 | awk '{print "'"$MARK_DIR"'/" $1 ".done"}'
|
|
}
|
|
|
|
process_file() {
|
|
file_path=$1
|
|
loader_prefix=$2
|
|
mark_file=$(marker_path "$file_path")
|
|
|
|
if [ -f "$mark_file" ]; then
|
|
return
|
|
fi
|
|
|
|
: > "$mark_file"
|
|
|
|
otool -L "$file_path" | tail -n +2 | awk '{print $1}' | while read -r dep_path; do
|
|
resolved_dep=$(resolve_dep_source "$file_path" "$dep_path" || true)
|
|
if [ -z "$resolved_dep" ]; then
|
|
continue
|
|
fi
|
|
|
|
dep_name=$(basename "$resolved_dep")
|
|
vendored_dep="$LIB_DIR/$dep_name"
|
|
|
|
if [ ! -f "$vendored_dep" ]; then
|
|
copy_binary "$resolved_dep" "$vendored_dep"
|
|
fi
|
|
|
|
install_name_tool -change "$dep_path" "$loader_prefix/$dep_name" "$file_path"
|
|
process_file "$vendored_dep" "@loader_path"
|
|
done
|
|
|
|
if [ "$loader_prefix" = "@loader_path" ]; then
|
|
install_name_tool -id "@loader_path/$(basename "$file_path")" "$file_path"
|
|
fi
|
|
}
|
|
|
|
normalize_file() {
|
|
file_path=$1
|
|
loader_prefix=$2
|
|
|
|
otool -L "$file_path" | tail -n +2 | awk '{print $1}' | while read -r dep_path; do
|
|
case "$dep_path" in
|
|
/System/*|/usr/lib/*)
|
|
continue
|
|
;;
|
|
@executable_path/*|@loader_path/*)
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
dep_name=$(basename "$dep_path")
|
|
vendored_dep="$LIB_DIR/$dep_name"
|
|
if [ -f "$vendored_dep" ]; then
|
|
install_name_tool -change "$dep_path" "$loader_prefix/$dep_name" "$file_path"
|
|
fi
|
|
done
|
|
|
|
if [ "$loader_prefix" = "@loader_path" ]; then
|
|
install_name_tool -id "@loader_path/$(basename "$file_path")" "$file_path"
|
|
fi
|
|
}
|
|
|
|
sign_file() {
|
|
file_path=$1
|
|
codesign --force --sign - --timestamp=none "$file_path" >/dev/null 2>&1
|
|
}
|
|
|
|
echo "Bundling ffmpeg from: $FFMPEG_SOURCE"
|
|
copy_binary "$FFMPEG_SOURCE" "$BIN_DIR/ffmpeg"
|
|
process_file "$BIN_DIR/ffmpeg" "@executable_path/../lib"
|
|
normalize_file "$BIN_DIR/ffmpeg" "@executable_path/../lib"
|
|
|
|
find "$LIB_DIR" -type f -name '*.dylib' | while read -r dylib_path; do
|
|
normalize_file "$dylib_path" "@loader_path"
|
|
done
|
|
|
|
find "$LIB_DIR" -type f -name '*.dylib' | while read -r dylib_path; do
|
|
normalize_file "$dylib_path" "@loader_path"
|
|
done
|
|
|
|
find "$LIB_DIR" -type f -name '*.dylib' | while read -r dylib_path; do
|
|
sign_file "$dylib_path"
|
|
done
|
|
|
|
sign_file "$BIN_DIR/ffmpeg"
|
|
|
|
echo "Bundled ffmpeg ready at: $VENDOR_ROOT"
|