mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
Support macOS bundling for binary distribution
This commit is contained in:
parent
c50d459b1e
commit
5a40c1802b
9 changed files with 109 additions and 39 deletions
|
@ -15,7 +15,9 @@ unzip -: sdk-*.zip
|
||||||
mkdir vulkan-sdk
|
mkdir vulkan-sdk
|
||||||
ln -s ${PWD}/Vulkan-Headers*/include vulkan-sdk/include
|
ln -s ${PWD}/Vulkan-Headers*/include vulkan-sdk/include
|
||||||
mkdir vulkan-sdk/lib
|
mkdir vulkan-sdk/lib
|
||||||
ln target/release/libportability.dylib vulkan-sdk/lib/libVulkan.dylib
|
cp target/release/libportability.dylib vulkan-sdk/lib/libVulkan.dylib
|
||||||
|
# Let macdeployqt locate and install Vulkan library
|
||||||
|
install_name_tool -id ${PWD}/vulkan-sdk/lib/libVulkan.dylib vulkan-sdk/lib/libVulkan.dylib
|
||||||
export VULKAN_SDK=${PWD}/vulkan-sdk
|
export VULKAN_SDK=${PWD}/vulkan-sdk
|
||||||
|
|
||||||
git submodule update --quiet --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng 3rdparty/cereal 3rdparty/hidapi 3rdparty/xxHash 3rdparty/yaml-cpp Vulkan/glslang
|
git submodule update --quiet --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng 3rdparty/cereal 3rdparty/hidapi 3rdparty/xxHash 3rdparty/yaml-cpp Vulkan/glslang
|
||||||
|
|
|
@ -1376,10 +1376,16 @@ const std::string& fs::get_config_dir()
|
||||||
|
|
||||||
dir.resize(dir.rfind('/') + 1);
|
dir.resize(dir.rfind('/') + 1);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (const char* home = ::getenv("HOME"))
|
||||||
|
dir = home + "/Library/Application Support"s;
|
||||||
|
#else
|
||||||
if (const char* home = ::getenv("XDG_CONFIG_HOME"))
|
if (const char* home = ::getenv("XDG_CONFIG_HOME"))
|
||||||
dir = home;
|
dir = home;
|
||||||
else if (const char* home = ::getenv("HOME"))
|
else if (const char* home = ::getenv("HOME"))
|
||||||
dir = home + "/.config"s;
|
dir = home + "/.config"s;
|
||||||
|
#endif
|
||||||
else // Just in case
|
else // Just in case
|
||||||
dir = "./config";
|
dir = "./config";
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,15 @@ file(GLOB RPCS3_SRC "*.cpp")
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_executable(rpcs3 WIN32 ${RPCS3_SRC})
|
add_executable(rpcs3 WIN32 ${RPCS3_SRC})
|
||||||
|
elseif(APPLE)
|
||||||
|
set(MACOSX_BUNDLE_BUNDLE_NAME rpcs3)
|
||||||
|
set(MACOSX_BUNDLE_GUI_IDENTIFIER "net.rpcs3.rpcs3")
|
||||||
|
set(MACOSX_BUNDLE_INFO_STRING "Open-source Sony PlayStation 3 emulator")
|
||||||
|
set(MACOSX_BUNDLE_ICON_FILE "rpcs3.icns")
|
||||||
|
set(MACOSX_BUNDLE_LONG_VERSION_STRING "0.0.5")
|
||||||
|
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "0.0.5")
|
||||||
|
set(MACOSX_BUNDLE_BUNDLE_VERSION "0.0.5")
|
||||||
|
add_executable(rpcs3 MACOSX_BUNDLE ${RPCS3_SRC} "${RPCS3_SRC_DIR}/rpcs3.icns")
|
||||||
else()
|
else()
|
||||||
add_executable(rpcs3 ${RPCS3_SRC})
|
add_executable(rpcs3 ${RPCS3_SRC})
|
||||||
endif()
|
endif()
|
||||||
|
@ -84,8 +93,17 @@ set_target_properties(rpcs3 PROPERTIES
|
||||||
|
|
||||||
cotire(rpcs3)
|
cotire(rpcs3)
|
||||||
|
|
||||||
if (UNIX)
|
|
||||||
# Copy icons to executable directory
|
# Copy icons to executable directory
|
||||||
|
if(APPLE)
|
||||||
|
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${RPCS3_SRC_DIR}/rpcs3.icns $<TARGET_FILE_DIR:rpcs3>/../Resources/rpcs3.icns
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${CMAKE_SOURCE_DIR}/bin/Icons $<TARGET_FILE_DIR:rpcs3>/../Resources/Icons
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${CMAKE_SOURCE_DIR}/bin/GuiConfigs $<TARGET_FILE_DIR:rpcs3>/../Resources/GuiConfigs
|
||||||
|
COMMAND "${Qt5_DIR}/../../../bin/macdeployqt" "${PROJECT_BINARY_DIR}/bin/rpcs3.app")
|
||||||
|
elseif(UNIX)
|
||||||
add_custom_command(TARGET rpcs3 POST_BUILD
|
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
${CMAKE_SOURCE_DIR}/bin/Icons $<TARGET_FILE_DIR:rpcs3>/Icons)
|
${CMAKE_SOURCE_DIR}/bin/Icons $<TARGET_FILE_DIR:rpcs3>/Icons)
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// STB_IMAGE_IMPLEMENTATION and STB_TRUETYPE_IMPLEMENTATION defined externally
|
// STB_IMAGE_IMPLEMENTATION and STB_TRUETYPE_IMPLEMENTATION defined externally
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
#include <stb_truetype.h>
|
#include <stb_truetype.h>
|
||||||
|
@ -505,24 +509,37 @@ namespace rsx
|
||||||
if (info->data == nullptr)
|
if (info->data == nullptr)
|
||||||
{
|
{
|
||||||
// Resource was not found in config dir, try and grab from relative path (linux)
|
// Resource was not found in config dir, try and grab from relative path (linux)
|
||||||
info = std::make_unique<image_info>(("Icons/ui/" + res).c_str());
|
auto src = "Icons/ui/" + res;
|
||||||
|
info = std::make_unique<image_info>(src.c_str());
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// Check for Icons in ../share/rpcs3 for AppImages and /usr/bin/
|
// Check for Icons in ../share/rpcs3 for AppImages,
|
||||||
|
// in rpcs3.app/Contents/Resources for App Bundles, and /usr/bin.
|
||||||
if (info->data == nullptr)
|
if (info->data == nullptr)
|
||||||
{
|
{
|
||||||
char result[ PATH_MAX ];
|
char result[ PATH_MAX ];
|
||||||
#ifdef __linux__
|
#if defined(__APPLE__)
|
||||||
ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
|
uint32_t bufsize = PATH_MAX;
|
||||||
|
bool success = _NSGetExecutablePath( result, &bufsize ) == 0;
|
||||||
|
#elif defined(__linux__)
|
||||||
|
bool success = readlink( "/proc/self/exe", result, PATH_MAX ) >= 0;
|
||||||
#else
|
#else
|
||||||
ssize_t count = readlink( "/proc/curproc/file", result, PATH_MAX );
|
bool success = readlink( "/proc/curproc/file", result, PATH_MAX ) >= 0;
|
||||||
#endif
|
#endif
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
std::string executablePath = dirname(result);
|
std::string executablePath = dirname(result);
|
||||||
info = std::make_unique<image_info>((executablePath + "/../share/rpcs3/Icons/ui/" + res).c_str());
|
#ifdef __APPLE__
|
||||||
|
src = executablePath + "/../Resources/Icons/ui/" + res;
|
||||||
|
#else
|
||||||
|
src = executablePath + "/../share/rpcs3/Icons/ui/" + res;
|
||||||
|
#endif
|
||||||
|
info = std::make_unique<image_info>(src.c_str());
|
||||||
// Check if the icons are in the same directory as the executable (local builds)
|
// Check if the icons are in the same directory as the executable (local builds)
|
||||||
if (info->data == nullptr)
|
if (info->data == nullptr)
|
||||||
{
|
{
|
||||||
info = std::make_unique<image_info>((executablePath + "/Icons/ui/" + res).c_str());
|
src = executablePath + "/Icons/ui/" + res;
|
||||||
|
info = std::make_unique<image_info>(src.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -530,7 +547,6 @@ namespace rsx
|
||||||
{
|
{
|
||||||
// Install the image to config dir
|
// Install the image to config dir
|
||||||
auto dst_dir = fs::get_config_dir() + "Icons/ui/";
|
auto dst_dir = fs::get_config_dir() + "Icons/ui/";
|
||||||
auto src = "Icons/ui/" + res;
|
|
||||||
auto dst = dst_dir + res;
|
auto dst = dst_dir + res;
|
||||||
|
|
||||||
if (!fs::is_dir(dst_dir))
|
if (!fs::is_dir(dst_dir))
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <dispatch/dispatch.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "rpcs3_version.h"
|
#include "rpcs3_version.h"
|
||||||
|
|
||||||
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
|
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
|
||||||
|
@ -50,6 +54,8 @@ static semaphore<> s_qt_mutex{};
|
||||||
static QApplication app0{argc, argv};
|
static QApplication app0{argc, argv};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto show_report = [](const std::string& text)
|
||||||
|
{
|
||||||
QMessageBox msg;
|
QMessageBox msg;
|
||||||
msg.setWindowTitle(tr("RPCS3: Fatal Error"));
|
msg.setWindowTitle(tr("RPCS3: Fatal Error"));
|
||||||
msg.setIcon(QMessageBox::Critical);
|
msg.setIcon(QMessageBox::Critical);
|
||||||
|
@ -67,6 +73,19 @@ static semaphore<> s_qt_mutex{};
|
||||||
.arg(tr("Please, don't send incorrect reports. Thanks for understanding.")));
|
.arg(tr("Please, don't send incorrect reports. Thanks for understanding.")));
|
||||||
msg.layout()->setSizeConstraint(QLayout::SetFixedSize);
|
msg.layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
msg.exec();
|
msg.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// Cocoa access is not allowed outside of the main thread
|
||||||
|
if (!pthread_main_np())
|
||||||
|
{
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^ { show_report(text); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
show_report(text);
|
||||||
|
}
|
||||||
|
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
BIN
rpcs3/rpcs3.icns
Normal file
BIN
rpcs3/rpcs3.icns
Normal file
Binary file not shown.
|
@ -422,9 +422,13 @@ void rpcs3_app::OnChangeStyleSheetRequest(const QString& path)
|
||||||
|
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
// If we can't open the file, try the /share or /Resources folder
|
||||||
// If we can't open the file, try the /share folder
|
#if !defined(_WIN32)
|
||||||
|
#ifdef __APPLE__
|
||||||
|
QString share_dir = QCoreApplication::applicationDirPath() + "/../Resources/";
|
||||||
|
#else
|
||||||
QString share_dir = QCoreApplication::applicationDirPath() + "/../share/rpcs3/";
|
QString share_dir = QCoreApplication::applicationDirPath() + "/../share/rpcs3/";
|
||||||
|
#endif
|
||||||
QFile share_file(share_dir + "GuiConfigs/" + QFileInfo(file.fileName()).fileName());
|
QFile share_file(share_dir + "GuiConfigs/" + QFileInfo(file.fileName()).fileName());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -451,7 +455,7 @@ void rpcs3_app::OnChangeStyleSheetRequest(const QString& path)
|
||||||
setStyleSheet(file.readAll());
|
setStyleSheet(file.readAll());
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
#if !defined(_WIN32)
|
||||||
else if (share_file.open(QIODevice::ReadOnly | QIODevice::Text))
|
else if (share_file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
{
|
{
|
||||||
QDir::setCurrent(share_dir);
|
QDir::setCurrent(share_dir);
|
||||||
|
|
|
@ -9,5 +9,6 @@ namespace rpcs3
|
||||||
return RPCS3_GIT_BRANCH;
|
return RPCS3_GIT_BRANCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Make this accessible from cmake and keep in sync with MACOSX_BUNDLE_BUNDLE_VERSION.
|
||||||
const extern utils::version version{ 0, 0, 5, utils::version_type::alpha, 1, RPCS3_GIT_VERSION };
|
const extern utils::version version{ 0, 0, 5, utils::version_type::alpha, 1, RPCS3_GIT_VERSION };
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,10 +338,14 @@ QStringList gui_settings::GetStylesheetEntries()
|
||||||
{
|
{
|
||||||
QStringList nameFilter = QStringList("*.qss");
|
QStringList nameFilter = QStringList("*.qss");
|
||||||
QStringList res = gui::utils::get_dir_entries(m_settingsDir, nameFilter);
|
QStringList res = gui::utils::get_dir_entries(m_settingsDir, nameFilter);
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
#if !defined(_WIN32)
|
||||||
// Makes stylesheets load if using AppImage or installed to /usr/bin
|
// Makes stylesheets load if using AppImage (App Bundle) or installed to /usr/bin
|
||||||
QDir linuxStylesheetDir = QCoreApplication::applicationDirPath() + "/../share/rpcs3/GuiConfigs/";
|
#ifdef __APPLE__
|
||||||
res.append(gui::utils::get_dir_entries(linuxStylesheetDir, nameFilter));
|
QDir platformStylesheetDir = QCoreApplication::applicationDirPath() + "/../Resources/GuiConfigs/";
|
||||||
|
#else
|
||||||
|
QDir platformStylesheetDir = QCoreApplication::applicationDirPath() + "/../share/rpcs3/GuiConfigs/";
|
||||||
|
#endif
|
||||||
|
res.append(gui::utils::get_dir_entries(platformStylesheetDir, nameFilter));
|
||||||
res.removeDuplicates();
|
res.removeDuplicates();
|
||||||
#endif
|
#endif
|
||||||
res.sort(Qt::CaseInsensitive);
|
res.sort(Qt::CaseInsensitive);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue