diff --git a/.github/dylib_packer.zsh b/.github/dylib_packer.zsh new file mode 100644 index 000000000000..573395cc5c2f --- /dev/null +++ b/.github/dylib_packer.zsh @@ -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/" \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 061904e173d6..708881067dbf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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: | diff --git a/WhiskyWineVersion.plist b/WhiskyWineVersion.plist index 90becb576974..a58f9dcdce82 100644 --- a/WhiskyWineVersion.plist +++ b/WhiskyWineVersion.plist @@ -11,7 +11,7 @@ minor 4 patch - 3 + 4 preRelease