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 <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3126 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
226 lines
5.8 KiB
CMake
226 lines
5.8 KiB
CMake
# 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()
|