From 18135424df0adbd3052849d9179b19da84b21771 Mon Sep 17 00:00:00 2001 From: crueter Date: Thu, 4 Dec 2025 06:00:58 +0100 Subject: [PATCH] [cmake] more modules, general "cleanup" (#3126) Successor to that old MoltenVK PR. Does a lot of cleanups within root CMakeLists.txt, hands over MoltenVK and VulkanValidationLayers to CPMUtil, and separates out common operations into my modules. Hopefully reduces the monstrosity that is root CMakeLists.txt. Please test: - builds on all platforms - VulkanValidationLayers Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3126 Reviewed-by: Lizzie Reviewed-by: CamilleLaVey --- .ci/license-header.sh | 2 +- CMakeLists.txt | 381 ++---------------- CMakeModules/GetSCMRev.cmake | 49 --- cpmfile.json | 12 +- externals/CMakeLists.txt | 14 + externals/cmake-modules/DefaultConfig.cmake | 17 + .../cmake-modules/DetectArchitecture.cmake | 225 +++++++++++ externals/cmake-modules/DetectPlatform.cmake | 151 +++++++ externals/cmake-modules/FasterLinker.cmake | 58 +++ .../GetGitRevisionDescription.cmake | 162 -------- .../GetGitRevisionDescription.cmake.in | 45 --- externals/cmake-modules/GetSCMRev.cmake | 85 ++++ externals/cmake-modules/UseCcache.cmake | 34 ++ externals/cmake-modules/UseLTO.cmake | 17 + externals/cpmfile.json | 20 +- src/dynarmic/CMakeLists.txt | 14 +- .../TargetArchitectureSpecificSources.cmake | 5 +- src/dynarmic/tests/CMakeLists.txt | 2 +- src/yuzu/CMakeLists.txt | 6 - tools/cpm/check-updates.sh | 26 +- tools/cpm/download.sh | 14 +- 21 files changed, 699 insertions(+), 640 deletions(-) delete mode 100644 CMakeModules/GetSCMRev.cmake create mode 100644 externals/cmake-modules/DefaultConfig.cmake create mode 100644 externals/cmake-modules/DetectArchitecture.cmake create mode 100644 externals/cmake-modules/DetectPlatform.cmake create mode 100644 externals/cmake-modules/FasterLinker.cmake delete mode 100644 externals/cmake-modules/GetGitRevisionDescription.cmake delete mode 100644 externals/cmake-modules/GetGitRevisionDescription.cmake.in create mode 100644 externals/cmake-modules/GetSCMRev.cmake create mode 100644 externals/cmake-modules/UseCcache.cmake create mode 100644 externals/cmake-modules/UseLTO.cmake diff --git a/.ci/license-header.sh b/.ci/license-header.sh index 784c6bac5a..d49714dae1 100755 --- a/.ci/license-header.sh +++ b/.ci/license-header.sh @@ -4,7 +4,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # specify full path if dupes may exist -EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake renderdoc_app.h tools/cpm tools/shellcheck.sh tools/update-cpm.sh tools/windows/vcvarsall.sh externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder" +EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake renderdoc_app.h tools/cpm tools/shellcheck.sh tools/update-cpm.sh tools/windows/vcvarsall.sh externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder externals/cmake-modules" # license header constants, please change when needed :)))) YEAR=2025 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a108e47af..1368ce3669 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,73 +5,23 @@ cmake_minimum_required(VERSION 3.22) project(yuzu) -if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") - set(PLATFORM_SUN ON) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") - set(PLATFORM_FREEBSD ON) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD") - set(PLATFORM_OPENBSD ON) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD") - set(PLATFORM_NETBSD ON) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "DragonFly") - set(PLATFORM_DRAGONFLYBSD ON) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Haiku") - set(PLATFORM_HAIKU ON) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - set(PLATFORM_LINUX ON) -endif() - -# dumb heuristic to detect msys2 -if (CMAKE_COMMAND MATCHES "msys64") - set(PLATFORM_MSYS ON) -endif() - -if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set(CXX_CLANG ON) - if (MSVC) - set(CXX_CLANG_CL ON) - endif() -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(CXX_GCC ON) -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(CXX_CL ON) -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") - set(CXX_ICC ON) -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - set(CXX_APPLE ON) -endif() - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") -# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/11112 -# This works totally fine on MinGW64, but not CLANG{,ARM}64 -if(MINGW AND CXX_CLANG) - set(CMAKE_SYSTEM_VERSION 10.0.0) -endif() +set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm) -# NB: this does not account for SPARC -# If you get Eden working on SPARC, please shoot crueter@crueter.xyz multiple emails -# and you will be hailed for eternity -if (PLATFORM_SUN) - # Terrific Solaris pkg shenanigans - list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake") - - # Amazing - absolutely incredible - list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake") - - # For some mighty reason, doing a normal release build sometimes may not trigger - # the proper -O3 switch to materialize - if (CMAKE_BUILD_TYPE MATCHES "Release") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") - endif() - if (CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") - endif() +include(DetectPlatform) +include(DetectArchitecture) +include(DefaultConfig) +include(DownloadExternals) +include(CMakeDependentOption) +include(CTest) +include(CPMUtil) + +DetectArchitecture() + +if (NOT DEFINED ARCHITECTURE) + message(FATAL_ERROR "Architecture didn't make it out of scope, did you delete DetectArchitecture.cmake?") endif() # Needed for FFmpeg w/ VAAPI and DRM @@ -90,34 +40,10 @@ if (PLATFORM_NETBSD) set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH}:${CMAKE_SYSROOT}/usr/pkg/lib/ffmpeg7/pkgconfig") endif() -# MSYS2 utilities -if (PLATFORM_MSYS) - include(FixMsysPaths) - # really, really dumb heuristic to detect what environment we are in - macro(system var) - if (CMAKE_COMMAND MATCHES ${var}) - set(MSYSTEM ${var}) - endif() - endmacro() - - system(mingw64) - system(clang64) - system(clangarm64) - system(ucrt64) - - if (NOT DEFINED MSYSTEM) - set(MSYSTEM msys2) - endif() - - # we (generally) want to prioritize environment-specific binaries if possible - # some, like autoconf, are not present on environments besides msys2 though - set(CMAKE_PROGRAM_PATH C:/msys64/${MSYSTEM}/bin C:/msys64/usr/bin) - set(ENV{PKG_CONFIG_PATH} C:/msys64/${MSYSTEM}/lib/pkgconfig) -endif() - # static stuff option(YUZU_STATIC_BUILD "Use static libraries and executables if available" OFF) +# TODO: StaticBuild.cmake if (YUZU_STATIC_BUILD) include(StaticQtLibs) @@ -177,92 +103,6 @@ if (YUZU_STATIC_BUILD) endif() endif() -# Detect current compilation architecture and create standard definitions -# ======================================================================= - -include(CheckSymbolExists) -function(detect_architecture symbol arch) - if (NOT DEFINED ARCHITECTURE) - set(CMAKE_REQUIRED_QUIET 1) - check_symbol_exists("${symbol}" "" ARCHITECTURE_${arch}) - unset(CMAKE_REQUIRED_QUIET) - - # The output variable needs to be unique across invocations otherwise - # CMake's crazy scope rules will keep it defined - if (ARCHITECTURE_${arch}) - set(ARCHITECTURE "${arch}" PARENT_SCOPE) - set(ARCHITECTURE_${arch} 1 PARENT_SCOPE) - add_definitions("-DARCHITECTURE_${arch}=1") - endif() - endif() -endfunction() - -if (NOT ENABLE_GENERIC) - # https://sourceforge.net/p/predef/wiki/Architectures/ - # TODO: THIS IS FUCKING FLAWED ONLY THE FIRST SYMBOL THAT APPEARS WILL BE CONSIDERED :( - if (MSVC) - detect_architecture("_M_AMD64" x86_64) - detect_architecture("_M_IX86" x86) - detect_architecture("_M_ARM" arm) - detect_architecture("_M_ARM64" arm64) - else() - detect_architecture("__x86_64__" x86_64) - detect_architecture("__i386__" x86) - detect_architecture("__arm__" arm) - detect_architecture("__aarch64__" arm64) - endif() - detect_architecture("__ARM64__" arm64) - detect_architecture("__aarch64__" arm64) - detect_architecture("_M_ARM64" arm64) - - detect_architecture("__arm__" arm) - detect_architecture("__TARGET_ARCH_ARM" arm) - detect_architecture("_M_ARM" arm) - - detect_architecture("__x86_64" x86_64) - detect_architecture("__x86_64__" x86_64) - detect_architecture("__amd64" x86_64) - detect_architecture("_M_X64" x86_64) - - detect_architecture("__i386" x86) - detect_architecture("__i386__" x86) - detect_architecture("_M_IX86" x86) - - detect_architecture("__ia64" ia64) - detect_architecture("__ia64__" ia64) - detect_architecture("_M_IA64" ia64) - - detect_architecture("__mips" mips) - detect_architecture("__mips__" mips) - detect_architecture("_M_MRX000" mips) - - detect_architecture("__powerpc64__" ppc64) - detect_architecture("__ppc64__" ppc64) - detect_architecture("__PPC64__" ppc64) - detect_architecture("_ARCH_PPC64" ppc64) - - detect_architecture("__ppc__" ppc) - detect_architecture("__ppc" ppc) - detect_architecture("__powerpc__" ppc) - detect_architecture("_ARCH_COM" ppc) - detect_architecture("_ARCH_PWR" ppc) - detect_architecture("_ARCH_PPC" ppc) - detect_architecture("_M_MPPC" ppc) - detect_architecture("_M_PPC" ppc) - - detect_architecture("__riscv" riscv) - - detect_architecture("__EMSCRIPTEN__" wasm) -endif() - -if (NOT DEFINED ARCHITECTURE) - set(ARCHITECTURE "GENERIC") - set(ARCHITECTURE_GENERIC 1) - add_definitions(-DARCHITECTURE_GENERIC=1) -endif() - -message(STATUS "Target architecture: ${ARCHITECTURE}") - if (MSVC AND ARCHITECTURE_x86) message(FATAL_ERROR "Attempting to build with the x86 environment is not supported. \ This can typically happen if you used the Developer Command Prompt from the start menu; \ @@ -292,21 +132,11 @@ if (CXX_CLANG_CL) endif() endif() -set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm) - -include(DownloadExternals) -include(CMakeDependentOption) -include(CTest) - # Disable Warnings as Errors for MSVC if (MSVC AND NOT CXX_CLANG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-") endif() -if (PLATFORM_FREEBSD OR PLATFORM_DRAGONFLYBSD) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/local/lib") -endif() - # Set bundled sdl2/qt as dependent options. # On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion cmake_dependent_option(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF) @@ -358,13 +188,7 @@ option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}") option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF) if(YUZU_ENABLE_LTO) - include(CheckIPOSupported) - check_ipo_supported(RESULT COMPILER_SUPPORTS_LTO) - if(NOT COMPILER_SUPPORTS_LTO) - message(FATAL_ERROR "Your compiler does not support interprocedural optimization (IPO). Re-run CMake with -DYUZU_ENABLE_LTO=OFF.") - endif() - set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ${COMPILER_SUPPORTS_LTO}) + include(UseLTO) endif() option(USE_CCACHE "Use ccache for compilation" OFF) @@ -391,7 +215,6 @@ if(USE_CCACHE) endif() endif() -# TODO(crueter): CI this? option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON) option(YUZU_LEGACY "Apply patches that improve compatibility with older GPUs (e.g. Snapdragon 865) at the cost of performance" OFF) @@ -401,12 +224,12 @@ cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "ENABLE_SDL2;NOT ANDROID" OFF) -cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF) +cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR PLATFORM_LINUX" OFF) option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" ON) set(YUZU_TZDB_PATH "" CACHE STRING "Path to a pre-downloaded timezone database") -cmake_dependent_option(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "LINUX" OFF) +cmake_dependent_option(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "PLATFORM_LINUX" OFF) cmake_dependent_option(YUZU_USE_BUNDLED_MOLTENVK "Download bundled MoltenVK lib" ON "APPLE" OFF) @@ -438,41 +261,15 @@ endif() # TODO(crueter): CPM this if (ANDROID AND YUZU_DOWNLOAD_ANDROID_VVL) - set(vvl_version "1.4.328.0") - set(vvl_zip_file "${CMAKE_BINARY_DIR}/externals/vvl-android-${vvl_version}.zip") - if (NOT EXISTS "${vvl_zip_file}") - # Download and extract validation layer release to externals directory - set(vvl_base_url "https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download") - file(DOWNLOAD "${vvl_base_url}/vulkan-sdk-${vvl_version}/android-binaries-${vvl_version}.zip" - "${vvl_zip_file}" SHOW_PROGRESS) - execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${vvl_zip_file}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals") - endif() + AddJsonPackage(vulkan-validation-layers) - # Copy the arm64 binary to src/android/app/main/jniLibs - if (ARCHITECTURE_arm64) - set(vvl_abi arm64-v8a) - elseif(ARCHITECTURE_x86_64) - set(vvl_abi x86_64) - endif() + set(abi ${CMAKE_ANDROID_ARCH_ABI}) - set(vvl_lib_path "${CMAKE_CURRENT_SOURCE_DIR}/src/android/app/src/main/jniLibs/${vvl_abi}/") - file(COPY "${CMAKE_BINARY_DIR}/externals/android-binaries-${vvl_version}/${vvl_abi}/libVkLayer_khronos_validation.so" + set(vvl_lib_path "${CMAKE_CURRENT_SOURCE_DIR}/src/android/app/src/main/jniLibs/${abi}/") + file(COPY "${VVL_SOURCE_DIR}/${abi}/libVkLayer_khronos_validation.so" DESTINATION "${vvl_lib_path}") endif() -if (ANDROID) - set(CMAKE_SKIP_INSTALL_RULES ON) - set(CMAKE_POLICY_VERSION_MINIMUM 3.5) # Workaround for Oboe -endif() - -# Default to a Release build -get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) - message(STATUS "Defaulting to a Release build") -endif() - if(EXISTS ${PROJECT_SOURCE_DIR}/hooks/pre-commit AND NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit) if (EXISTS ${PROJECT_SOURCE_DIR}/.git/) message(STATUS "Copying pre-commit hook") @@ -480,25 +277,23 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/hooks/pre-commit AND NOT EXISTS ${PROJECT_SOURCE endif() endif() -configure_file(${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc - ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc +set(compat_base dist/compatibility_list/compatibility_list) +set(compat_qrc ${compat_base}.qrc) +set(compat_json ${compat_base}.json) + +configure_file(${PROJECT_SOURCE_DIR}/${compat_qrc} + ${PROJECT_BINARY_DIR}/${compat_qrc} COPYONLY) -if (EXISTS ${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.json) - configure_file("${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.json" - "${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json" +if (EXISTS ${PROJECT_SOURCE_DIR}/${compat_json}) + configure_file("${PROJECT_SOURCE_DIR}/${compat_json}" + "${PROJECT_BINARY_DIR}/${compat_json}" COPYONLY) endif() -if (ENABLE_COMPATIBILITY_LIST_DOWNLOAD AND NOT EXISTS ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json) - message(STATUS "Downloading compatibility list for yuzu...") - file(DOWNLOAD - https://api.yuzu-emu.org/gamedb/ - "${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json" SHOW_PROGRESS) -endif() - -if (NOT EXISTS ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json) - file(WRITE ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json "") +# TODO: Compat list download +if (NOT EXISTS ${PROJECT_BINARY_DIR}/${compat_json}) + file(WRITE ${PROJECT_BINARY_DIR}/${compat_json} "") endif() if (YUZU_LEGACY) @@ -580,8 +375,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # System imported libraries # ======================================================================= -include(CPMUtil) - # openssl funniness if (ENABLE_OPENSSL) if (YUZU_USE_BUNDLED_OPENSSL) @@ -673,6 +466,7 @@ if (YUZU_USE_CPM) add_library(Opus::opus ALIAS opus) endif() else() + # TODO: we can probably just use CPM for this... right? # Enforce the search mode of non-required packages for better and shorter failure messages find_package(fmt 8 REQUIRED) @@ -737,10 +531,9 @@ endfunction() if (APPLE) # Umbrella framework for everything GUI-related - find_library(COCOA_LIBRARY Cocoa) + find_library(COCOA_LIBRARY Cocoa REQUIRED) + find_library(IOKIT_LIBRARY IOKit REQUIRED) set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) - # find_library(ICONV_LIBRARY iconv REQUIRED) - # list(APPEND PLATFORM_LIBRARIES ${ICONV_LIBRARY}) elseif (WIN32) # Target Windows 10 add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00) @@ -881,11 +674,6 @@ if(ENABLE_QT) set_target_properties(Qt6::Platform PROPERTIES INTERFACE_COMPILE_FEATURES "") endif() -if (UNIX AND NOT APPLE AND NOT ANDROID) - find_package(PkgConfig REQUIRED) - pkg_check_modules(LIBVA libva) -endif() - if (NOT (YUZU_USE_BUNDLED_FFMPEG OR YUZU_USE_EXTERNAL_FFMPEG)) # Use system installed FFmpeg find_package(FFmpeg REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS}) @@ -912,54 +700,6 @@ endif() set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -# Setup a custom clang-format target (if clang-format can be found) that will run -# against all the src files. This should be used before making a pull request. -# ======================================================================= - -set(CLANG_FORMAT_POSTFIX "-15") -find_program(CLANG_FORMAT - NAMES clang-format${CLANG_FORMAT_POSTFIX} - clang-format - PATHS ${PROJECT_BINARY_DIR}/externals) -# if find_program doesn't find it, try to download from externals -if (NOT CLANG_FORMAT) - if (WIN32 AND NOT CMAKE_CROSSCOMPILING) - message(STATUS "Clang format not found! Downloading...") - set(CLANG_FORMAT "${PROJECT_BINARY_DIR}/externals/clang-format${CLANG_FORMAT_POSTFIX}.exe") - file(DOWNLOAD - https://github.com/eden-emulator/ext-windows-bin/raw/master/clang-format${CLANG_FORMAT_POSTFIX}.exe - "${CLANG_FORMAT}" SHOW_PROGRESS - STATUS DOWNLOAD_SUCCESS) - if (NOT DOWNLOAD_SUCCESS EQUAL 0) - message(WARNING "Could not download clang format! Disabling the clang format target") - file(REMOVE ${CLANG_FORMAT}) - unset(CLANG_FORMAT) - endif() - else() - message(WARNING "Clang format not found! Disabling the clang format target") - endif() -endif() - -if (CLANG_FORMAT) - set(SRCS ${PROJECT_SOURCE_DIR}/src) - set(CCOMMENT "Running clang format against all the .h and .cpp files in src/") - if (WIN32) - add_custom_target(clang-format - COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}" - COMMENT ${CCOMMENT}) - elseif(MINGW) - add_custom_target(clang-format - COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp | xargs `cygpath -u ${CLANG_FORMAT}` -i - COMMENT ${CCOMMENT}) - else() - add_custom_target(clang-format - COMMAND find ${SRCS} -iname *.h -o -iname *.cpp | xargs ${CLANG_FORMAT} -i - COMMENT ${CCOMMENT}) - endif() - unset(SRCS) - unset(CCOMMENT) -endif() - # Include source code # =================== @@ -993,47 +733,8 @@ if (MSVC AND CXX_CLANG) link_libraries(llvm-mingw-runtime) endif() -#[[ - search order: - - gold (GCC only) - the best, generally, but unfortunately not packaged anymore - - mold (GCC only) - generally does well on GCC - - ldd - preferred on clang - - bfd - the final fallback - - If none are found (macOS uses ld.prime, etc) just use the default linker -]] if (YUZU_USE_FASTER_LD) - find_program(LINKER_BFD bfd) - if (LINKER_BFD) - set(LINKER bfd) - endif() - - find_program(LINKER_LLD lld) - if (LINKER_LLD) - set(LINKER lld) - endif() - - if (CXX_GCC) - find_program(LINKER_MOLD mold) - if (LINKER_MOLD AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1") - set(LINKER mold) - endif() - - find_program(LINKER_GOLD gold) - if (LINKER_GOLD) - set(LINKER gold) - endif() - endif() - - if (LINKER) - message(NOTICE "Selecting ${LINKER} as linker") - add_link_options("-fuse-ld=${LINKER}") - else() - message(WARNING "No faster linker found--using default") - endif() - - if (LINKER STREQUAL "lld" AND CXX_GCC) - message(WARNING "Using lld on GCC may cause issues with certain LTO settings. If the program fails to compile, disable YUZU_USE_FASTER_LD, or install mold or GNU gold.") - endif() + include(FasterLinker) endif() # Set runtime library to MD/MDd for all configurations @@ -1055,14 +756,6 @@ if(MSVC) ) endif() -if (MINGW) - # This saves a truly ridiculous amount of time during linking - # In my tests, without this it takes 2 mins, with it takes 3-5 seconds - # or on GitHub Actions, 10 minutes -> 3 seconds - set(MINGW_FLAGS "-Wl,--strip-all -Wl,--gc-sections") - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${MINGW_FLAGS}") -endif() - add_subdirectory(src) # Set yuzu project or yuzu-cmd project as default StartUp Project in Visual Studio depending on whether QT is enabled or not diff --git a/CMakeModules/GetSCMRev.cmake b/CMakeModules/GetSCMRev.cmake deleted file mode 100644 index ee5ce6a91c..0000000000 --- a/CMakeModules/GetSCMRev.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# SPDX-FileCopyrightText: 2025 crueter -# SPDX-License-Identifier: GPL-3.0-or-later - -include(GetGitRevisionDescription) - -function(trim var) - string(REGEX REPLACE "\n" "" new "${${var}}") - set(${var} ${new} PARENT_SCOPE) -endfunction() - -set(TAG_FILE ${CMAKE_SOURCE_DIR}/GIT-TAG) -set(REF_FILE ${CMAKE_SOURCE_DIR}/GIT-REFSPEC) -set(COMMIT_FILE ${CMAKE_SOURCE_DIR}/GIT-COMMIT) -set(RELEASE_FILE ${CMAKE_SOURCE_DIR}/GIT-RELEASE) - -if (EXISTS ${REF_FILE} AND EXISTS ${COMMIT_FILE}) - file(READ ${REF_FILE} GIT_REFSPEC) - file(READ ${COMMIT_FILE} GIT_COMMIT) -else() - get_git_head_revision(GIT_REFSPEC GIT_COMMIT) - git_branch_name(GIT_REFSPEC) - if (GIT_REFSPEC MATCHES "NOTFOUND") - set(GIT_REFSPEC 1.0.0) - set(GIT_COMMIT stable) - endif() -endif() - -if (EXISTS ${TAG_FILE}) - file(READ ${TAG_FILE} GIT_TAG) -else() - git_describe(GIT_TAG --tags --abbrev=0) - if (GIT_TAG MATCHES "NOTFOUND") - set(GIT_TAG "${GIT_REFSPEC}") - endif() -endif() - -if (EXISTS ${RELEASE_FILE}) - file(READ ${RELEASE_FILE} GIT_RELEASE) - trim(GIT_RELEASE) - message(STATUS "Git release: ${GIT_RELEASE}") -endif() - -trim(GIT_REFSPEC) -trim(GIT_COMMIT) -trim(GIT_TAG) - -message(STATUS "Git commit: ${GIT_COMMIT}") -message(STATUS "Git tag: ${GIT_TAG}") -message(STATUS "Git refspec: ${GIT_REFSPEC}") diff --git a/cpmfile.json b/cpmfile.json index c00f955087..d4bf2a5b20 100644 --- a/cpmfile.json +++ b/cpmfile.json @@ -25,9 +25,9 @@ "fmt": { "repo": "fmtlib/fmt", "tag": "%VERSION%", - "hash": "c4ab814c20fbad7e3f0ae169125a4988a2795631194703251481dc36b18da65c886c4faa9acd046b0a295005217b3689eb0126108a9ba5aac2ca909aae263c2f", + "hash": "f0da82c545b01692e9fd30fdfb613dbb8dd9716983dcd0ff19ac2a8d36f74beb5540ef38072fdecc1e34191b3682a8542ecbf3a61ef287dbba0a2679d4e023f2", "version": "8", - "git_version": "12.0.0" + "git_version": "12.1.0" }, "lz4": { "name": "lz4", @@ -91,5 +91,13 @@ "version": "20250828", "artifact": "clang-rt-builtins.tar.zst", "hash": "d902392caf94e84f223766e2cc51ca5fab6cae36ab8dc6ef9ef6a683ab1c483bfcfe291ef0bd38ab16a4ecc4078344fa8af72da2f225ab4c378dee23f6186181" + }, + "vulkan-validation-layers": { + "package": "VVL", + "repo": "KhronosGroup/Vulkan-ValidationLayers", + "tag": "vulkan-sdk-%VERSION%", + "git_version": "1.4.328.1", + "artifact": "android-binaries-%VERSION%.zip", + "hash": "5ec895a453cb7c2f156830b9766953a0c2bd44dea99e6a3dac4160305041ccd3e87534b4ce0bd102392178d2a8eca48411856298f9395e60117cdfe89f72137e" } } diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index d19feb0b52..28b34d56ac 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -392,3 +392,17 @@ if (ANDROID) add_library(oboe::oboe ALIAS oboe) endif() + +# moltenvk +if (NOT YUZU_USE_BUNDLED_MOLTENVK) + find_library(MOLTENVK_LIBRARY MoltenVK) +else() + unset(MOLTENVK_LIBRARY) +endif() + +# TODO: kosmickrisp? +if (NOT MOLTENVK_LIBRARY) + AddJsonPackage(moltenvk) + + set(MOLTENVK_LIBRARY "${moltenvk_SOURCE_DIR}/MoltenVK/dylib/macOS/libMoltenVK.dylib" CACHE STRING "" FORCE) +endif() diff --git a/externals/cmake-modules/DefaultConfig.cmake b/externals/cmake-modules/DefaultConfig.cmake new file mode 100644 index 0000000000..eb5bb3cdef --- /dev/null +++ b/externals/cmake-modules/DefaultConfig.cmake @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +## DefaultConfig ## + +# Generally, you will always want "some" default configuration for your project. +# This module does nothing but enforce that. :) + +set(CMAKE_BUILD_TYPE_DEFAULT "Release" CACHE STRING "Default build type") + +get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE_DEFAULT}" + CACHE STRING "Choose the type of build." FORCE) + message(STATUS "[DefaultConfig] Defaulting to a " + "${CMAKE_BUILD_TYPE_DEFAULT} build") +endif() diff --git a/externals/cmake-modules/DetectArchitecture.cmake b/externals/cmake-modules/DetectArchitecture.cmake new file mode 100644 index 0000000000..82dce31878 --- /dev/null +++ b/externals/cmake-modules/DetectArchitecture.cmake @@ -0,0 +1,225 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +## DetectArchitecture ## +#[[ +Does exactly as it sounds. Detects common symbols defined for different architectures and +adds compile definitions thereof. Namely: +- arm64 +- arm +- x86_64 +- x86 +- ia64 +- mips64 +- mips +- ppc64 +- ppc +- riscv +- riscv64 +- loongarch64 +- wasm + +Unsupported architectures: +- ARMv2-6 +- m68k +- PIC + +This file WILL NOT detect endian-ness for you. + +This file is based off of Yuzu and Dynarmic. +]] + +# multiarch builds are a special case and also very difficult +# this is what I have for now, but it's not ideal + +# Do note that situations where multiple architectures are defined +# should NOT be too dependent on the architecture +# otherwise, you may end up with duplicate code +if (CMAKE_OSX_ARCHITECTURES) + set(MULTIARCH_BUILD 1) + set(ARCHITECTURE "${CMAKE_OSX_ARCHITECTURES}") + + # hope and pray the architecture names match + foreach(ARCH IN ${CMAKE_OSX_ARCHITECTURES}) + set(ARCHITECTURE_${ARCH} 1 PARENT_SCOPE) + add_definitions(-DARCHITECTURE_${ARCH}=1) + endforeach() + + return() +endif() + +include(CheckSymbolExists) +function(detect_architecture symbol arch) + # The output variable needs to be unset between invocations otherwise + # CMake's crazy scope rules will keep it defined + unset(SYMBOL_EXISTS CACHE) + + if (NOT DEFINED ARCHITECTURE) + set(CMAKE_REQUIRED_QUIET 1) + check_symbol_exists("${symbol}" "" SYMBOL_EXISTS) + unset(CMAKE_REQUIRED_QUIET) + + if (SYMBOL_EXISTS) + set(ARCHITECTURE "${arch}" PARENT_SCOPE) + set(ARCHITECTURE_${arch} 1 PARENT_SCOPE) + add_definitions(-DARCHITECTURE_${arch}=1) + endif() + endif() +endfunction() + +function(detect_architecture_symbols) + if (DEFINED ARCHITECTURE) + return() + endif() + + set(oneValueArgs ARCH) + set(multiValueArgs SYMBOLS) + + cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" + "${ARGN}") + + set(arch "${ARGS_ARCH}") + foreach(symbol ${ARGS_SYMBOLS}) + detect_architecture("${symbol}" "${arch}") + + if (ARCHITECTURE_${arch}) + message(DEBUG "[DetectArchitecture] Found architecture symbol ${symbol} for ${arch}") + set(ARCHITECTURE "${arch}" PARENT_SCOPE) + set(ARCHITECTURE_${arch} 1 PARENT_SCOPE) + add_definitions(-DARCHITECTURE_${arch}=1) + + return() + endif() + endforeach() +endfunction() + +function(DetectArchitecture) + # arches here are put in a sane default order of importance + # notably, amd64, arm64, and riscv (in order) are BY FAR the most common + # mips is pretty popular in embedded + # ppc64 is pretty popular in supercomputing + # sparc is uh + # ia64 exists + # the rest exist, but are probably less popular than ia64 + + detect_architecture_symbols( + ARCH arm64 + SYMBOLS + "__ARM64__" + "__aarch64__" + "_M_ARM64") + + detect_architecture_symbols( + ARCH x86_64 + SYMBOLS + "__x86_64" + "__x86_64__" + "__amd64" + "_M_X64" + "_M_AMD64") + + # riscv is interesting since it generally does not define a riscv64-specific symbol + # We can, however, check for the rv32 zcf extension which is good enough of a heuristic on GCC + detect_architecture_symbols( + ARCH riscv + SYMBOLS + "__riscv_zcf") + + # if zcf doesn't exist we can safely assume it's riscv64 + detect_architecture_symbols( + ARCH riscv64 + SYMBOLS + "__riscv") + + detect_architecture_symbols( + ARCH x86 + SYMBOLS + "__i386" + "__i386__" + "_M_IX86") + + detect_architecture_symbols( + ARCH arm + SYMBOLS + "__arm__" + "__TARGET_ARCH_ARM" + "_M_ARM") + + detect_architecture_symbols( + ARCH ia64 + SYMBOLS + "__ia64" + "__ia64__" + "_M_IA64") + + # mips is probably the least fun to detect due to microMIPS + # Because microMIPS is such cancer I'm considering it out of scope for now + detect_architecture_symbols( + ARCH mips64 + SYMBOLS + "__mips64") + + detect_architecture_symbols( + ARCH mips + SYMBOLS + "__mips" + "__mips__" + "_M_MRX000") + + detect_architecture_symbols( + ARCH ppc64 + SYMBOLS + "__ppc64__" + "__powerpc64__" + "_ARCH_PPC64" + "_M_PPC64") + + detect_architecture_symbols( + ARCH ppc + SYMBOLS + "__ppc__" + "__ppc" + "__powerpc__" + "_ARCH_COM" + "_ARCH_PWR" + "_ARCH_PPC" + "_M_MPPC" + "_M_PPC") + + detect_architecture_symbols( + ARCH sparc64 + SYMBOLS + "__sparc_v9__") + + detect_architecture_symbols( + ARCH sparc + SYMBOLS + "__sparc__" + "__sparc") + + # I don't actually know about loongarch32 since crossdev does not support it, only 64 + detect_architecture_symbols( + ARCH loongarch64 + SYMBOLS + "__loongarch__" + "__loongarch64") + + detect_architecture_symbols( + ARCH wasm + SYMBOLS + "__EMSCRIPTEN__") + + # "generic" target + # If you have reached this point, you're on some as-of-yet unsupported architecture. + # See the docs up above for known unsupported architectures + # If you're not in the list... I think you know what you're doing. + if (NOT DEFINED ARCHITECTURE) + set(ARCHITECTURE "GENERIC") + set(ARCHITECTURE_GENERIC 1) + add_definitions(-DARCHITECTURE_GENERIC=1) + endif() + + message(STATUS "[DetectArchitecture] Target architecture: ${ARCHITECTURE}") + set(ARCHITECTURE "${ARCHITECTURE}" PARENT_SCOPE) + set(ARCHITECTURE_${ARCHITECTURE} 1 PARENT_SCOPE) +endfunction() diff --git a/externals/cmake-modules/DetectPlatform.cmake b/externals/cmake-modules/DetectPlatform.cmake new file mode 100644 index 0000000000..25b324a674 --- /dev/null +++ b/externals/cmake-modules/DetectPlatform.cmake @@ -0,0 +1,151 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +## DetectPlatform ## + +# This is a small helper that sets PLATFORM_ variables for various +# operating systems and distributions. Note that Apple, Windows, Android, etc. +# are not covered, as CMake already does that for us. + +# It also sets CXX_ for the C++ compiler. + +# Furthermore, some platforms have really silly requirements/quirks, so this +# also does a few of those. + +# This module contains contributions from the Eden Emulator Project, +# notably from crueter and Lizzie. + +if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") + set(PLATFORM_SUN ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") + set(PLATFORM_FREEBSD ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD") + set(PLATFORM_OPENBSD ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD") + set(PLATFORM_NETBSD ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "DragonFly") + set(PLATFORM_DRAGONFLYBSD ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Haiku") + set(PLATFORM_HAIKU ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(PLATFORM_LINUX ON) +endif() + +# dumb heuristic to detect msys2 +if (CMAKE_COMMAND MATCHES "msys64") + set(PLATFORM_MSYS ON) +endif() + +if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CXX_CLANG ON) + if (MSVC) + set(CXX_CLANG_CL ON) + endif() +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CXX_GCC ON) +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CXX_CL ON) +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") + set(CXX_ICC ON) +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(CXX_APPLE ON) +endif() + +# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/11112 +# This works totally fine on MinGW64, but not CLANG{,ARM}64 +if(MINGW AND CXX_CLANG) + set(CMAKE_SYSTEM_VERSION 10.0.0) +endif() + +# NB: this does not account for SPARC +if (PLATFORM_SUN) + # Terrific OpenIndiana pkg shenanigans + list(APPEND CMAKE_PREFIX_PATH + "${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake") + list(APPEND CMAKE_MODULE_PATH + "${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake") + + # Amazing - absolutely incredible + list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake") + list(APPEND CMAKE_MODULE_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake") + + # For some mighty reason, doing a normal release build sometimes + # may not trigger the proper -O3 switch to materialize + if (CMAKE_BUILD_TYPE MATCHES "Release") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") + endif() + if (CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") + endif() +endif() + +# MSYS2 utilities + +# Sometimes, PkgConfig modules will incorrectly reference / when CMake +# wants you to reference it as C:/msys64/. This function corrects that. +# Example in a Find module: +#[[ + if (PLATFORM_MSYS) + FixMsysPath(PkgConfig::OPUS) + endif() +]] + +function(FixMsysPath target) + get_target_property(include_dir ${target} INTERFACE_INCLUDE_DIRECTORIES) + + if (NOT (include_dir MATCHES "^/")) + return() + endif() + + set(root_default $ENV{MSYS2_LOCATION}) + if (root_default STREQUAL "") + set(root_default "C:/msys64") + endif() + + set(MSYS_ROOT_PATH ${root_default} + CACHE STRING "Location of the MSYS2 root") + + set(include_dir "C:/msys64${include_dir}") + set_target_properties(${target} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${include_dir}) +endfunction() + +# MSYSTEM handling + program_path +if (PLATFORM_MSYS) + # really, really dumb heuristic to detect what environment we are in + macro(system var) + if (CMAKE_COMMAND MATCHES ${var}) + set(MSYSTEM ${var}) + endif() + endmacro() + + system(mingw64) + system(clang64) + system(clangarm64) + system(ucrt64) + + if (NOT DEFINED MSYSTEM) + set(MSYSTEM msys2) + endif() + + # We generally want to prioritize environment-specific binaries if possible + # some, like autoconf, are not present on environments besides msys2 though + set(CMAKE_PROGRAM_PATH C:/msys64/${MSYSTEM}/bin C:/msys64/usr/bin) + set(ENV{PKG_CONFIG_PATH} C:/msys64/${MSYSTEM}/lib/pkgconfig) +endif() + +# This saves a truly ridiculous amount of time during linking +# In my tests, without this, Eden takes 2 mins, with this, it takes 3-5 seconds +# or on GitHub Actions, 10 minutes -> 3 seconds +if (MINGW) + set(MINGW_FLAGS "-Wl,--strip-all -Wl,--gc-sections") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE + "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${MINGW_FLAGS}") +endif() + +# awesome +if (PLATFORM_FREEBSD OR PLATFORM_DRAGONFLYBSD) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/local/lib") +endif() \ No newline at end of file diff --git a/externals/cmake-modules/FasterLinker.cmake b/externals/cmake-modules/FasterLinker.cmake new file mode 100644 index 0000000000..6b472a4f0f --- /dev/null +++ b/externals/cmake-modules/FasterLinker.cmake @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +## FasterLinker ## + +# This finds a faster linker for your compiler, if available. +# Only really tested on Linux. I would not recommend this on MSYS2. + +#[[ + search order: + - gold (GCC only) - the best, generally, but not packaged anymore + - mold (GCC only) - generally does well on GCC + - lld - preferred on clang + - bfd - the final fallback + - If none are found (macOS uses ld.prime, etc) just use the default linker +]] + +# This module is based on the work of Yuzu, specifically Liam White, +# and later extended by crueter. + +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CXX_GCC ON) +endif() + +find_program(LINKER_BFD bfd) +if (LINKER_BFD) + set(LINKER bfd) +endif() + +find_program(LINKER_LLD lld) +if (LINKER_LLD) + set(LINKER lld) +endif() + +if (CXX_GCC) + find_program(LINKER_MOLD mold) + if (LINKER_MOLD AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1") + set(LINKER mold) + endif() + + find_program(LINKER_GOLD gold) + if (LINKER_GOLD) + set(LINKER gold) + endif() +endif() + +if (LINKER) + message(NOTICE "[FasterLinker] Selecting ${LINKER} as linker") + add_link_options("-fuse-ld=${LINKER}") +else() + message(WARNING "[FasterLinker] No faster linker found--using default") +endif() + +if (LINKER STREQUAL "lld" AND CXX_GCC) + message(WARNING + "[FasterLinker] Using lld on GCC may cause issues " + "with certain LTO settings.") +endif() diff --git a/externals/cmake-modules/GetGitRevisionDescription.cmake b/externals/cmake-modules/GetGitRevisionDescription.cmake deleted file mode 100644 index dab1347753..0000000000 --- a/externals/cmake-modules/GetGitRevisionDescription.cmake +++ /dev/null @@ -1,162 +0,0 @@ -# SPDX-FileCopyrightText: 2009 Iowa State University -# SPDX-FileContributor: Ryan Pavlik -# SPDX-License-Identifier: BSL-1.0 - -# - Returns a version string from Git -# -# These functions force a re-configure on each git commit so that you can -# trust the values of the variables in your build system. -# -# get_git_head_revision( [ ...]) -# -# Returns the refspec and sha hash of the current head revision -# -# git_describe( [ ...]) -# -# Returns the results of git describe on the source tree, and adjusting -# the output so that it tests false if an error occurs. -# -# git_get_exact_tag( [ ...]) -# -# Returns the results of git describe --exact-match on the source tree, -# and adjusting the output so that it tests false if there was no exact -# matching tag. -# -# Requires CMake 2.6 or newer (uses the 'function' command) -# -# Original Author: -# 2009-2010 Ryan Pavlik -# http://academic.cleardefinition.com -# Iowa State University HCI Graduate Program/VRAC -# -# Copyright Iowa State University 2009-2010. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -if(__get_git_revision_description) - return() -endif() -set(__get_git_revision_description YES) - -# We must run the following at "include" time, not at function call time, -# to find the path to this module rather than the path to a calling list file -get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) - -function(get_git_head_revision _refspecvar _hashvar) - set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - set(GIT_DIR "${GIT_PARENT_DIR}/.git") - while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories - set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") - get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) - if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) - # We have reached the root directory, we are not in git - set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) - set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) - return() - endif() - set(GIT_DIR "${GIT_PARENT_DIR}/.git") - endwhile() - # check if this is a submodule - if(NOT IS_DIRECTORY ${GIT_DIR}) - file(READ ${GIT_DIR} submodule) - string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) - get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) - get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) - endif() - set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") - if(NOT EXISTS "${GIT_DATA}") - file(MAKE_DIRECTORY "${GIT_DATA}") - endif() - - if(NOT EXISTS "${GIT_DIR}/HEAD") - return() - endif() - set(HEAD_FILE "${GIT_DATA}/HEAD") - configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) - - configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" - "${GIT_DATA}/grabRef.cmake" - @ONLY) - include("${GIT_DATA}/grabRef.cmake") - - set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) - set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) -endfunction() - -function(git_branch_name _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - - if(NOT GIT_FOUND) - set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) - return() - endif() - - execute_process(COMMAND - "${GIT_EXECUTABLE}" - rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY - "${CMAKE_SOURCE_DIR}" - RESULT_VARIABLE - res - OUTPUT_VARIABLE - out - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") - endif() - - set(${_var} "${out}" PARENT_SCOPE) -endfunction() - -function(git_describe _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - #get_git_head_revision(refspec hash) - if(NOT GIT_FOUND) - set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) - return() - endif() - #if(NOT hash) - # set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) - # return() - #endif() - - # TODO sanitize - #if((${ARGN}" MATCHES "&&") OR - # (ARGN MATCHES "||") OR - # (ARGN MATCHES "\\;")) - # message("Please report the following error to the project!") - # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") - #endif() - - #message(STATUS "Arguments to execute_process: ${ARGN}") - - execute_process(COMMAND - "${GIT_EXECUTABLE}" - describe - ${hash} - ${ARGN} - WORKING_DIRECTORY - "${CMAKE_SOURCE_DIR}" - RESULT_VARIABLE - res - OUTPUT_VARIABLE - out - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") - endif() - - set(${_var} "${out}" PARENT_SCOPE) -endfunction() - -function(git_get_exact_tag _var) - git_describe(out --exact-match ${ARGN}) - set(${_var} "${out}" PARENT_SCOPE) -endfunction() diff --git a/externals/cmake-modules/GetGitRevisionDescription.cmake.in b/externals/cmake-modules/GetGitRevisionDescription.cmake.in deleted file mode 100644 index 868e032efb..0000000000 --- a/externals/cmake-modules/GetGitRevisionDescription.cmake.in +++ /dev/null @@ -1,45 +0,0 @@ -# SPDX-FileCopyrightText: 2009 Iowa State University -# SPDX-FileContributor: Ryan Pavlik -# SPDX-License-Identifier: BSL-1.0 - -# Internal file for GetGitRevisionDescription.cmake -# -# Requires CMake 2.6 or newer (uses the 'function' command) -# -# Original Author: -# 2009-2010 Ryan Pavlik -# http://academic.cleardefinition.com -# Iowa State University HCI Graduate Program/VRAC -# -# Copyright Iowa State University 2009-2010. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -set(HEAD_HASH) - -file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) - -string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) -if(HEAD_CONTENTS MATCHES "ref") - # named branch - string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") - if(EXISTS "@GIT_DIR@/${HEAD_REF}") - configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") - configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - set(HEAD_HASH "${HEAD_REF}") - endif() -else() - # detached HEAD - configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) -endif() - -if(NOT HEAD_HASH) - if(EXISTS "@GIT_DATA@/head-ref") - file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) - string(STRIP "${HEAD_HASH}" HEAD_HASH) - else() - set(HEAD_HASH "Unknown") - endif() -endif() diff --git a/externals/cmake-modules/GetSCMRev.cmake b/externals/cmake-modules/GetSCMRev.cmake new file mode 100644 index 0000000000..4b144584e8 --- /dev/null +++ b/externals/cmake-modules/GetSCMRev.cmake @@ -0,0 +1,85 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +## GetSCMRev ## +# Name is self explanatory. Gets revision information from files, OR from git. +# Prioritizes GIT-TAG, GIT-REFSPEC, GIT-COMMIT, GIT-RELEASE files within the root directory, +# otherwise grabs stuff from Git. + +# loosely based on Ryan Pavlik's work +find_package(Git QUIET) + +# commit: git rev-parse HEAD +# tag: git describe --tags --abbrev=0 +# branch: git rev-parse --abbrev-ref=HEAD + +function(run_git_command variable) + if(NOT GIT_FOUND) + set(${variable} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${variable} "${out}" PARENT_SCOPE) +endfunction() + +function(trim var) + string(REGEX REPLACE "\n" "" new "${${var}}") + set(${var} ${new} PARENT_SCOPE) +endfunction() + +set(TAG_FILE ${CMAKE_SOURCE_DIR}/GIT-TAG) +set(REF_FILE ${CMAKE_SOURCE_DIR}/GIT-REFSPEC) +set(COMMIT_FILE ${CMAKE_SOURCE_DIR}/GIT-COMMIT) +set(RELEASE_FILE ${CMAKE_SOURCE_DIR}/GIT-RELEASE) + +if (EXISTS ${REF_FILE} AND EXISTS ${COMMIT_FILE}) + file(READ ${REF_FILE} GIT_REFSPEC) + file(READ ${COMMIT_FILE} GIT_COMMIT) +else() + run_git_command(GIT_COMMIT rev-parse HEAD) + run_git_command(GIT_REFSPEC rev-parse --abbrev-ref HEAD) + + if (GIT_REFSPEC MATCHES "NOTFOUND") + set(GIT_REFSPEC 1.0.0) + set(GIT_COMMIT stable) + endif() +endif() + +if (EXISTS ${TAG_FILE}) + file(READ ${TAG_FILE} GIT_TAG) +else() + run_git_command(GIT_TAG describe --tags --abbrev=0) + if (GIT_TAG MATCHES "NOTFOUND") + set(GIT_TAG "${GIT_REFSPEC}") + endif() +endif() + +if (EXISTS ${RELEASE_FILE}) + file(READ ${RELEASE_FILE} GIT_RELEASE) + trim(GIT_RELEASE) + message(STATUS "[GetSCMRev] Git release: ${GIT_RELEASE}") +endif() + +trim(GIT_REFSPEC) +trim(GIT_COMMIT) +trim(GIT_TAG) + +message(STATUS "[GetSCMRev] Git commit: ${GIT_COMMIT}") +message(STATUS "[GetSCMRev] Git tag: ${GIT_TAG}") +message(STATUS "[GetSCMRev] Git refspec: ${GIT_REFSPEC}") diff --git a/externals/cmake-modules/UseCcache.cmake b/externals/cmake-modules/UseCcache.cmake new file mode 100644 index 0000000000..8caea18fe0 --- /dev/null +++ b/externals/cmake-modules/UseCcache.cmake @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +## UseCcache ## + +# Adds an option to enable CCache and uses it if provided. +# Also does some debug info downgrading to make it easier. +# Credit to DraVee for his work on this + +option(USE_CCACHE "Use ccache for compilation" OFF) +set(CCACHE_PATH "ccache" CACHE STRING "Path to ccache binary") +if(USE_CCACHE) + find_program(CCACHE_BINARY ${CCACHE_PATH}) + if(CCACHE_BINARY) + message(STATUS "[UseCcache] Found ccache at: ${CCACHE_BINARY}") + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_BINARY}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_BINARY}) + else() + message(FATAL_ERROR "[UseCcache] USE_CCACHE enabled, but no " + "executable found at: ${CCACHE_PATH}") + endif() + # Follow SCCache recommendations: + # + if(WIN32) + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG + "${CMAKE_C_FLAGS_DEBUG}") + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO + "${CMAKE_C_FLAGS_RELWITHDEBINFO}") + endif() +endif() diff --git a/externals/cmake-modules/UseLTO.cmake b/externals/cmake-modules/UseLTO.cmake new file mode 100644 index 0000000000..d1603aba1c --- /dev/null +++ b/externals/cmake-modules/UseLTO.cmake @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +## UseLTO ## + +# Enable Interprocedural Optimization (IPO). +# Self-explanatory. + +include(CheckIPOSupported) +check_ipo_supported(RESULT COMPILER_SUPPORTS_LTO) +if(NOT COMPILER_SUPPORTS_LTO) + message(FATAL_ERROR + "Your compiler does not support interprocedural optimization" + " (IPO).") +endif() +set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ${COMPILER_SUPPORTS_LTO}) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 7f5af5dfce..067a824b64 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -28,8 +28,8 @@ "httplib": { "repo": "yhirose/cpp-httplib", "tag": "v%VERSION%", - "hash": "b364500f76e2ecb0fe21b032d831272e3f1dfeea71af74e325f8fc4ce9dcdb3c941b97a5b422bdeafb9facd058597b90f8bfc284fb9afe3c33fefa15dd5a010b", - "git_version": "0.26.0", + "hash": "e7a8877d489c97669a8ee536e1498575be921e558ed947253013fe6b67a49d4569eedd01f543caa70183b92d8ac0e8687d662a70d880954412e387317008a239", + "git_version": "0.28.0", "find_args": "MODULE GLOBAL", "patches": [ "0001-mingw.patch" @@ -89,9 +89,9 @@ "package": "unordered_dense", "repo": "martinus/unordered_dense", "tag": "v%VERSION%", - "hash": "f9c819e28e1c1a387acfee09277d6af5e366597a0d39acf1c687acf0608a941ba966af8aaebdb8fba0126c7360269c4a51754ef4cab17c35c01a30215f953368", + "hash": "b98b5d4d96f8e0081b184d6c4c1181fae4e41723b54bed4296717d7f417348b48fad0bbcc664cac142b8c8a47e95aa57c1eb1cf6caa855fd782fad3e3ab99e5e", "find_args": "CONFIG", - "git_version": "4.5.0" + "git_version": "4.8.1" }, "mbedtls": { "package": "MbedTLS", @@ -188,9 +188,9 @@ "package": "SimpleIni", "repo": "brofield/simpleini", "tag": "v%VERSION%", - "hash": "6c198636816a0018adbf7f735d402c64245c6fcd540b7360d4388d46f007f3a520686cdaec4705cb8cb31401b2cb4797a80b42ea5d08a6a5807c0848386f7ca1", + "hash": "b937c18a7b6277d77ca7ebfb216af4984810f77af4c32d101b7685369a4bd5eb61406223f82698e167e6311a728d07415ab59639fdf19eff71ad6dc2abfda989", "find_args": "MODULE", - "git_version": "4.22" + "git_version": "4.25" }, "sdl2_generic": { "package": "SDL2", @@ -210,5 +210,13 @@ "key": "steamdeck", "bundled": true, "skip_updates": "true" + }, + "moltenvk": { + "repo": "KhronosGroup/MoltenVK", + "tag": "v%VERSION%", + "git_version": "1.4.1", + "artifact": "MoltenVK-macOS.tar", + "hash": "a394329f390a11d1052d2efeef5f7f33860465eea4d7e9e1faf808e616d533a283b9c55074fb833ef95ef40067fc319470eab07dc72ac63e6464dc26cbe34905", + "bundled": true } } diff --git a/src/dynarmic/CMakeLists.txt b/src/dynarmic/CMakeLists.txt index 6328d4c90d..6d19c4355a 100644 --- a/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/CMakeLists.txt @@ -33,12 +33,6 @@ option(DYNARMIC_INSTALL "Install dynarmic headers and CMake files" OFF) option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF) option(DYNARMIC_ENABLE_LTO "Enable LTO" OFF) -# Default to a Release build -if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) - message(STATUS "Defaulting to a Release build") -endif() - # Set hard requirements for C++ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -54,12 +48,6 @@ endif() # Add the module directory to the list of paths list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") -# Arch detection -if (NOT DEFINED ARCHITECTURE) - message(FATAL_ERROR "Unsupported architecture encountered. Ending CMake generation.") -endif() -message(STATUS "Target architecture: ${ARCHITECTURE}") - # Compiler flags if (MSVC) set(DYNARMIC_CXX_FLAGS @@ -119,7 +107,7 @@ else() endif() find_package(Boost 1.57 REQUIRED) -find_package(fmt 9 CONFIG) +find_package(fmt 8 CONFIG) # Pull in externals CMakeLists for libs where available add_subdirectory(externals) diff --git a/src/dynarmic/CMakeModules/TargetArchitectureSpecificSources.cmake b/src/dynarmic/CMakeModules/TargetArchitectureSpecificSources.cmake index f08911c6f2..7af6cc518b 100644 --- a/src/dynarmic/CMakeModules/TargetArchitectureSpecificSources.cmake +++ b/src/dynarmic/CMakeModules/TargetArchitectureSpecificSources.cmake @@ -1,5 +1,8 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + function(target_architecture_specific_sources project arch) - if (NOT DYNARMIC_MULTIARCH_BUILD) + if (NOT MULTIARCH_BUILD) target_sources("${project}" PRIVATE ${ARGN}) return() endif() diff --git a/src/dynarmic/tests/CMakeLists.txt b/src/dynarmic/tests/CMakeLists.txt index a77c681f31..4124ca975b 100644 --- a/src/dynarmic/tests/CMakeLists.txt +++ b/src/dynarmic/tests/CMakeLists.txt @@ -56,7 +56,7 @@ if ("x86_64" IN_LIST ARCHITECTURE) native/preserve_xmm.cpp ) - if (NOT MSVC AND NOT DYNARMIC_MULTIARCH_BUILD) + if (NOT MSVC AND NOT MULTIARCH_BUILD) target_sources(dynarmic_tests PRIVATE rsqrt_test.cpp rsqrt_test_fn.s diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index e505319b3c..8abeb90086 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -375,12 +375,6 @@ if (APPLE) set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE TRUE) set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) - if (YUZU_USE_BUNDLED_MOLTENVK) - set(MOLTENVK_PLATFORM "macOS") - set(MOLTENVK_VERSION "v1.4.0") - download_moltenvk(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION}) - endif() - set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib") find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED) message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.") diff --git a/tools/cpm/check-updates.sh b/tools/cpm/check-updates.sh index 5fc7836199..189c520690 100755 --- a/tools/cpm/check-updates.sh +++ b/tools/cpm/check-updates.sh @@ -8,10 +8,14 @@ RETURN=0 -filter() { +filter_out() { TAGS=$(echo "$TAGS" | jq "[.[] | select(.name | test(\"$1\"; \"i\") | not)]") } +filter_in() { + TAGS=$(echo "$TAGS" | jq "[.[] | select(.name | test(\"$1\"; \"i\"))]") +} + usage() { cat << EOF Usage: $0 [uf] [PACKAGE]... @@ -83,19 +87,27 @@ while true; do # filter out some commonly known annoyances # TODO add more - filter vulkan-sdk # vulkan - filter yotta # mbedtls + if [ "$PACKAGE" = "vulkan-validation-layers" ]; then + filter_in vulkan-sdk + else + filter_out vulkan-sdk + fi + + [ "$CI" = "true" ] && filter_in "-" + + filter_out yotta # mbedtls # ignore betas/alphas (remove if needed) - filter alpha - filter beta - filter rc + filter_out alpha + filter_out beta + filter_out rc # Add package-specific overrides here, e.g. here for fmt: - [ "$PACKAGE" = fmt ] && filter v0.11 + [ "$PACKAGE" = fmt ] && filter_out v0.11 LATEST=$(echo "$TAGS" | jq -r '.[0].name') + [ "$LATEST" = "null" ] && echo "-- * Up-to-date" && continue [ "$LATEST" = "$TAG" ] && [ "$FORCE" != "true" ] && echo "-- * Up-to-date" && continue RETURN=1 diff --git a/tools/cpm/download.sh b/tools/cpm/download.sh index bc436ba0f1..c8a1d637e0 100755 --- a/tools/cpm/download.sh +++ b/tools/cpm/download.sh @@ -20,10 +20,13 @@ download_package() { ACTUAL_HASH=$("${HASH_ALGO}"sum "$OUTFILE" | cut -d" " -f1) [ "$ACTUAL_HASH" != "$HASH" ] && echo "!! $FILENAME did not match expected hash; expected $HASH but got $ACTUAL_HASH" && exit 1 + TMPDIR="$TMP/extracted" mkdir -p "$OUTDIR" + mkdir -p "$TMPDIR" PREVDIR="$PWD" - cd "$OUTDIR" + mkdir -p "$TMPDIR" + cd "$TMPDIR" case "$FILENAME" in (*.7z) @@ -44,11 +47,16 @@ download_package() { # thanks gnu if [ "$(echo "$DIRS" | wc -l)" -eq 2 ]; then SUBDIR=$(find . -maxdepth 1 -type d -not -name ".") - mv "$SUBDIR"/* . - mv "$SUBDIR"/.* . 2>/dev/null || true + mv "$SUBDIR"/* "$OUTDIR" + mv "$SUBDIR"/.* "$OUTDIR" 2>/dev/null || true rmdir "$SUBDIR" + else + mv ./* "$OUTDIR" + mv ./.* "$OUTDIR" 2>/dev/null || true fi + cd "$OUTDIR" + if echo "$JSON" | grep -e "patches" > /dev/null; then PATCHES=$(echo "$JSON" | jq -r '.patches | join(" ")') for patch in $PATCHES; do