eden/CMakeModules/DetectArchitecture.cmake
crueter 77f52784cd
Some checks failed
eden-license / license-header (pull_request) Failing after 28s
Test
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-10-08 00:19:32 -04:00

173 lines
4.3 KiB
CMake

# SPDX-FileCopyrightText: 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
- mips
- ppc64
- ppc
- riscv
- wasm
This file is based off of Yuzu and Dynarmic.
TODO: add SPARC
]]
# 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)
unset(SYMBOL_EXISTS CACHE)
if (NOT DEFINED ARCHITECTURE)
set(CMAKE_REQUIRED_QUIET 1)
check_symbol_exists("${symbol}" "" SYMBOL_EXISTS)
unset(CMAKE_REQUIRED_QUIET)
# The output variable needs to be unique across invocations otherwise
# CMake's crazy scope rules will keep it defined
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}")
message(STATUS "Architecture: symbols ${ARGS_SYMBOLS} for arch ${arch}")
foreach(symbol ${ARGS_SYMBOLS})
detect_architecture("${symbol}" "${arch}")
message(STATUS "Architecture: symbol ${symbol} ${ARCHITECTURE_${arch}}")
if (ARCHITECTURE_${arch})
message(STATUS "[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)
detect_architecture_symbols(
ARCH arm64
SYMBOLS
"__ARM64__"
"__aarch64__"
"_M_ARM64")
detect_architecture_symbols(
ARCH arm
SYMBOLS
"__arm__"
"__TARGET_ARCH_ARM"
"_M_ARM")
detect_architecture_symbols(
ARCH x86_64
SYMBOLS
"__x86_64"
"__x86_64__"
"__amd64"
"_M_X64"
"_M_AMD64")
detect_architecture_symbols(
ARCH x86
SYMBOLS
"__i386"
"__i386__"
"_M_IX86")
detect_architecture_symbols(
ARCH ia64
SYMBOLS
"__ia64"
"__ia64__"
"_M_IA64")
detect_architecture_symbols(
ARCH mips
SYMBOLS
"__mips"
"__mips__"
"_M_MRX000")
detect_architecture_symbols(
ARCH ppc64
SYMBOLS
"__ppc64__"
"__powerpc64__")
detect_architecture_symbols(
ARCH ppc
SYMBOLS
"__ppc__"
"__ppc"
"__powerpc__"
"_ARCH_COM"
"_ARCH_PWR"
"_ARCH_PPC"
"_M_MPPC"
"_M_PPC")
detect_architecture_symbols(
ARCH riscv
SYMBOLS
"__riscv")
detect_architecture_symbols(
ARCH wasm
SYMBOLS
"__EMSCRIPTEN__")
if (NOT DEFINED ARCHITECTURE)
set(ARCHITECTURE "GENERIC")
set(ARCHITECTURE_GENERIC 1)
add_definitions(-DARCHITECTURE_GENERIC=1)
endif()
message(STATUS "[DetectArchitecture] Target architecture(s): ${ARCHITECTURE}")
set(ARCHITECTURE "${ARCHITECTURE}" PARENT_SCOPE)
set(ARCHITECTURE_${ARCHITECTURE} 1 PARENT_SCOPE)
endfunction()