mirror of
https://github.com/jellyfin/jellyfin-desktop.git
synced 2026-10-26 16:45:24 +00:00
Fix mac ci build; use aqtinstall
This commit is contained in:
1 parent
9696de712c
commit
b8c4e83e17
5 files changed
+117
-38
No files matched your search
@@ -10,30 +10,40 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: macos-15-intel
|
||||
homebrew_prefix: /usr/local
|
||||
artifact: macos-intel
|
||||
- runner: macos-15
|
||||
homebrew_prefix: /opt/homebrew
|
||||
artifact: macos-arm64
|
||||
- runner: macos-15-intel
|
||||
artifact: macos-intel
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.10.1'
|
||||
arch: clang_64
|
||||
modules: 'qtwebengine qtwebchannel qtpositioning'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew update
|
||||
brew install ninja mpv qt@6 || true
|
||||
brew install mpv
|
||||
- name: Release build
|
||||
run: |
|
||||
cmake -B build -G Ninja -DQTROOT=${{ matrix.homebrew_prefix }}/opt/qt@6 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=output -DCHECK_FOR_UPDATES=ON -DUSE_STATIC_MPVQT=ON
|
||||
cmake -B build -G Ninja \
|
||||
-DQTROOT=$QT_ROOT_DIR \
|
||||
-DCMAKE_PREFIX_PATH=$QT_ROOT_DIR \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=output \
|
||||
-DCHECK_FOR_UPDATES=ON \
|
||||
-DUSE_STATIC_MPVQT=ON
|
||||
cmake --build build --target install
|
||||
- name: Sign and create dmg
|
||||
run: |
|
||||
codesign --force --deep -s - "./build/output/Jellyfin Desktop.app/"
|
||||
codesign --force --deep -s - "./output/Jellyfin Desktop.app/"
|
||||
brew install create-dmg
|
||||
create-dmg --volname "Jellyfin Desktop" --no-internet-enable "Jellyfin Desktop.dmg" "./build/output/Jellyfin Desktop.app"
|
||||
create-dmg --volname "Jellyfin Desktop" --no-internet-enable "Jellyfin Desktop.dmg" "./output/Jellyfin Desktop.app"
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
if(APPLE)
|
||||
set(SCRIPT CompleteBundleOSX)
|
||||
set(SCRIPT CompleteBundleMac)
|
||||
elseif(WIN32)
|
||||
set(SCRIPT CompleteBundleWin)
|
||||
endif(APPLE)
|
||||
|
||||
@@ -2,23 +2,27 @@ set(app "${CMAKE_INSTALL_PREFIX}/@EXE@")
|
||||
set(framework_path "${app}/Contents/Frameworks")
|
||||
set(weprocess "${framework_path}/QtWebEngineCore.framework/Versions/Current/Helpers/QtWebEngineProcess.app")
|
||||
|
||||
# Determine rpath based on architecture
|
||||
cmake_host_system_information(RESULT arch QUERY OS_PLATFORM)
|
||||
if(arch STREQUAL "arm64")
|
||||
set(rpath_str "/opt/homebrew/lib")
|
||||
else()
|
||||
set(rpath_str "/usr/local/lib")
|
||||
endif()
|
||||
# Detect homebrew prefix
|
||||
execute_process(
|
||||
COMMAND brew --prefix
|
||||
OUTPUT_VARIABLE brew_prefix
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
set(brew_lib "${brew_prefix}/lib")
|
||||
set(brew_qt_lib "${brew_prefix}/opt/qt/lib")
|
||||
|
||||
set(args ${app})
|
||||
list(APPEND args "-verbose=2")
|
||||
list(APPEND args "-qmldir=@SOURCE_ROOT@/src/ui")
|
||||
list(APPEND args "-libpath=@QTROOT@/lib")
|
||||
list(APPEND args "-libpath=${brew_qt_lib}")
|
||||
list(APPEND args "-libpath=${brew_lib}")
|
||||
foreach(BIN ${BINS})
|
||||
list(APPEND args "-executable=${app}/${BIN}")
|
||||
endforeach(BIN ${BINS})
|
||||
|
||||
set(ENV{DYLD_LIBRARY_PATH} @QTROOT@/lib:@DEPENDENCY_ROOT@/lib)
|
||||
set(ENV{DYLD_FRAMEWORK_PATH} @QTROOT@/lib:@DEPENDENCY_ROOT@/lib)
|
||||
set(ENV{DYLD_LIBRARY_PATH} @QTROOT@/lib:${brew_qt_lib}:${brew_lib}:@DEPENDENCY_ROOT@/lib)
|
||||
set(ENV{DYLD_FRAMEWORK_PATH} @QTROOT@/lib:${brew_qt_lib}:${brew_lib}:@DEPENDENCY_ROOT@/lib)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E remove "${app}/Contents/Resources/qt.conf"
|
||||
@@ -50,6 +54,16 @@ function(fix_lib_dependencies lib framework_libs_var)
|
||||
set(needs_fix TRUE)
|
||||
endif()
|
||||
|
||||
# Fix flat Qt refs like @executable_path/../Frameworks/QtCore -> framework path
|
||||
if(line MATCHES "^@executable_path/../Frameworks/(Qt[^/ ]+) ")
|
||||
set(qt_name "${CMAKE_MATCH_1}")
|
||||
string(REGEX REPLACE " \\(compatibility.*$" "" old_ref "${line}")
|
||||
set(new_ref "@executable_path/../Frameworks/${qt_name}.framework/Versions/A/${qt_name}")
|
||||
message(STATUS "Fixing flat Qt ref ${old_ref} -> ${new_ref}")
|
||||
execute_process(COMMAND install_name_tool -change "${old_ref}" "${new_ref}" "${lib}" ERROR_QUIET)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
if(needs_fix)
|
||||
# Extract dependency path (remove compatibility version suffix)
|
||||
string(REGEX REPLACE " \\(compatibility.*$" "" dependency_str "${line}")
|
||||
@@ -59,13 +73,9 @@ function(fix_lib_dependencies lib framework_libs_var)
|
||||
if(dependency_str MATCHES "^@rpath/(.+)")
|
||||
set(dep_name "${CMAKE_MATCH_1}")
|
||||
# Search multiple potential locations for @rpath dependencies
|
||||
set(search_paths "${rpath_str}/${dep_name}")
|
||||
set(search_paths "${brew_lib}/${dep_name}")
|
||||
# Add Cellar paths - some libs (like libjxl_cms) aren't symlinked to main lib dir
|
||||
if(arch STREQUAL "arm64")
|
||||
file(GLOB cellar_candidates "/opt/homebrew/Cellar/*/*/lib/${dep_name}")
|
||||
else()
|
||||
file(GLOB cellar_candidates "/usr/local/Cellar/*/*/lib/${dep_name}")
|
||||
endif()
|
||||
file(GLOB cellar_candidates "${brew_prefix}/Cellar/*/*/lib/${dep_name}")
|
||||
list(APPEND search_paths ${cellar_candidates})
|
||||
|
||||
set(resolved_path "")
|
||||
@@ -83,12 +93,8 @@ function(fix_lib_dependencies lib framework_libs_var)
|
||||
elseif(dependency_str MATCHES "^@loader_path/(.+)")
|
||||
get_filename_component(dep_name "${CMAKE_MATCH_1}" NAME)
|
||||
# Same search logic for @loader_path
|
||||
set(search_paths "${rpath_str}/${dep_name}")
|
||||
if(arch STREQUAL "arm64")
|
||||
file(GLOB cellar_candidates "/opt/homebrew/Cellar/*/*/lib/${dep_name}")
|
||||
else()
|
||||
file(GLOB cellar_candidates "/usr/local/Cellar/*/*/lib/${dep_name}")
|
||||
endif()
|
||||
set(search_paths "${brew_lib}/${dep_name}")
|
||||
file(GLOB cellar_candidates "${brew_prefix}/Cellar/*/*/lib/${dep_name}")
|
||||
list(APPEND search_paths ${cellar_candidates})
|
||||
|
||||
set(resolved_path "")
|
||||
@@ -107,6 +113,51 @@ function(fix_lib_dependencies lib framework_libs_var)
|
||||
set(resolved_path "${dependency_str}")
|
||||
endif()
|
||||
|
||||
# Check if this is a framework reference (e.g., Python.framework/Versions/3.x/Python)
|
||||
if(dependency_str MATCHES "\\.framework/")
|
||||
get_filename_component(bin_name "${dependency_str}" NAME)
|
||||
|
||||
# Qt frameworks: macdeployqt handles them, just fix refs to use framework path
|
||||
if(bin_name MATCHES "^Qt")
|
||||
# Extract framework-relative path (e.g., QtCore.framework/Versions/A/QtCore)
|
||||
string(REGEX MATCH "[^/]+\\.framework/.*" fw_rel_path "${dependency_str}")
|
||||
set(target "@executable_path/../Frameworks/${fw_rel_path}")
|
||||
message(STATUS "Fixing Qt framework ${dependency_str} -> ${target}")
|
||||
execute_process(COMMAND install_name_tool -change "${dependency_str}" "${target}" "${lib}" ERROR_QUIET)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Non-Qt frameworks (e.g., Python): copy as flat file
|
||||
set(target "@executable_path/../Frameworks/${bin_name}")
|
||||
|
||||
list(FIND framework_libs "${bin_name}" idx)
|
||||
if(idx EQUAL -1)
|
||||
# Resolve the framework binary path
|
||||
string(REGEX REPLACE "^@rpath" "${brew_lib}" resolved_fw "${dependency_str}")
|
||||
string(REGEX REPLACE "^@loader_path" "${brew_lib}" resolved_fw "${resolved_fw}")
|
||||
|
||||
if(EXISTS "${resolved_fw}")
|
||||
get_filename_component(real_path "${resolved_fw}" REALPATH)
|
||||
message(STATUS "Copying framework binary ${real_path} -> ${framework_path}/${bin_name}")
|
||||
file(COPY "${real_path}" DESTINATION "${framework_path}")
|
||||
get_filename_component(real_name "${real_path}" NAME)
|
||||
if(NOT "${real_name}" STREQUAL "${bin_name}")
|
||||
file(RENAME "${framework_path}/${real_name}" "${framework_path}/${bin_name}")
|
||||
endif()
|
||||
execute_process(COMMAND install_name_tool -id "${target}" "${framework_path}/${bin_name}" ERROR_QUIET)
|
||||
list(APPEND framework_libs "${bin_name}")
|
||||
set_property(GLOBAL APPEND PROPERTY LIBS_TO_FIX "${framework_path}/${bin_name}")
|
||||
else()
|
||||
message(WARNING "Could not find framework binary: ${resolved_fw}")
|
||||
continue()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "Fixing ${dependency_str} -> ${target}")
|
||||
execute_process(COMMAND install_name_tool -change "${dependency_str}" "${target}" "${lib}" ERROR_QUIET)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
get_filename_component(dep_name "${resolved_path}" NAME)
|
||||
set(target "@executable_path/../Frameworks/${dep_name}")
|
||||
|
||||
@@ -149,7 +200,11 @@ endforeach()
|
||||
# Collect all libs to fix
|
||||
file(GLOB_RECURSE all_dylibs "${app}/*.dylib")
|
||||
file(GLOB_RECURSE all_sos "${app}/*.so")
|
||||
set_property(GLOBAL PROPERTY LIBS_TO_FIX ${all_dylibs} ${all_sos})
|
||||
# Framework binaries have no extension - scan them for deps like QtDBus
|
||||
file(GLOB framework_bins "${framework_path}/*.framework/Versions/*/[A-Z]*")
|
||||
list(FILTER framework_bins EXCLUDE REGEX "\\.(plist|h|json|tbd)$")
|
||||
list(FILTER framework_bins EXCLUDE REGEX "/(Headers|Resources)/")
|
||||
set_property(GLOBAL PROPERTY LIBS_TO_FIX ${all_dylibs} ${all_sos} ${framework_bins})
|
||||
|
||||
# Process libs iteratively (handles newly discovered deps)
|
||||
set(max_iterations 100)
|
||||
@@ -122,18 +122,27 @@ ninja windows_package
|
||||
|
||||
## Building for MacOS
|
||||
|
||||
Install [Qt 6](https://www.qt.io/download-thank-you?hsLang=en), remember to check `Qt WebEngine`.
|
||||
|
||||
Then run the following commands (replace <QT_DIR> with your QT installation location):
|
||||
Install Qt 6.10.1 using aqtinstall and mpv from Homebrew:
|
||||
|
||||
```bash
|
||||
brew install mpv ninja qt
|
||||
# Install dependencies
|
||||
brew install aqtinstall mpv ninja
|
||||
|
||||
# Download Qt
|
||||
aqt install-qt mac desktop 6.10.1 -m qtwebengine qtwebchannel qtpositioning
|
||||
|
||||
# Clone and build
|
||||
git clone --recursive https://github.com/jellyfin/jellyfin-desktop.git
|
||||
cd jellyfin-desktop
|
||||
|
||||
cmake -B build -G Ninja -DUSE_STATIC_MPVQT=ON
|
||||
cmake --build build
|
||||
export QTROOT=$(pwd)/6.10.1/macos
|
||||
cmake -B build -G Ninja \
|
||||
-DQTROOT=$QTROOT \
|
||||
-DCMAKE_PREFIX_PATH=$QTROOT \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=output \
|
||||
-DUSE_STATIC_MPVQT=ON
|
||||
cmake --build build --target install
|
||||
```
|
||||
|
||||
## Log File Location
|
||||
|
||||
+6
-1
@@ -128,9 +128,14 @@ get_property(BUNDLED_FILES GLOBAL PROPERTY CONFIG_BUNDLED_FILES)
|
||||
add_executable(${MAIN_TARGET} WIN32 MACOSX_BUNDLE ${MAIN_SRCS} ${BUNDLED_FILES} ${RESOURCE_FILES} ${XCODE_RESOURCES})
|
||||
add_dependencies(${MAIN_TARGET} generate_resources)
|
||||
std_target_properties(${MAIN_TARGET})
|
||||
if(APPLE)
|
||||
set(_install_rpath "@executable_path/../Frameworks")
|
||||
else()
|
||||
set(_install_rpath "${QTROOT}/lib")
|
||||
endif()
|
||||
set_target_properties(${MAIN_TARGET} PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/bundle/osx/Info.plist.in
|
||||
INSTALL_RPATH "${QTROOT}/lib"
|
||||
INSTALL_RPATH "${_install_rpath}"
|
||||
OUTPUT_NAME ${MAIN_NAME}
|
||||
)
|
||||
copy_resources(${MAIN_TARGET})
|
||||
|
||||
Reference in new issue
Block a user