From 308c7ebb7afe481debfa9fd51c99f01ff21540b5 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 2 Jun 2026 05:02:49 +0200 Subject: [PATCH] [ci] Fix update-deps workflow me when spaces Signed-off-by: crueter --- .forgejo/workflows/translations.yml | 2 +- .forgejo/workflows/update-deps.yml | 13 +- CMakeModules/CPMUtil.cmake | 66 ++++---- CMakeModules/DetectArchitecture.cmake | 221 ++++++++++++++++++++++++++ CMakeModules/DetectPlatform.cmake | 152 ++++++++++++++++++ tools/cpm/package/update.sh | 15 +- 6 files changed, 433 insertions(+), 36 deletions(-) create mode 100644 CMakeModules/DetectArchitecture.cmake create mode 100644 CMakeModules/DetectPlatform.cmake diff --git a/.forgejo/workflows/translations.yml b/.forgejo/workflows/translations.yml index 4a2d52e745..fe2e82dff3 100644 --- a/.forgejo/workflows/translations.yml +++ b/.forgejo/workflows/translations.yml @@ -52,7 +52,7 @@ jobs: } EOF - curl -X 'POST' \ + curl -XPOST \ 'https://git.eden-emu.dev/api/v1/repos/eden-emu/eden/pulls' \ -H 'accept: application/json' \ -H 'Authorization: Bearer ${{ secrets.CI_FJ_TOKEN }}' \ diff --git a/.forgejo/workflows/update-deps.yml b/.forgejo/workflows/update-deps.yml index 154328f906..638fcd4bdb 100644 --- a/.forgejo/workflows/update-deps.yml +++ b/.forgejo/workflows/update-deps.yml @@ -1,4 +1,4 @@ -name: update-deps +name: Update Dependencies on: # saturday at noon @@ -7,7 +7,7 @@ on: workflow_dispatch: jobs: - tx-update: + update-deps: runs-on: source steps: - uses: actions/checkout@v4 @@ -24,18 +24,21 @@ jobs: git remote set-url origin ci:eden-emu/eden.git DATE=$(date +"%b %d") + TIMESTAMP=$(date +"%s") echo "DATE=$DATE" >> "$GITHUB_ENV" + echo "TIMESTAMP=$TIMESTAMP" >> "$GITHUB_ENV" - git switch -c update-deps-$DATE + git switch -c update-deps-$TIMESTAMP tools/cpmutil.sh package update -ac git push - name: Create PR run: | + set -x TITLE="[externals] Dependency update for $DATE" BODY="$(git show -s --format='%b')" BASE=master - HEAD=update-deps-$DATE + HEAD=update-deps-$TIMESTAMP cat << EOF > data.json { @@ -46,7 +49,7 @@ jobs: } EOF - curl -X 'POST' \ + curl -XPOST \ 'https://git.eden-emu.dev/api/v1/repos/eden-emu/eden/pulls' \ -H 'accept: application/json' \ -H 'Authorization: Bearer ${{ secrets.CI_FJ_TOKEN }}' \ diff --git a/CMakeModules/CPMUtil.cmake b/CMakeModules/CPMUtil.cmake index d077816721..796e7f34ad 100644 --- a/CMakeModules/CPMUtil.cmake +++ b/CMakeModules/CPMUtil.cmake @@ -128,7 +128,8 @@ function(AddDependentPackages) message(FATAL_ERROR "Partial dependency installation detected " "for the following packages:\n${package_names}\n" "You can solve this in one of two ways:\n" - "1. Install the following packages to your system if available:" + "1. Install or upgrade the following packages " + "to your system if available:" "\n\t${bundled_names}\n" "2. Set the following variables to ON:" "\n\t${system_names}\n" @@ -247,9 +248,9 @@ function(AddJsonPackage) set(multiValueArgs OPTIONS) - set(options MODULE) + set(optionArgs MODULE) - cmake_parse_arguments(JSON "${options}" "${oneValueArgs}" "${multiValueArgs}" + cmake_parse_arguments(JSON "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}") list(LENGTH ARGN argnLength) @@ -278,11 +279,11 @@ function(AddJsonPackage) parse_object(${object}) - if(ci) - if (JSON_MODULE) - set(EXTRA_ARGS MODULE) - endif() + if (JSON_MODULE) + set(EXTRA_ARGS MODULE) + endif() + if(ci) AddCIPackage( VERSION ${version} NAME ${name} @@ -313,23 +314,24 @@ function(AddJsonPackage) FORCE_BUNDLED_PACKAGE "${JSON_FORCE_BUNDLED_PACKAGE}" SOURCE_SUBDIR "${source_subdir}" - GIT_VERSION ${git_version} - GIT_HOST ${git_host} + GIT_VERSION "${git_version}" + GIT_HOST "${git_host}" - ARTIFACT ${artifact} - TAG ${tag}) + ARTIFACT "${artifact}" + TAG "${tag}" + ${EXTRA_ARGS}) endif() # pass stuff to parent scope Propagate(${package}_ADDED) Propagate(${package}_SOURCE_DIR) Propagate(${package}_BINARY_DIR) + Propagate(CMAKE_PREFIX_PATH) endfunction() function(AddPackage) cpm_set_policies() - - # TODO(crueter): git clone? + set(EXTRA_ARGS "") #[[ URL configurations, descending order of precedence: @@ -374,7 +376,9 @@ function(AddPackage) set(multiValueArgs OPTIONS PATCHES) - cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "${multiValueArgs}" + set(optionArgs MODULE) + + cmake_parse_arguments(PKG_ARGS "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}") if(NOT DEFINED PKG_ARGS_NAME) @@ -558,6 +562,12 @@ function(AddPackage) VERSION ${PKG_ARGS_VERSION}) endif() + if (PKG_ARGS_MODULE) + set(PKG_ARGS_DOWNLOAD_ONLY ON) + elseif (NOT DEFINED PKG_ARGS_DOWNLOAD_ONLY) + set(PKG_ARGS_DOWNLOAD_ONLY OFF) + endif() + CPMAddPackage( NAME ${PKG_ARGS_NAME} URL ${pkg_url} @@ -607,13 +617,14 @@ function(AddPackage) endif() # pass stuff to parent scope - set(${PKG_ARGS_NAME}_ADDED "${${PKG_ARGS_NAME}_ADDED}" - PARENT_SCOPE) - set(${PKG_ARGS_NAME}_SOURCE_DIR "${${PKG_ARGS_NAME}_SOURCE_DIR}" - PARENT_SCOPE) - set(${PKG_ARGS_NAME}_BINARY_DIR "${${PKG_ARGS_NAME}_BINARY_DIR}" - PARENT_SCOPE) + Propagate(${PKG_ARGS_NAME}_ADDED) + Propagate(${PKG_ARGS_NAME}_SOURCE_DIR) + Propagate(${PKG_ARGS_NAME}_BINARY_DIR) + if (PKG_ARGS_MODULE) + list(PREPEND CMAKE_PREFIX_PATH "${${ARTIFACT_PACKAGE}_SOURCE_DIR}") + Propagate(CMAKE_PREFIX_PATH) + endif() endfunction() # TODO(crueter): we could do an AddMultiArchPackage, multiplatformpackage? @@ -706,6 +717,10 @@ function(AddCIPackage) set(ARTIFACT "${ARTIFACT_NAME}-${pkgname}-${ARTIFACT_VERSION}.${ARTIFACT_EXT}") + if (PKG_ARGS_MODULE) + set(EXTRA_ARGS MODULE) + endif() + AddPackage( NAME ${ARTIFACT_PACKAGE} REPO ${ARTIFACT_REPO} @@ -716,16 +731,11 @@ function(AddCIPackage) KEY "${pkgname}-${ARTIFACT_VERSION}" HASH_SUFFIX sha512sum FORCE_BUNDLED_PACKAGE ON - DOWNLOAD_ONLY ${PKG_ARGS_MODULE}) + ${EXTRA_ARGS}) set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE) - set(${ARTIFACT_PACKAGE}_SOURCE_DIR - "${${ARTIFACT_PACKAGE}_SOURCE_DIR}" PARENT_SCOPE) - - if (PKG_ARGS_MODULE) - list(PREPEND CMAKE_PREFIX_PATH "${${ARTIFACT_PACKAGE}_SOURCE_DIR}") - Propagate(CMAKE_PREFIX_PATH) - endif() + Propagate(${ARTIFACT_PACKAGE}_SOURCE_DIR) + Propagate(CMAKE_PREFIX_PATH) else() find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED) endif() diff --git a/CMakeModules/DetectArchitecture.cmake b/CMakeModules/DetectArchitecture.cmake new file mode 100644 index 0000000000..105963c8c2 --- /dev/null +++ b/CMakeModules/DetectArchitecture.cmake @@ -0,0 +1,221 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: LGPL-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() + +# 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}") \ No newline at end of file diff --git a/CMakeModules/DetectPlatform.cmake b/CMakeModules/DetectPlatform.cmake new file mode 100644 index 0000000000..0ad695066b --- /dev/null +++ b/CMakeModules/DetectPlatform.cmake @@ -0,0 +1,152 @@ +# SPDX-FileCopyrightText: Copyright 2025 crueter +# SPDX-License-Identifier: LGPL-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/tools/cpm/package/update.sh b/tools/cpm/package/update.sh index 92f4f423a9..77d408bee0 100755 --- a/tools/cpm/package/update.sh +++ b/tools/cpm/package/update.sh @@ -83,8 +83,13 @@ for pkg in $packages; do echo "-- Package $PACKAGE" # TODO(crueter): Support for Forgejo updates w/ forgejo_token - # Use gh-cli to avoid ratelimits lmao - TAGS=$(gh api --method GET "/repos/$REPO/tags") + # Use gh-cli to avoid ratelimits, if available + endpoint="/repos/$REPO/tags" + if command -v gh >/dev/null 2>&1; then + TAGS=$(gh api --method GET "$endpoint") + else + TAGS=$(curl -sfL "https://api.github.com$endpoint") + fi # filter out some commonly known annoyances # TODO add more @@ -105,6 +110,12 @@ for pkg in $packages; do filter_out beta filter_out rc + # openssl + if [ "$PACKAGE" = openssl ]; then + filter_out rsaref + filter_in "openssl-" + fi + # Add package-specific overrides here, e.g. here for fmt: [ "$PACKAGE" != fmt ] || filter_out v0.11