Build: Improve MacOS support
This commit is contained in:
parent
abb39e8a00
commit
b30c86ed75
|
@ -46,6 +46,9 @@ endif()
|
||||||
if((LINUX OR FREEBSD) AND NOT ANDROID)
|
if((LINUX OR FREEBSD) AND NOT ANDROID)
|
||||||
option(USE_DBUS "Enable DBus support for screensaver inhibiting" ON)
|
option(USE_DBUS "Enable DBus support for screensaver inhibiting" ON)
|
||||||
endif()
|
endif()
|
||||||
|
if(APPLE)
|
||||||
|
option(SKIP_POSTPROCESS_BUNDLE "Disable bundle post-processing, including Qt additions" OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
|
|
@ -88,7 +88,8 @@ if(${CPU_ARCH} STREQUAL "aarch64")
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
# Currently disabled becuase the old rec sucks.
|
||||||
message("Enabling vixl debug assertions")
|
#if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||||
target_compile_definitions(vixl PUBLIC VIXL_DEBUG)
|
# message("Enabling vixl debug assertions")
|
||||||
endif()
|
# target_compile_definitions(vixl PUBLIC VIXL_DEBUG)
|
||||||
|
#endif()
|
||||||
|
|
|
@ -167,7 +167,30 @@ if(ENABLE_DISCORD_PRESENCE)
|
||||||
target_link_libraries(core PRIVATE discord-rpc)
|
target_link_libraries(core PRIVATE discord-rpc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Copy the provided data directory to the output directory.
|
# Copy the provided data directory to the output directory. Borrowed from PCSX2.
|
||||||
add_custom_command(TARGET core POST_BUILD
|
function(add_resources target path basedir)
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/data" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
get_filename_component(dir ${path} DIRECTORY)
|
||||||
)
|
file(RELATIVE_PATH subdir ${basedir} ${dir})
|
||||||
|
if(APPLE)
|
||||||
|
target_sources(${target} PRIVATE ${path})
|
||||||
|
set_source_files_properties(${path} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/${subdir})
|
||||||
|
else()
|
||||||
|
add_custom_command(TARGET ${target} POST_BUILD
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:${target}>/resources/${subdir}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${path}" "$<TARGET_FILE_DIR:${target}>/resources/${subdir}")
|
||||||
|
endif()
|
||||||
|
source_group(Resources/${subdir} FILES ${path})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(add_core_resources target)
|
||||||
|
add_util_resources(${target})
|
||||||
|
|
||||||
|
file(GLOB_RECURSE RESOURCE_FILES ${CMAKE_SOURCE_DIR}/data/resources/*)
|
||||||
|
foreach(path IN LISTS RESOURCE_FILES)
|
||||||
|
get_filename_component(file ${path} NAME)
|
||||||
|
if("${file}" MATCHES "^\\.") # Don't copy macOS garbage (mainly Finder's .DS_Store files) into application
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
add_resources(${target} ${path} ${CMAKE_SOURCE_DIR}/data/resources/)
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
|
@ -1904,6 +1904,13 @@ void System::Throttle()
|
||||||
Common::Timer::SleepUntil(s_next_frame_time, false);
|
Common::Timer::SleepUntil(s_next_frame_time, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Log_DevPrintf("Asked for %.2f ms, slept for %.2f ms, %.2f ms late",
|
||||||
|
Common::Timer::ConvertValueToMilliseconds(s_next_frame_time - current_time),
|
||||||
|
Common::Timer::ConvertValueToMilliseconds(Common::Timer::GetCurrentValue() - current_time),
|
||||||
|
Common::Timer::ConvertValueToMilliseconds(Common::Timer::GetCurrentValue() - s_next_frame_time));
|
||||||
|
#endif
|
||||||
|
|
||||||
s_next_frame_time += s_frame_period;
|
s_next_frame_time += s_frame_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,14 +164,16 @@ set(TS_FILES
|
||||||
translations/duckstation-qt_zh-cn.ts
|
translations/duckstation-qt_zh-cn.ts
|
||||||
)
|
)
|
||||||
|
|
||||||
set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations")
|
|
||||||
qt6_add_translation(QM_FILES ${TS_FILES})
|
|
||||||
|
|
||||||
add_executable(duckstation-qt ${SRCS} ${QM_FILES})
|
add_executable(duckstation-qt ${SRCS} ${QM_FILES})
|
||||||
target_precompile_headers(duckstation-qt PRIVATE "pch.h")
|
target_precompile_headers(duckstation-qt PRIVATE "pch.h")
|
||||||
target_include_directories(duckstation-qt PRIVATE "${Qt6Gui_PRIVATE_INCLUDE_DIRS}" "${CMAKE_CURRENT_SOURCE_DIR}")
|
target_include_directories(duckstation-qt PRIVATE "${Qt6Gui_PRIVATE_INCLUDE_DIRS}" "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
target_link_libraries(duckstation-qt PRIVATE core common imgui minizip scmversion Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network)
|
target_link_libraries(duckstation-qt PRIVATE core common imgui minizip scmversion Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network)
|
||||||
|
|
||||||
|
# Our Qt builds may have exceptions on, so force them off.
|
||||||
|
target_compile_definitions(duckstation-qt PRIVATE QT_NO_EXCEPTIONS)
|
||||||
|
|
||||||
|
add_core_resources(duckstation-qt)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(duckstation-qt PRIVATE duckstation-qt.rc)
|
target_sources(duckstation-qt PRIVATE duckstation-qt.rc)
|
||||||
|
|
||||||
|
@ -196,60 +198,45 @@ if(WIN32)
|
||||||
add_custom_command(TARGET duckstation-qt POST_BUILD
|
add_custom_command(TARGET duckstation-qt POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/qt.conf.win" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qt.conf"
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/qt.conf.win" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qt.conf"
|
||||||
)
|
)
|
||||||
endif()
|
#set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations")
|
||||||
|
elseif(APPLE)
|
||||||
|
# Don't generate a bundle for XCode, it makes code signing fail...
|
||||||
|
if(NOT CMAKE_GENERATOR MATCHES "Xcode")
|
||||||
|
set(BUNDLE_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DuckStation.app)
|
||||||
|
set_target_properties(duckstation-qt PROPERTIES
|
||||||
|
MACOSX_BUNDLE true
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
|
||||||
|
OUTPUT_NAME DuckStation
|
||||||
|
)
|
||||||
|
|
||||||
if(APPLE AND NOT CMAKE_GENERATOR MATCHES "Xcode")
|
# Inject Qt Libraries into bundle.
|
||||||
set(BUNDLE_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DuckStation.app)
|
if(NOT SKIP_POSTPROCESS_BUNDLE)
|
||||||
|
find_program(MACDEPLOYQT_EXE macdeployqt HINTS "${QT_BINARY_DIRECTORY}")
|
||||||
# Ask for an application bundle.
|
add_custom_target(duckstation-postprocess-bundle ALL
|
||||||
set_target_properties(duckstation-qt PROPERTIES
|
COMMAND "${MACDEPLOYQT_EXE}" "${BUNDLE_PATH}" -no-strip
|
||||||
MACOSX_BUNDLE true
|
)
|
||||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
|
add_dependencies(duckstation-postprocess-bundle duckstation-qt)
|
||||||
OUTPUT_NAME DuckStation
|
endif()
|
||||||
)
|
endif()
|
||||||
|
|
||||||
# Use macdeployqt to inject Qt into the bundle.
|
|
||||||
get_target_property(MOC_EXECUTABLE_LOCATION Qt6::moc IMPORTED_LOCATION)
|
|
||||||
get_filename_component(QT_BINARY_DIRECTORY "${MOC_EXECUTABLE_LOCATION}" DIRECTORY)
|
|
||||||
find_program(MACDEPLOYQT_EXE macdeployqt HINTS "${QT_BINARY_DIRECTORY}")
|
|
||||||
add_custom_target(duckstation-postprocess-bundle ALL
|
|
||||||
COMMAND "${MACDEPLOYQT_EXE}" "${BUNDLE_PATH}" -no-strip
|
|
||||||
)
|
|
||||||
add_dependencies(duckstation-postprocess-bundle duckstation-qt)
|
|
||||||
|
|
||||||
# Copy icon into the bundle
|
# Copy icon into the bundle
|
||||||
target_sources(duckstation-qt PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/DuckStation.icns")
|
target_sources(duckstation-qt PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/DuckStation.icns")
|
||||||
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/DuckStation.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/DuckStation.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||||
|
|
||||||
# Copy resources into the bundle
|
# Translation setup
|
||||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/data/resources")
|
qt_add_lrelease(duckstation-qt TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE QM_FILES)
|
||||||
file(GLOB_RECURSE resources RELATIVE "${CMAKE_SOURCE_DIR}/data/resources" "${CMAKE_SOURCE_DIR}/data/resources/*")
|
foreach (QM_FILE IN LISTS QM_FILES)
|
||||||
foreach(res ${resources})
|
target_sources(duckstation-qt PRIVATE ${QM_FILE})
|
||||||
target_sources(duckstation-qt PRIVATE "${CMAKE_SOURCE_DIR}/data/resources/${res}")
|
set_source_files_properties(${QM_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/translations)
|
||||||
get_filename_component(resdir "${res}" DIRECTORY)
|
endforeach()
|
||||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/data/resources/${res}" PROPERTIES
|
else()
|
||||||
MACOSX_PACKAGE_LOCATION "Resources/${resdir}")
|
# TODO: Copy base translations.
|
||||||
source_group("Resources" FILES "${CMAKE_SOURCE_DIR}/data/resources/${res}")
|
qt_add_lrelease(duckstation-qt TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE QM_FILES)
|
||||||
endforeach()
|
set(QM_OUTPUT_DIR "$<TARGET_FILE_DIR:duckstation-qt>/translations")
|
||||||
|
add_custom_command(TARGET duckstation-qt POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${QM_OUTPUT_DIR}")
|
||||||
# Copy translations into the bundle
|
foreach (QM_FILE IN LISTS QM_FILES)
|
||||||
add_custom_command(TARGET duckstation-qt
|
get_filename_component(QM_FILE_NAME ${QM_FILE} NAME)
|
||||||
POST_BUILD
|
add_custom_command(TARGET duckstation-qt POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${QM_FILE}" "${QM_OUTPUT_DIR}/${QM_FILE_NAME}")
|
||||||
COMMAND mkdir -p $<TARGET_FILE_DIR:duckstation-qt>/translations
|
endforeach()
|
||||||
COMMAND cp ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations/*.qm $<TARGET_FILE_DIR:duckstation-qt>/translations)
|
|
||||||
|
|
||||||
# Copy MoltenVK into the bundle
|
|
||||||
unset(MOLTENVK_PATH CACHE)
|
|
||||||
find_file(MOLTENVK_PATH NAMES
|
|
||||||
libMoltenVK.dylib
|
|
||||||
lib/libMoltenVK.dylib
|
|
||||||
)
|
|
||||||
if (MOLTENVK_PATH)
|
|
||||||
target_sources(duckstation-qt PRIVATE "${MOLTENVK_PATH}")
|
|
||||||
set_source_files_properties("${MOLTENVK_PATH}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
|
||||||
message(STATUS "Using MoltenVK from ${MOLTENVK_PATH}")
|
|
||||||
else()
|
|
||||||
message(WARNING "MoltenVK not found in path, it will depend on the target system having it.")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#include "qthost.h"
|
#include "qthost.h"
|
||||||
|
@ -1939,7 +1939,7 @@ bool QtHost::ParseCommandLineParametersAndInitializeConfig(QApplication& app,
|
||||||
{
|
{
|
||||||
// NOTE: No point translating this, because no config means the language won't be loaded anyway.
|
// NOTE: No point translating this, because no config means the language won't be loaded anyway.
|
||||||
QMessageBox::critical(nullptr, QStringLiteral("Error"), QStringLiteral("Failed to initialize config."));
|
QMessageBox::critical(nullptr, QStringLiteral("Error"), QStringLiteral("Failed to initialize config."));
|
||||||
return EXIT_FAILURE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the file we're starting actually exists.
|
// Check the file we're starting actually exists.
|
||||||
|
|
|
@ -71,7 +71,12 @@ void QtHost::InstallTranslator()
|
||||||
QString::fromStdString(Host::GetBaseStringSettingValue("Main", "Language", GetDefaultLanguage())));
|
QString::fromStdString(Host::GetBaseStringSettingValue("Main", "Language", GetDefaultLanguage())));
|
||||||
|
|
||||||
// install the base qt translation first
|
// install the base qt translation first
|
||||||
const QString base_dir(QStringLiteral("%1/translations").arg(qApp->applicationDirPath()));
|
#ifndef __APPLE__
|
||||||
|
const QString base_dir = QStringLiteral("%1/translations").arg(qApp->applicationDirPath());
|
||||||
|
#else
|
||||||
|
const QString base_dir = QStringLiteral("%1/../Resources/translations").arg(qApp->applicationDirPath());
|
||||||
|
#endif
|
||||||
|
|
||||||
QString base_path(QStringLiteral("%1/qtbase_%2.qm").arg(base_dir).arg(language));
|
QString base_path(QStringLiteral("%1/qtbase_%2.qm").arg(base_dir).arg(language));
|
||||||
bool has_base_ts = QFile::exists(base_path);
|
bool has_base_ts = QFile::exists(base_path);
|
||||||
if (!has_base_ts)
|
if (!has_base_ts)
|
||||||
|
|
|
@ -157,6 +157,7 @@ if(ENABLE_OPENGL)
|
||||||
gl/context_agl.mm
|
gl/context_agl.mm
|
||||||
gl/context_agl.h
|
gl/context_agl.h
|
||||||
)
|
)
|
||||||
|
set_source_files_properties(gl/context_agl.mm PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -191,11 +192,6 @@ if(ENABLE_VULKAN)
|
||||||
vulkan_texture.h
|
vulkan_texture.h
|
||||||
)
|
)
|
||||||
target_compile_definitions(util PUBLIC "WITH_VULKAN=1")
|
target_compile_definitions(util PUBLIC "WITH_VULKAN=1")
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
# Needed for Vulkan Swap Chain.
|
|
||||||
target_link_libraries(util PRIVATE "objc")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_SDL2)
|
if(USE_SDL2)
|
||||||
|
@ -287,3 +283,21 @@ elseif(NOT ANDROID)
|
||||||
platform_misc_unix.cpp
|
platform_misc_unix.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
function(add_util_resources target)
|
||||||
|
if(APPLE)
|
||||||
|
# Copy MoltenVK into the bundle
|
||||||
|
unset(MOLTENVK_PATH CACHE)
|
||||||
|
find_file(MOLTENVK_PATH NAMES
|
||||||
|
libMoltenVK.dylib
|
||||||
|
lib/libMoltenVK.dylib
|
||||||
|
)
|
||||||
|
if (MOLTENVK_PATH)
|
||||||
|
target_sources(${target} PRIVATE "${MOLTENVK_PATH}")
|
||||||
|
set_source_files_properties("${MOLTENVK_PATH}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||||
|
message(STATUS "Using MoltenVK from ${MOLTENVK_PATH}")
|
||||||
|
else()
|
||||||
|
message(WARNING "MoltenVK not found in path, it will depend on the target system having it.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
Loading…
Reference in New Issue