From 929019e76bf5477ce5b7f71e7c2cb196d17868bd Mon Sep 17 00:00:00 2001 From: Wunk Date: Mon, 11 Mar 2024 10:51:17 -0700 Subject: [PATCH] Refactor build targets into `AlberCore` (#455) * Ignore `.cache` folder * Add `AlberCore` build-target Separate the AlberCore from its frontends. Allowing two front-ends to interface with the same core implementation. This also allows for the core to interface better with unit-testing. * Modularize SDL/Qt frontend Separates all QT/SDL build files and options into the frontend-build-target * Fix optional OpenGL enablement Software renderer requires OpenGL, so AlberCore requries OpenGL. The QT frontend currently requires OpenGL due to `ScreenWidget` * Fix Android build * Fix LTO linking * Fix windows build `LoadLibrary` is a preprocessor that will use either `LoadLibraryW` or `LoadLibraryA` depending on if `UNICODE` is defined or not. In this case we are using an ASCII string literal and and can explicitly specify the usage of `LoadLibraryA` with an ASCII literal. * Bonk * Bonk --------- Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> --- .gitignore | 2 +- CMakeLists.txt | 341 ++++++++++++------------ third_party/duckstation/window_info.cpp | 2 +- 3 files changed, 178 insertions(+), 167 deletions(-) diff --git a/.gitignore b/.gitignore index 7214ef50..786db912 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ build/ .vs/ .vscode/*.log - +.cache/ ipch/ *.aps *.ncb diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dbe438f..d8a69acb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,11 +72,9 @@ endif() if(ENABLE_QT_GUI) find_package(Qt6 REQUIRED COMPONENTS Widgets) - - # We can't use qt_standard_project_setup since it's Qt 6.3+ and we don't need to set the minimum that high - set(CMAKE_AUTOMOC ON) - set(CMAKE_AUTORCC ON) - set(CMAKE_AUTOUIC ON) + if(NOT ENABLE_OPENGL) + message(FATAL_ERROR "Qt frontend requires OpenGL") + endif() endif() set(SDL_STATIC ON CACHE BOOL "" FORCE) @@ -153,9 +151,9 @@ endif() add_subdirectory(third_party/teakra EXCLUDE_FROM_ALL) set(SOURCE_FILES src/emulator.cpp src/io_file.cpp src/config.cpp - src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp - src/core/memory.cpp src/renderer.cpp src/core/renderer_null/renderer_null.cpp - src/http_server.cpp src/stb_image_write.c src/core/cheats.cpp src/core/action_replay.cpp + src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp + src/core/memory.cpp src/renderer.cpp src/core/renderer_null/renderer_null.cpp + src/http_server.cpp src/stb_image_write.c src/core/cheats.cpp src/core/action_replay.cpp src/discord_rpc.cpp src/lua.cpp src/memory_mapped_file.cpp src/miniaudio.cpp ) set(CRYPTO_SOURCE_FILES src/core/crypto/aes_engine.cpp) @@ -199,26 +197,24 @@ set(AUDIO_SOURCE_FILES src/core/audio/dsp_core.cpp src/core/audio/null_core.cpp set(RENDERER_SW_SOURCE_FILES src/core/renderer_sw/renderer_sw.cpp) # Frontend source files -if(NOT ANDROID) - if(ENABLE_QT_GUI) - set(FRONTEND_SOURCE_FILES src/panda_qt/main.cpp src/panda_qt/screen.cpp src/panda_qt/main_window.cpp src/panda_qt/about_window.cpp - src/panda_qt/config_window.cpp src/panda_qt/zep.cpp src/panda_qt/text_editor.cpp src/panda_qt/cheats_window.cpp - ) - set(FRONTEND_HEADER_FILES include/panda_qt/screen.hpp include/panda_qt/main_window.hpp include/panda_qt/about_window.hpp - include/panda_qt/config_window.hpp include/panda_qt/text_editor.hpp include/panda_qt/cheats_window.hpp - ) +if(ENABLE_QT_GUI) + set(FRONTEND_SOURCE_FILES src/panda_qt/main.cpp src/panda_qt/screen.cpp src/panda_qt/main_window.cpp src/panda_qt/about_window.cpp + src/panda_qt/config_window.cpp src/panda_qt/zep.cpp src/panda_qt/text_editor.cpp src/panda_qt/cheats_window.cpp + ) + set(FRONTEND_HEADER_FILES include/panda_qt/screen.hpp include/panda_qt/main_window.hpp include/panda_qt/about_window.hpp + include/panda_qt/config_window.hpp include/panda_qt/text_editor.hpp include/panda_qt/cheats_window.hpp + ) - source_group("Source Files\\Qt" FILES ${FRONTEND_SOURCE_FILES}) - source_group("Header Files\\Qt" FILES ${FRONTEND_HEADER_FILES}) - include_directories(${Qt6Gui_PRIVATE_INCLUDE_DIRS}) + source_group("Source Files\\Qt" FILES ${FRONTEND_SOURCE_FILES}) + source_group("Header Files\\Qt" FILES ${FRONTEND_HEADER_FILES}) + include_directories(${Qt6Gui_PRIVATE_INCLUDE_DIRS}) - include_directories(third_party/zep/include) # Include zep for text editor usage - configure_file(third_party/zep/cmake/config_app.h.cmake ${CMAKE_BINARY_DIR}/zep_config/config_app.h) - include_directories(${CMAKE_BINARY_DIR}/zep_config) - else() - set(FRONTEND_SOURCE_FILES src/panda_sdl/main.cpp src/panda_sdl/frontend_sdl.cpp) - set(FRONTEND_HEADER_FILES "") - endif() + include_directories(third_party/zep/include) # Include zep for text editor usage + configure_file(third_party/zep/cmake/config_app.h.cmake ${CMAKE_BINARY_DIR}/zep_config/config_app.h) + include_directories(${CMAKE_BINARY_DIR}/zep_config) +else() + set(FRONTEND_SOURCE_FILES src/panda_sdl/main.cpp src/panda_sdl/frontend_sdl.cpp) + set(FRONTEND_HEADER_FILES "") endif() set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp @@ -257,10 +253,10 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp ) cmrc_add_resource_library( - resources_console_fonts - NAMESPACE ConsoleFonts - WHENCE "src/core/services/fonts/" - "src/core/services/fonts/CitraSharedFontUSRelocated.bin" + resources_console_fonts + NAMESPACE ConsoleFonts + WHENCE "src/core/services/fonts/" + "src/core/services/fonts/CitraSharedFontUSRelocated.bin" ) set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp @@ -315,62 +311,62 @@ set(RENDERER_VK_SOURCE_FILES "") # Empty by default unless we are compiling with if(ENABLE_OPENGL) # This may look weird but opengl.hpp is our header even if it's in the third_party folder - set(RENDERER_GL_INCLUDE_FILES third_party/opengl/opengl.hpp - include/renderer_gl/renderer_gl.hpp include/renderer_gl/textures.hpp - include/renderer_gl/surfaces.hpp include/renderer_gl/surface_cache.hpp - include/renderer_gl/gl_state.hpp - ) + set(RENDERER_GL_INCLUDE_FILES third_party/opengl/opengl.hpp + include/renderer_gl/renderer_gl.hpp include/renderer_gl/textures.hpp + include/renderer_gl/surfaces.hpp include/renderer_gl/surface_cache.hpp + include/renderer_gl/gl_state.hpp + ) - set(RENDERER_GL_SOURCE_FILES src/core/renderer_gl/renderer_gl.cpp + set(RENDERER_GL_SOURCE_FILES src/core/renderer_gl/renderer_gl.cpp src/core/renderer_gl/textures.cpp src/core/renderer_gl/etc1.cpp src/core/renderer_gl/gl_state.cpp src/host_shaders/opengl_display.frag src/host_shaders/opengl_display.vert src/host_shaders/opengl_vertex_shader.vert src/host_shaders/opengl_fragment_shader.frag - ) + ) set(HEADER_FILES ${HEADER_FILES} ${RENDERER_GL_INCLUDE_FILES}) source_group("Source Files\\Core\\OpenGL Renderer" FILES ${RENDERER_GL_SOURCE_FILES}) - cmrc_add_resource_library( - resources_renderer_gl - NAMESPACE RendererGL - WHENCE "src/host_shaders/" - "src/host_shaders/opengl_display.frag" - "src/host_shaders/opengl_display.vert" - "src/host_shaders/opengl_vertex_shader.vert" - "src/host_shaders/opengl_fragment_shader.frag" - ) + cmrc_add_resource_library( + resources_renderer_gl + NAMESPACE RendererGL + WHENCE "src/host_shaders/" + "src/host_shaders/opengl_display.frag" + "src/host_shaders/opengl_display.vert" + "src/host_shaders/opengl_vertex_shader.vert" + "src/host_shaders/opengl_fragment_shader.frag" + ) endif() if(ENABLE_VULKAN) - find_package( - Vulkan 1.3.206 REQUIRED - COMPONENTS glslangValidator - ) + find_package( + Vulkan 1.3.206 REQUIRED + COMPONENTS glslangValidator + ) - set(RENDERER_VK_INCLUDE_FILES include/renderer_vk/renderer_vk.hpp - include/renderer_vk/vk_api.hpp include/renderer_vk/vk_debug.hpp - include/renderer_vk/vk_descriptor_heap.hpp - include/renderer_vk/vk_descriptor_update_batch.hpp - include/renderer_vk/vk_sampler_cache.hpp - include/renderer_vk/vk_memory.hpp include/renderer_vk/vk_pica.hpp - ) + set(RENDERER_VK_INCLUDE_FILES include/renderer_vk/renderer_vk.hpp + include/renderer_vk/vk_api.hpp include/renderer_vk/vk_debug.hpp + include/renderer_vk/vk_descriptor_heap.hpp + include/renderer_vk/vk_descriptor_update_batch.hpp + include/renderer_vk/vk_sampler_cache.hpp + include/renderer_vk/vk_memory.hpp include/renderer_vk/vk_pica.hpp + ) - set(RENDERER_VK_SOURCE_FILES src/core/renderer_vk/renderer_vk.cpp - src/core/renderer_vk/vk_api.cpp src/core/renderer_vk/vk_debug.cpp - src/core/renderer_vk/vk_descriptor_heap.cpp - src/core/renderer_vk/vk_descriptor_update_batch.cpp - src/core/renderer_vk/vk_sampler_cache.cpp - src/core/renderer_vk/vk_memory.cpp src/core/renderer_vk/vk_pica.cpp - ) + set(RENDERER_VK_SOURCE_FILES src/core/renderer_vk/renderer_vk.cpp + src/core/renderer_vk/vk_api.cpp src/core/renderer_vk/vk_debug.cpp + src/core/renderer_vk/vk_descriptor_heap.cpp + src/core/renderer_vk/vk_descriptor_update_batch.cpp + src/core/renderer_vk/vk_sampler_cache.cpp + src/core/renderer_vk/vk_memory.cpp src/core/renderer_vk/vk_pica.cpp + ) set(HEADER_FILES ${HEADER_FILES} ${RENDERER_VK_INCLUDE_FILES}) source_group("Source Files\\Core\\Vulkan Renderer" FILES ${RENDERER_VK_SOURCE_FILES}) - set(RENDERER_VK_HOST_SHADERS_SOURCE - "src/host_shaders/vulkan_display.frag" - "src/host_shaders/vulkan_display.vert" - ) + set(RENDERER_VK_HOST_SHADERS_SOURCE + "src/host_shaders/vulkan_display.frag" + "src/host_shaders/vulkan_display.vert" + ) set(RENDERER_VK_HOST_SHADERS_FLAGS -e main --target-env vulkan1.1) @@ -383,30 +379,34 @@ if(ENABLE_VULKAN) # Compile each vulkan shader into an .spv file foreach( HOST_SHADER_SOURCE ${RENDERER_VK_HOST_SHADERS_SOURCE} ) - get_filename_component( FILE_NAME ${HOST_SHADER_SOURCE} NAME ) - set( HOST_SHADER_SPIRV "${PROJECT_BINARY_DIR}/host_shaders/${FILE_NAME}.spv" ) - add_custom_command( - OUTPUT ${HOST_SHADER_SPIRV} - COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/host_shaders/" - COMMAND Vulkan::glslangValidator ${RENDERER_VK_HOST_SHADERS_FLAGS} -V "${PROJECT_SOURCE_DIR}/${HOST_SHADER_SOURCE}" -o ${HOST_SHADER_SPIRV} - DEPENDS ${HOST_SHADER_SOURCE} - ) - list( APPEND RENDERER_VK_HOST_SHADERS_SPIRV ${HOST_SHADER_SPIRV} ) + get_filename_component( FILE_NAME ${HOST_SHADER_SOURCE} NAME ) + set( HOST_SHADER_SPIRV "${PROJECT_BINARY_DIR}/host_shaders/${FILE_NAME}.spv" ) + add_custom_command( + OUTPUT ${HOST_SHADER_SPIRV} + COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/host_shaders/" + COMMAND Vulkan::glslangValidator ${RENDERER_VK_HOST_SHADERS_FLAGS} -V "${PROJECT_SOURCE_DIR}/${HOST_SHADER_SOURCE}" -o ${HOST_SHADER_SPIRV} + DEPENDS ${HOST_SHADER_SOURCE} + ) + list( APPEND RENDERER_VK_HOST_SHADERS_SPIRV ${HOST_SHADER_SPIRV} ) endforeach() - cmrc_add_resource_library( - resources_renderer_vk - NAMESPACE RendererVK - WHENCE "${PROJECT_BINARY_DIR}/host_shaders/" - ${RENDERER_VK_HOST_SHADERS_SPIRV} - ) + cmrc_add_resource_library( + resources_renderer_vk + NAMESPACE RendererVK + WHENCE "${PROJECT_BINARY_DIR}/host_shaders/" + ${RENDERER_VK_HOST_SHADERS_SPIRV} + ) endif() source_group("Header Files\\Core" FILES ${HEADER_FILES}) -set(ALL_SOURCES ${SOURCE_FILES} ${FRONTEND_SOURCE_FILES} ${FS_SOURCE_FILES} ${CRYPTO_SOURCE_FILES} ${KERNEL_SOURCE_FILES} +set(ALL_SOURCES ${SOURCE_FILES} ${FS_SOURCE_FILES} ${CRYPTO_SOURCE_FILES} ${KERNEL_SOURCE_FILES} ${LOADER_SOURCE_FILES} ${SERVICE_SOURCE_FILES} ${APPLET_SOURCE_FILES} ${RENDERER_SW_SOURCE_FILES} ${PICA_SOURCE_FILES} ${THIRD_PARTY_SOURCE_FILES} ${AUDIO_SOURCE_FILES} ${HEADER_FILES} ${FRONTEND_HEADER_FILES}) +if(ANDROID) + set(ALL_SOURCES ${ALL_SOURCES} src/jni_driver.cpp) +endif() + if(ENABLE_OPENGL) # Add the OpenGL source files to ALL_SOURCES set(ALL_SOURCES ${ALL_SOURCES} ${RENDERER_GL_SOURCE_FILES}) @@ -417,95 +417,106 @@ if(ENABLE_VULKAN) set(ALL_SOURCES ${ALL_SOURCES} ${RENDERER_VK_SOURCE_FILES}) endif() +add_library(AlberCore STATIC ${ALL_SOURCES}) + if(ANDROID) - set(ALL_SOURCES ${ALL_SOURCES} src/jni_driver.cpp) + target_link_libraries(AlberCore PRIVATE EGL log) endif() -if(BUILD_HYDRA_CORE) - include_directories(third_party/hydra_core/include) - add_library(Alber SHARED ${ALL_SOURCES} src/hydra_core.cpp) - target_compile_definitions(Alber PRIVATE PANDA3DS_HYDRA_CORE=1) +target_link_libraries(AlberCore PRIVATE dynarmic cryptopp glad resources_console_fonts teakra) +target_link_libraries(AlberCore PUBLIC glad) + +if(NOT ANDROID) + target_link_libraries(AlberCore PUBLIC SDL2-static) +endif() + +if(ENABLE_DISCORD_RPC AND NOT ANDROID) + target_compile_definitions(AlberCore PUBLIC "PANDA3DS_ENABLE_DISCORD_RPC=1") + target_link_libraries(AlberCore PRIVATE discord-rpc) +endif() + +if(ENABLE_LUAJIT) + target_compile_definitions(AlberCore PUBLIC "PANDA3DS_ENABLE_LUA=1") + target_link_libraries(AlberCore PRIVATE libluajit) + + # If we're not on Android, link libuv too + if (NOT ANDROID) + target_link_libraries(AlberCore PRIVATE uv_a) + endif() +endif() + +if(ENABLE_OPENGL) + target_compile_definitions(AlberCore PUBLIC "PANDA3DS_ENABLE_OPENGL=1") + target_link_libraries(AlberCore PRIVATE resources_renderer_gl) +endif() + +if(ENABLE_VULKAN) + target_compile_definitions(AlberCore PUBLIC "PANDA3DS_ENABLE_VULKAN=1") + target_link_libraries(AlberCore PRIVATE Vulkan::Vulkan resources_renderer_vk) +endif() + +if(GPU_DEBUG_INFO) + target_compile_definitions(AlberCore PRIVATE GPU_DEBUG_INFO=1) +endif() + +if(ENABLE_USER_BUILD) + target_compile_definitions(AlberCore PRIVATE PANDA3DS_USER_BUILD=1) +endif() + +if(ENABLE_USER_BUILD OR DISABLE_PANIC_DEV) + target_compile_definitions(AlberCore PRIVATE PANDA3DS_LIMITED_PANICS=1) +endif() + +if(ENABLE_HTTP_SERVER) + target_compile_definitions(AlberCore PRIVATE PANDA3DS_ENABLE_HTTP_SERVER=1) +endif() + +# Configure frontend + +if(ENABLE_QT_GUI) + target_compile_definitions(AlberCore PUBLIC "PANDA3DS_FRONTEND_QT=1") else() - add_executable(Alber ${ALL_SOURCES}) + target_compile_definitions(AlberCore PUBLIC "PANDA3DS_FRONTEND_SDL=1") endif() -if(ANDROID) - target_link_libraries(Alber PRIVATE EGL log) +if(NOT BUILD_HYDRA_CORE) + add_executable(Alber ${FRONTEND_SOURCE_FILES} ${FRONTEND_HEADER_FILES}) + target_link_libraries(Alber PRIVATE AlberCore) + + if(ENABLE_QT_GUI) + target_compile_definitions(Alber PUBLIC "ZEP_QT=1") + target_compile_definitions(Alber PUBLIC "ZEP_FEATURE_CPP_FILE_SYSTEM=1") + target_link_libraries(Alber PRIVATE Qt6::Widgets) + + # We can't use qt_standard_project_setup since it's Qt 6.3+ and we don't need to set the minimum that high + set_target_properties(Alber PROPERTIES AUTOMOC ON) + set_target_properties(Alber PROPERTIES AUTORCC ON) + set_target_properties(Alber PROPERTIES AUTOUIC ON) + + if(LINUX OR FREEBSD) + find_package(X11 REQUIRED) + target_link_libraries(Alber PRIVATE ${X11_LIBRARIES}) + + if(ENABLE_OPENGL) + find_package(OpenGL REQUIRED COMPONENTS OpenGL EGL GLX) + target_link_libraries(Alber PRIVATE OpenGL::OpenGL OpenGL::EGL OpenGL::GLX) + endif() + endif() + + qt_add_resources(AlberCore "app_images" + PREFIX "/" + FILES + docs/img/rsob_icon.png docs/img/rstarstruck_icon.png + ) + else() + endif() +elseif(BUILD_HYDRA_CORE) + target_compile_definitions(AlberCore PRIVATE PANDA3DS_HYDRA_CORE=1) + include_directories(third_party/hydra_core/include) + add_library(Alber SHARED src/hydra_core.cpp) + target_link_libraries(Alber PUBLIC AlberCore) endif() if(ENABLE_LTO OR ENABLE_USER_BUILD) set_target_properties(Alber PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) endif() - -target_link_libraries(Alber PRIVATE dynarmic cryptopp glad resources_console_fonts teakra) - -if(NOT ANDROID) - target_link_libraries(Alber PRIVATE SDL2-static) -endif() - -if(ENABLE_DISCORD_RPC AND NOT ANDROID) - target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_DISCORD_RPC=1") - target_link_libraries(Alber PRIVATE discord-rpc) -endif() - -if(ENABLE_LUAJIT) - target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_LUA=1") - target_link_libraries(Alber PRIVATE libluajit) - - # If we're not on Android, link libuv too - if (NOT ANDROID) - target_link_libraries(Alber PRIVATE uv_a) - endif() -endif() - -if(ENABLE_OPENGL) - target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_OPENGL=1") - target_link_libraries(Alber PRIVATE resources_renderer_gl) -endif() - -if(ENABLE_VULKAN) - target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_VULKAN=1") - target_link_libraries(Alber PRIVATE Vulkan::Vulkan resources_renderer_vk) -endif() - -if(ENABLE_QT_GUI) - target_compile_definitions(Alber PUBLIC "PANDA3DS_FRONTEND_QT=1") - target_compile_definitions(Alber PUBLIC "ZEP_QT=1") - target_compile_definitions(Alber PUBLIC "ZEP_FEATURE_CPP_FILE_SYSTEM=1") - - target_link_libraries(Alber PRIVATE Qt6::Widgets) - - if(LINUX OR FREEBSD) - find_package(X11 REQUIRED) - target_link_libraries(Alber PRIVATE ${X11_LIBRARIES}) - - if(ENABLE_OPENGL) - find_package(OpenGL REQUIRED COMPONENTS OpenGL EGL GLX) - target_link_libraries(Alber PRIVATE OpenGL::OpenGL OpenGL::EGL OpenGL::GLX) - endif() - endif() - - qt_add_resources(Alber "app_images" - PREFIX "/" - FILES - docs/img/rsob_icon.png docs/img/rstarstruck_icon.png - ) -else() - target_compile_definitions(Alber PUBLIC "PANDA3DS_FRONTEND_SDL=1") -endif() - -if(GPU_DEBUG_INFO) - target_compile_definitions(Alber PRIVATE GPU_DEBUG_INFO=1) -endif() - -if(ENABLE_USER_BUILD) - target_compile_definitions(Alber PRIVATE PANDA3DS_USER_BUILD=1) -endif() - -if(ENABLE_USER_BUILD OR DISABLE_PANIC_DEV) - target_compile_definitions(Alber PRIVATE PANDA3DS_LIMITED_PANICS=1) -endif() - -if(ENABLE_HTTP_SERVER) - target_compile_definitions(Alber PRIVATE PANDA3DS_ENABLE_HTTP_SERVER=1) -endif() diff --git a/third_party/duckstation/window_info.cpp b/third_party/duckstation/window_info.cpp index 5f131826..4e56ab0c 100644 --- a/third_party/duckstation/window_info.cpp +++ b/third_party/duckstation/window_info.cpp @@ -16,7 +16,7 @@ static bool GetRefreshRateFromDWM(HWND hwnd, float* refresh_rate) if (!load_tried) { load_tried = true; - dwm_module = LoadLibrary(L"dwmapi.dll"); + dwm_module = LoadLibraryA("dwmapi.dll"); if (dwm_module) { std::atexit([]() {