Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Packing Script #17

Merged
merged 9 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions .github/dylib_packer.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#!/bin/zsh

# Define the fixed array of GStreamer libraries
GSTREAMER_LIBS=(
"libgstapplemedia"
"libgstasf"
"libgstaudioconvert"
"libgstaudioparsers"
"libgstaudioresample"
"libgstavi"
"libgstcoreelements"
"libgstdebug"
"libgstdeinterlace"
"libgstid3demux"
"libgstisomp4"
"libgstlibav"
"libgstopengl"
"libgstplayback"
"libgsttypefindfunctions"
"libgstvideoconvertscale"
"libgstvideofilter"
"libgstvideoparsersbad"
"libgstwavparse"
)

# Global array to store all discovered dylibs, with unique entries only
typeset -aU all_dylibs
# Queue for iterative processing
typeset -a queue

# Function to resolve @rpath dependencies by searching in Homebrew's lib directory
resolve_rpath() {
local ref_dylib="$1"

# Extract the actual filename after @rpath
local dylib_name="${ref_dylib#@rpath/}"

# Get Homebrew's lib directory
local brew_lib_dir="$(brew --prefix)/lib"

# Check if the dylib exists in Homebrew's lib directory
local resolved_path="${brew_lib_dir}/${dylib_name}"
if [[ -f "$resolved_path" ]]; then
echo "$resolved_path"
else
# If not found, return empty string to avoid trying to open unresolved @rpath
echo ""
fi
}

# Function to find all dylib dependencies iteratively
find_dylib_dependencies() {
local dylib="$1"

# Initialize the queue with the initial dylib
queue+=("$dylib")

# Process each dylib in the queue
while [[ ${#queue[@]} -gt 0 ]]; do
local current_dylib="${queue[1]}"
queue=("${queue[@]:1}") # Remove the first element from the queue

# Get all referenced dylibs using otool
local referenced_dylibs=($(otool -L "$current_dylib" | awk '/^\t/ {print $1}' | grep '\.dylib'))

for ref_dylib in $referenced_dylibs; do
# Skip /usr/lib dylibs
if [[ "$ref_dylib" == /usr/lib/* ]]; then
continue
fi

# Resolve @rpath references by looking in Homebrew's lib directory
if [[ "$ref_dylib" == @rpath/* ]]; then
ref_dylib=$(resolve_rpath "$ref_dylib")
# Skip if @rpath couldn't be resolved
if [[ -z "$ref_dylib" ]]; then
echo "Warning: Could not resolve @rpath for $current_dylib" >&2
continue
fi
fi

# If the dylib is not already in the global array, add it to the array and the queue
if [[ ! " ${all_dylibs[*]} " =~ " $ref_dylib " ]]; then
all_dylibs+=("$ref_dylib")
queue+=("$ref_dylib")
fi
done
done
}

# Function to fix up brew dylib LCs
update_dylib_paths() {
local dylib_file="$1"
local path_prefix="$2"
echo "Processing $dylib_file..."

otool -L "$dylib_file" | grep -v "$dylib_file" | awk '{print $1}' | while read -r dylib_path; do
if [[ $dylib_path != /usr/lib* && $dylib_path != /System/* ]]; then
# For paths not excluded, replace the prefix with @loader_path/
local lib_name="${dylib_path##*/}"
local new_dylib_path="${path_prefix}${lib_name}"
echo "Updating $dylib_path to $new_dylib_path"
# Use install_name_tool to change the path
install_name_tool -change "$dylib_path" "$new_dylib_path" "$dylib_file"
codesign -fs- "$dylib_file"
fi
done
}

# Function to copy the libraries into the appropriate directories
copy_libraries() {
local lib="$1"
local gstreamer_dir="Libraries/Wine/lib/gstreamer-1.0"
local lib_dir="Libraries/Wine/lib"

mkdir -p "$gstreamer_dir" "$lib_dir"

# Check if the library is a GStreamer library by checking its path
if [[ "$lib" == *"/gstreamer-1.0/"* ]]; then
echo "Copying GStreamer library: $lib -> $gstreamer_dir"
cp "$lib" "$gstreamer_dir"
update_dylib_paths "$gstreamer_dir/$(basename "$lib")" "@loader_path/../"
else
echo "Copying non-GStreamer library: $lib -> $lib_dir"
cp "$lib" "$lib_dir"
update_dylib_paths "$lib_dir/$(basename "$lib")" "@loader_path/"
fi
}

# Get the Homebrew prefix for gstreamer
GSTREAMER_PREFIX=$(brew --prefix gstreamer)

# Iterate over the fixed GStreamer libraries array
for lib in "${GSTREAMER_LIBS[@]}"; do
dylib_path="${GSTREAMER_PREFIX}/lib/gstreamer-1.0/${lib}.dylib"

if [ -f "$dylib_path" ]; then
echo "Checking dependencies for: $dylib_path"
find_dylib_dependencies "$dylib_path"
else
echo "Error: $dylib_path not found"
fi
done

# Copy all found dylibs to the appropriate directories
for dylib in "${all_dylibs[@]}"; do
copy_libraries "$dylib"
done

# Copy GStreamer include files
cp -a "$(brew --prefix gstreamer)/lib/gstreamer-1.0/include" Libraries/Wine/lib/gstreamer-1.0

# Update specific GStreamer shared object
update_dylib_paths Libraries/Wine/lib/wine/x86_64-unix/winegstreamer.so "@rpath/"
154 changes: 2 additions & 152 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,158 +214,8 @@ jobs:

- name: Copy External Libs
run: |
LIBS=(
"libaribb24.0"
"libbluray.2"
"libfontconfig.1"
"libfreetype"
"libfreetype.6"
"libgio-2.0.0"
"libglib-2.0.0"
"libgmodule-2.0.0"
"libgmp.10"
"libgnutls.30"
"libgobject-2.0.0"
"libgraphene-1.0.0"
"libgstallocators-1.0.0"
"libgstapp-1.0.0"
"libgstaudio-1.0.0"
"libgstbase-1.0.0"
"libgstcodecparsers-1.0.0"
"libgstcodecs-1.0.0"
"libgstcontroller-1.0.0"
"libgstgl-1.0.0"
"libgstpbutils-1.0.0"
"libgstreamer-1.0.0"
"libgstriff-1.0.0"
"libgstrtp-1.0.0"
"libgstrtsp-1.0.0"
"libgstsdp-1.0.0"
"libgsttag-1.0.0"
"libgsttranscoder-1.0.0"
"libgstvideo-1.0.0"
"libgthread-2.0.0"
"libharfbuzz.0"
"libhogweed.6"
"libidn2.0"
"libintl.8"
"libjpeg.8"
"libjxl.0.11"
"libjxl_threads.0.11"
"libMoltenVK"
"libnettle.8"
"libogg.0"
"liborc-0.4.0"
"libp11-kit.0"
"libpcre2-8.0"
"libpng16.16"
"librav1e.0.7"
"librist.4"
"librubberband.2"
"libsamplerate.0"
"libSDL2-2.0.0"
"libsoxr.0"
"libsrt.1.5"
"libtasn1.6"
"libunistring.5"
"libvidstab.1.2"
"libvmaf.3"
"libvorbis.0"
"libvorbisenc.2"
"libvpx.8"
"libwebp.7"
"libwebpmux.3"
"libXau.6"
"libXdmcp.6"
"libX11.6"
"libX11-xcb.1"
"libx264.164"
"libx265.209"
"libxcb.1"
"libzimg.2"
"libzmq.5"
)

FFMPEG_LIBS=(
"libavfilter.10"
"libavformat.61"
"libavcodec.61"
"libavutil.59"
"libpostproc.58"
"libswresample.5"
"libswscale.8"
)

GSTREAMER_LIBS=(
"libgstapplemedia"
"libgstasf"
"libgstaudioconvert"
"libgstaudioparsers"
"libgstaudioresample"
"libgstavi"
"libgstcoreelements"
"libgstdebug"
"libgstdeinterlace"
"libgstid3demux"
"libgstisomp4"
"libgstlibav"
"libgstopengl"
"libgstplayback"
"libgsttypefindfunctions"
"libgstvideoconvertscale"
"libgstvideofilter"
"libgstvideoparsersbad"
"libgstwavparse"
)

for i in "${LIBS[@]}"
do
cp -Lr $(brew --prefix)/lib/"$i".dylib Libraries/Wine/lib
done

for i in "${FFMPEG_LIBS[@]}"
do
cp -Lr $(brew --prefix ffmpeg@7)/lib/"$i".dylib Libraries/Wine/lib
done

mkdir Libraries/Wine/lib/gstreamer-1.0

for i in "${GSTREAMER_LIBS[@]}"
do
cp -Lr $(brew --prefix gstreamer)/lib/gstreamer-1.0/"$i".dylib Libraries/Wine/lib/gstreamer-1.0
done

cp -a $(brew --prefix gstreamer)/lib/gstreamer-1.0/include Libraries/Wine/lib/gstreamer-1.0

# Fixup brew dylib LCs

update_dylib_paths() {
local dylib_file="$1"
local path_prefix="$2"
echo "Processing $dylib_file..."

# Extract LC_LOAD_DYLIB paths using otool
local load_dylibs=$(otool -L "$dylib_file" | grep -v "$dylib_file" | awk '{print $1}')

for path in $load_dylibs; do
if [[ $path != /usr/lib* && $path != /System/* ]]; then
# For paths not excluded, replace the prefix with @loader_path/
local lib_name="${path##*/}"
local new_path="${path_prefix}${lib_name}"
echo "Updating $path to $new_path"
# Use install_name_tool to change the path
install_name_tool -change "$path" "$new_path" "$dylib_file"
codesign -fs- "$dylib_file"
fi
done
}

export -f update_dylib_paths

find Libraries/Wine/lib -maxdepth 1 -type f -name '*.dylib' -exec bash -c 'update_dylib_paths "$0" "@loader_path/"' {} \;
find Libraries/Wine/lib/gstreamer-1.0 -maxdepth 1 -type f -name '*.dylib' -exec bash -c 'update_dylib_paths "$0" "@loader_path/../"' {} \;

update_dylib_paths Libraries/Wine/lib/wine/x86_64-unix/winegstreamer.so "@rpath/"
chmod +x .github/dylib_packer.zsh
.github/dylib_packer.zsh

- name: Install GPTK
run: |
Expand Down
2 changes: 1 addition & 1 deletion WhiskyWineVersion.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<key>minor</key>
<integer>4</integer>
<key>patch</key>
<integer>3</integer>
<integer>4</integer>
<key>preRelease</key>
<string></string>
</dict>
Expand Down
Loading