mirror of
https://github.com/strawberrymusicplayer/strawberry
synced 2025-01-31 01:29:41 +01:00
Fix macOS deployment
This commit is contained in:
parent
8193be36e5
commit
6fb48af598
12
.github/workflows/ccpp.yml
vendored
12
.github/workflows/ccpp.yml
vendored
@ -1055,8 +1055,7 @@ jobs:
|
||||
- name: Link Sparkle
|
||||
shell: bash
|
||||
run: |
|
||||
sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1)/Sparkle.framework /Library/Frameworks/Sparkle.framework
|
||||
sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1)/Sparkle.framework.dSYM /Library/Frameworks/Sparkle.framework.dSYM
|
||||
sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1) /usr/local/opt/sparkle
|
||||
|
||||
- name: Create Build Environment
|
||||
shell: bash
|
||||
@ -1082,9 +1081,6 @@ jobs:
|
||||
working-directory: build
|
||||
shell: bash
|
||||
run: make install
|
||||
- name: Hack to make macdeployqt find plugins
|
||||
shell: bash
|
||||
run: sudo ln -s /usr/local/Cellar/qt/$(ls /usr/local/Cellar/qt/ | tail -n1)/share/qt/plugins /usr/local/plugins
|
||||
- name: Create DMG
|
||||
working-directory: build
|
||||
shell: bash
|
||||
@ -1131,8 +1127,7 @@ jobs:
|
||||
- name: Link Sparkle
|
||||
shell: bash
|
||||
run: |
|
||||
sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1)/Sparkle.framework /Library/Frameworks/Sparkle.framework
|
||||
sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1)/Sparkle.framework.dSYM /Library/Frameworks/Sparkle.framework.dSYM
|
||||
sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1) /usr/local/opt/sparkle
|
||||
|
||||
- name: Create Build Environment
|
||||
shell: bash
|
||||
@ -1158,9 +1153,6 @@ jobs:
|
||||
working-directory: build
|
||||
shell: bash
|
||||
run: make install
|
||||
- name: Hack to make macdeployqt find plugins
|
||||
shell: bash
|
||||
run: sudo ln -s /usr/local/Cellar/qt/$(ls /usr/local/Cellar/qt/ | tail -n1)/share/qt/plugins /usr/local/plugins
|
||||
- name: Create DMG
|
||||
working-directory: build
|
||||
shell: bash
|
||||
|
@ -19,8 +19,7 @@ before_install:
|
||||
- brew install libcdio libmtp
|
||||
- brew install create-dmg
|
||||
- brew install --cask sparkle
|
||||
- sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1)/Sparkle.framework /Library/Frameworks/Sparkle.framework
|
||||
- sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1)/Sparkle.framework.dSYM /Library/Frameworks/Sparkle.framework.dSYM
|
||||
- sudo ln -s /usr/local/Caskroom/sparkle/$(ls /usr/local/Caskroom/sparkle | head -n1) /usr/local/opt/sparkle
|
||||
- export Qt6_DIR=/usr/local/opt/qt6/lib/cmake
|
||||
- export Qt6LinguistTools_DIR=/usr/local/opt/qt6/lib/cmake/Qt6LinguistTools
|
||||
- ls /usr/local/lib/gstreamer-1.0
|
||||
@ -31,7 +30,6 @@ before_script:
|
||||
script:
|
||||
- make -j8
|
||||
- make install
|
||||
- sudo ln -s /usr/local/Cellar/qt/$(ls /usr/local/Cellar/qt/ | tail -n1)/share/qt/plugins /usr/local/plugins
|
||||
- make dmg2
|
||||
after_success:
|
||||
- ls -lh strawberry*.dmg
|
||||
|
5
3rdparty/macdeployqt/main.cpp
vendored
5
3rdparty/macdeployqt/main.cpp
vendored
@ -278,6 +278,10 @@ int main(int argc, char **argv)
|
||||
if (runStripEnabled)
|
||||
stripAppBinary(appBundlePath);
|
||||
|
||||
if (!FinalCheck(appBundlePath)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (runCodesign)
|
||||
codesign(codesignIdentiy, appBundlePath);
|
||||
|
||||
@ -288,4 +292,3 @@ int main(int argc, char **argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
112
3rdparty/macdeployqt/shared.cpp
vendored
112
3rdparty/macdeployqt/shared.cpp
vendored
@ -856,6 +856,11 @@ void changeInstallName(const QString &bundlePath, const FrameworkInfo &framework
|
||||
if (!canonicalInstallName.isEmpty() && canonicalInstallName != framework.installName) {
|
||||
changeInstallName(canonicalInstallName, deployedInstallName, binary);
|
||||
}
|
||||
// Homebrew workaround, resolve symlink /usr/local/opt/library to /usr/local/Cellar/library
|
||||
if (framework.installName.startsWith("/usr/local/opt/") && framework.installName.count('/') >= 5) {
|
||||
canonicalInstallName = QFileInfo(framework.installName.section('/', 0, 4)).canonicalFilePath() + "/" + framework.installName.section('/', 5);
|
||||
changeInstallName(canonicalInstallName, deployedInstallName, binary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1679,3 +1684,110 @@ void fixupFramework(const QString &frameworkName)
|
||||
changeIdentification("@rpath/" + frameworkBinary, frameworkBinary);
|
||||
addRPath("@loader_path/../../Contents/Frameworks/", frameworkBinary);
|
||||
}
|
||||
|
||||
bool FinalCheck(const QString &appBundlePath) {
|
||||
|
||||
bool success = true;
|
||||
|
||||
QDirIterator iter(appBundlePath, QDir::Files | QDir::NoSymLinks, QDirIterator::Subdirectories);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
QString filepath = iter.fileInfo().filePath();
|
||||
|
||||
if (filepath.endsWith(".plist") ||
|
||||
filepath.endsWith(".icns") ||
|
||||
filepath.endsWith(".prl") ||
|
||||
filepath.endsWith(".conf") ||
|
||||
filepath.endsWith(".h") ||
|
||||
filepath.endsWith(".nib") ||
|
||||
filepath.endsWith(".strings") ||
|
||||
filepath.endsWith(".css") ||
|
||||
filepath.endsWith("CodeResources") ||
|
||||
filepath.endsWith("PkgInfo") ||
|
||||
filepath.endsWith(".modulemap")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//qDebug() << "Final check on" << filepath;
|
||||
|
||||
QProcess otool;
|
||||
otool.start("otool", QStringList() << "-L" << filepath);
|
||||
otool.waitForFinished();
|
||||
if (otool.exitStatus() != QProcess::NormalExit || otool.exitCode() != 0) {
|
||||
LogError() << otool.readAllStandardError();
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
QString output = otool.readAllStandardOutput();
|
||||
QStringList output_lines = output.split("\n", Qt::SkipEmptyParts);
|
||||
if (output_lines.size() < 2) {
|
||||
LogError() << "Could not parse otool output:" << output;
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
QString first_line = output_lines.first();
|
||||
if (first_line.endsWith(':')) first_line.chop(1);
|
||||
if (first_line == filepath) {
|
||||
output_lines.removeFirst();
|
||||
}
|
||||
else {
|
||||
LogError() << "First line" << first_line << "does not match" << filepath;
|
||||
success = false;
|
||||
}
|
||||
static const QRegularExpression regexp(QStringLiteral("^\\t(.+) \\(compatibility version (\\d+\\.\\d+\\.\\d+), current version (\\d+\\.\\d+\\.\\d+)(, weak)?\\)$"));
|
||||
for (const QString &output_line : output_lines) {
|
||||
|
||||
//qDebug() << "Final check on" << filepath << output_line;
|
||||
|
||||
const auto match = regexp.match(output_line);
|
||||
if (match.hasMatch()) {
|
||||
QString library = match.captured(1);
|
||||
if (QFileInfo(library).fileName() == QFileInfo(filepath).fileName()) { // It's this.
|
||||
continue;
|
||||
}
|
||||
else if (library.startsWith("@executable_path")) {
|
||||
QString real_path = library;
|
||||
real_path = real_path.replace("@executable_path", appBundlePath + "/Contents/MacOS");
|
||||
if (!QFile(real_path).exists()) {
|
||||
LogError() << real_path << "does not exist for" << filepath;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if (library.startsWith("@rpath")) {
|
||||
QString real_path = library;
|
||||
real_path = real_path.replace("@rpath", appBundlePath + "/Contents/Frameworks");
|
||||
if (!QFile(real_path).exists() && !real_path.endsWith("QtSvg")) { // FIXME: Ignore broken svg image plugin.
|
||||
LogError() << real_path << "does not exist for" << filepath;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if (library.startsWith("@loader_path")) {
|
||||
QString loader_path = QFileInfo(filepath).path();
|
||||
QString real_path = library;
|
||||
real_path = real_path.replace("@loader_path", loader_path);
|
||||
if (!QFile(real_path).exists()) {
|
||||
LogError() << real_path << "does not exist for" << filepath;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if (library.startsWith("/System/Library/") || library.startsWith("/usr/lib/")) { // System library
|
||||
continue;
|
||||
}
|
||||
else if (library.endsWith("libgcc_s.1.dylib")) { // fftw points to it for some reason.
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
LogError() << "File" << filepath << "points to" << library;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogError() << "Could not parse otool output line:" << output_line;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
}
|
||||
|
2
3rdparty/macdeployqt/shared.h
vendored
2
3rdparty/macdeployqt/shared.h
vendored
@ -136,6 +136,6 @@ QSet<QString> codesignBundle(const QString &identity,
|
||||
void codesign(const QString &identity, const QString &appBundlePath);
|
||||
void createDiskImage(const QString &appBundlePath, const QString &filesystemType);
|
||||
void fixupFramework(const QString &appBundlePath);
|
||||
|
||||
bool FinalCheck(const QString &appBundlePath);
|
||||
|
||||
#endif
|
||||
|
@ -251,7 +251,7 @@ set(SINGLEAPPLICATION_LIBRARIES singleapplication)
|
||||
set(SINGLECOREAPPLICATION_LIBRARIES singlecoreapplication)
|
||||
|
||||
if(APPLE)
|
||||
find_library(SPARKLE Sparkle)
|
||||
find_library(SPARKLE Sparkle PATHS "/usr/local/opt/sparkle")
|
||||
add_subdirectory(3rdparty/macdeployqt)
|
||||
add_subdirectory(3rdparty/SPMediaKeyTap)
|
||||
set(SPMEDIAKEYTAP_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/SPMediaKeyTap)
|
||||
|
@ -21,12 +21,16 @@ endif()
|
||||
|
||||
if(MACDEPLOYQT_EXECUTABLE AND CREATEDMG_EXECUTABLE AND MACOS_VERSION_PACKAGE)
|
||||
add_custom_target(dmg
|
||||
COMMAND ${MACDEPLOYQT_EXECUTABLE} strawberry.app -executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/strawberry-tagreader -verbose=3
|
||||
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/strawberry.app/Contents/Frameworks/
|
||||
COMMAND cp -r /usr/local/opt/sparkle/Sparkle.framework ${CMAKE_BINARY_DIR}/strawberry.app/Contents/Frameworks/
|
||||
COMMAND ${MACDEPLOYQT_EXECUTABLE} strawberry.app -verbose=3 -executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/strawberry-tagreader
|
||||
COMMAND ${CREATEDMG_EXECUTABLE} --volname strawberry --background "${CMAKE_SOURCE_DIR}/dist/macos/dmg_background.png" --app-drop-link 450 218 --icon strawberry.app 150 218 --window-size 600 450 strawberry-${STRAWBERRY_VERSION_PACKAGE}-${MACOS_VERSION_PACKAGE}-${CMAKE_HOST_SYSTEM_PROCESSOR}.dmg strawberry.app
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
add_custom_target(dmg2
|
||||
COMMAND ${MACDEPLOYQT_EXECUTABLE} strawberry.app -executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/strawberry-tagreader -verbose=3
|
||||
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/strawberry.app/Contents/Frameworks/
|
||||
COMMAND cp -r /usr/local/opt/sparkle/Sparkle.framework ${CMAKE_BINARY_DIR}/strawberry.app/Contents/Frameworks/
|
||||
COMMAND ${MACDEPLOYQT_EXECUTABLE} strawberry.app -verbose=3 -executable=${CMAKE_BINARY_DIR}/strawberry.app/Contents/PlugIns/strawberry-tagreader
|
||||
COMMAND ${CREATEDMG_EXECUTABLE} --skip-jenkins --volname strawberry --background "${CMAKE_SOURCE_DIR}/dist/macos/dmg_background.png" --app-drop-link 450 218 --icon strawberry.app 150 218 --window-size 600 450 strawberry-${STRAWBERRY_VERSION_PACKAGE}-${MACOS_VERSION_PACKAGE}-${CMAKE_HOST_SYSTEM_PROCESSOR}.dmg strawberry.app
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user