mirror of
https://github.com/jellyfin/jellyfin-media-player.git
synced 2024-11-27 00:00:38 +00:00
Merge pull request #571 from gnattu/apple-silicon-build
feat: add Apple silicon build
This commit is contained in:
commit
9b9bb09318
47
.github/workflows/main.yml
vendored
47
.github/workflows/main.yml
vendored
@ -8,28 +8,25 @@ on:
|
||||
- test
|
||||
jobs:
|
||||
build-mac:
|
||||
runs-on: macos-11
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Qt 5.15.2
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: "5.15.2"
|
||||
modules: "qtwebengine"
|
||||
setup-python: 'false'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew update
|
||||
brew install ninja mpv || true
|
||||
brew install ninja mpv qt@5 || true
|
||||
- name: Release build
|
||||
run: |
|
||||
./download_webclient.sh
|
||||
sed -i '' 's/<body>/<body style="overscroll-behavior: none;">/' ./build/dist/index.html
|
||||
cd build
|
||||
cmake -GNinja -DQTROOT=$Qt5_DIR -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=output ..
|
||||
cmake -GNinja -DQTROOT=/usr/local/opt/qt@5 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=output ..
|
||||
ninja install
|
||||
- name: Fix library paths and create dmg
|
||||
run: |
|
||||
python3 ./scripts/fix-install-names.py ./build/output/Jellyfin\ Media\ Player.app
|
||||
python3 ./scripts/fix-webengine.py ./build/output/Jellyfin\ Media\ Player.app
|
||||
codesign --force --deep -s - ./build/output/Jellyfin\ Media\ Player.app/
|
||||
brew install create-dmg
|
||||
create-dmg --volname "Jellyfin Media Player" --no-internet-enable "JellyfinMediaPlayer.dmg" "./build/output/Jellyfin Media Player.app"
|
||||
- name: Archive production artifacts
|
||||
@ -38,12 +35,40 @@ jobs:
|
||||
name: macos
|
||||
path: ${{ github.workspace }}/JellyfinMediaPlayer.dmg
|
||||
|
||||
build-macarm64:
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew update
|
||||
brew install ninja mpv qt@5 || true
|
||||
- name: Release build
|
||||
run: |
|
||||
./download_webclient.sh
|
||||
sed -i '' 's/<body>/<body style="overscroll-behavior: none;">/' ./build/dist/index.html
|
||||
cd build
|
||||
cmake -GNinja -DQTROOT=/opt/homebrew/opt/qt@5 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=output ..
|
||||
ninja install
|
||||
- name: Fix library paths and create dmg
|
||||
run: |
|
||||
python3 ./scripts/fix-install-names.py ./build/output/Jellyfin\ Media\ Player.app
|
||||
python3 ./scripts/fix-webengine.py ./build/output/Jellyfin\ Media\ Player.app
|
||||
codesign --force --deep -s - ./build/output/Jellyfin\ Media\ Player.app/
|
||||
brew install create-dmg
|
||||
create-dmg --volname "Jellyfin Media Player" --no-internet-enable "JellyfinMediaPlayer.dmg" "./build/output/Jellyfin Media Player.app"
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos-arm64
|
||||
path: ${{ github.workspace }}/JellyfinMediaPlayer.dmg
|
||||
|
||||
build-win64:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Qt 5.15.2
|
||||
uses: jurplel/install-qt-action@v4
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: "5.15.2"
|
||||
arch: "win64_msvc2019_64"
|
||||
@ -89,7 +114,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Qt 5.15.2
|
||||
uses: jurplel/install-qt-action@v4
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: "5.15.2"
|
||||
arch: "win32_msvc2019"
|
||||
|
@ -4,6 +4,7 @@ import argparse
|
||||
from collections import deque
|
||||
import subprocess
|
||||
import shutil
|
||||
import platform
|
||||
|
||||
|
||||
def main(argv=tuple(sys.argv[1:])):
|
||||
@ -13,6 +14,9 @@ def main(argv=tuple(sys.argv[1:])):
|
||||
|
||||
bundle_path = Path(arguments.bundle[0])
|
||||
framework_path = bundle_path / 'Contents' / 'Frameworks'
|
||||
rpath_str = '/usr/local/lib'
|
||||
if platform.machine() == 'arm64':
|
||||
rpath_str = '/opt/homebrew/lib'
|
||||
framework_libs = set(file.name for file in framework_path.glob('*.dylib')).union(set(file.name for file in framework_path.glob('*.so')))
|
||||
libs_to_fix = deque()
|
||||
libs_to_fix.extend(file for file in bundle_path.glob('**/*.dylib'))
|
||||
@ -23,13 +27,23 @@ def main(argv=tuple(sys.argv[1:])):
|
||||
result = subprocess.check_output(['otool', '-L', str(lib.resolve())], stderr=subprocess.STDOUT).decode('utf-8')
|
||||
for dependency in result.splitlines():
|
||||
dependency = dependency.strip().lstrip()
|
||||
if dependency.startswith('/usr/local'):
|
||||
if dependency.startswith('/usr/local') or dependency.startswith('/opt/homebrew') or dependency.startswith('@rpath') or dependency.startswith('@loader_path'):
|
||||
# cut off trailing compatibility string
|
||||
dependency = Path(dependency.split(' (compatibility')[0])
|
||||
dependency_str = dependency.split(' (compatibility')[0].strip()
|
||||
if dependency.startswith('@rpath'):
|
||||
dependency = dependency_str.replace("@rpath", rpath_str)
|
||||
dependency = Path(dependency)
|
||||
elif dependency.startswith('@loader_path'):
|
||||
dependency = dependency_str.replace("@loader_path", rpath_str)
|
||||
dependency = Path(dependency)
|
||||
dependency_name = dependency.name
|
||||
dependency = (Path(rpath_str) / dependency_name).resolve()
|
||||
else:
|
||||
dependency = Path(dependency_str)
|
||||
|
||||
# if somehow macdeployqt didn't copy the lib for us, we do a manual copy
|
||||
if dependency.name not in framework_libs:
|
||||
shutil.copy(str(dependency.resolve()), str(framework_path.resolve()))
|
||||
shutil.copy(str(dependency.resolve()), str((framework_path / dependency.name).resolve()))
|
||||
framework_libs.add(dependency.name)
|
||||
# add the newly added library in to the to fix queue
|
||||
libs_to_fix.append(framework_path / dependency.name)
|
||||
@ -38,9 +52,9 @@ def main(argv=tuple(sys.argv[1:])):
|
||||
|
||||
# now we fix the path using install_name_tool
|
||||
target = f'@executable_path/../Frameworks/{dependency.name}'
|
||||
print(f'Fixing dependency {dependency} of {lib} to {target}')
|
||||
print(f'Fixing dependency {dependency_str} of {lib} to {target}')
|
||||
subprocess.run(['install_name_tool', '-id', target, lib])
|
||||
subprocess.run(['install_name_tool', '-change', str(dependency), target, lib])
|
||||
subprocess.run(['install_name_tool', '-change', dependency_str, target, lib])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
35
scripts/fix-webengine.py
Normal file
35
scripts/fix-webengine.py
Normal file
@ -0,0 +1,35 @@
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
from collections import deque
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
def main(argv=tuple(sys.argv[1:])):
|
||||
arg_parser = argparse.ArgumentParser(description='Fix third party library paths in .app bundles.')
|
||||
arg_parser.add_argument('bundle', metavar='BUNDLE', type=str, nargs=1)
|
||||
arguments = arg_parser.parse_args(argv)
|
||||
|
||||
bundle_path = Path(arguments.bundle[0])
|
||||
print(bundle_path)
|
||||
webengine_path = bundle_path / 'Contents' / 'Frameworks' / 'QtWebEngineCore.framework' / 'Helpers' / 'QtWebEngineProcess.app'
|
||||
link_path = webengine_path / 'Contents' / 'Frameworks'
|
||||
bin_to_fix = webengine_path / 'Contents' / 'MacOS' / 'QtWebEngineProcess'
|
||||
|
||||
os.symlink('../../../../../../../Frameworks', link_path)
|
||||
|
||||
result = subprocess.check_output(['otool', '-L', str(bin_to_fix.resolve())],stderr=subprocess.STDOUT).decode('utf-8')
|
||||
for dependency in result.splitlines():
|
||||
dependency = dependency.strip().lstrip()
|
||||
if dependency.startswith('/opt/homebrew'):
|
||||
# cut off trailing compatibility string
|
||||
dependency_str = dependency.split(' (compatibility')[0].strip()
|
||||
dependency_framework_str = dependency_str.split('/lib')[1].strip()
|
||||
dependency_framework = Path(dependency_framework_str)
|
||||
target = f'@executable_path/../Frameworks{dependency_framework_str}'
|
||||
subprocess.run(['install_name_tool', '-id', target, bin_to_fix])
|
||||
subprocess.run(['install_name_tool', '-change', dependency_str, target, bin_to_fix])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user