Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 131 additions & 13 deletions cmake/Yokai/Architecture.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,105 @@
# Architecture detection.
################################################################################

# When adding a new architecture, look at all the places YOKAI_TARGET_ARCH is used.
# When adding a new architecture, look at all the places YOKAI_HOST_ARCH
# and YOKAI_TARGET_ARCH are used.

option(USE_ARCH_INTRINSICS "Enable custom code using intrinsics functions or asm declarations" ON)
mark_as_advanced(USE_ARCH_INTRINSICS)

function(yokai_detect_arch)
function(yokai_detect_host_arch)
set(arch_name "unknown")

string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" processor_lower)

foreach(name
"arm"
"arm64"
"i686"
"mipsel"
"ppc64"
"riscv64"
)
if ("${processor_lower}" STREQUAL "${name}")
set(arch_name "${processor_lower}")
endif()
endforeach()

if ("${arch_name}" STREQUAL "unknown")
set(ARCHES_amd64 "em64t" "x86_64")
set(ARCHES_arm "armv6l" "armv7l")
set(ARCHES_arm64 "aarch64")
set(ARCHES_loong64 "loongarch64")
set(ARCHES_ppc64el "ppc64le")

foreach(name
"amd64"
"arm"
"arm64"
"loong64"
"ppc64el"
)
if ("${processor_lower}" IN_LIST ARCHES_${name})
set(arch_name "${name}")
endif()
endforeach()
endif()

if ("${arch_name}" STREQUAL "unknown")
if ("${processor_lower}")
message(WARNING "Undocumented host architecture: ${processor_lower}")
else()
message(WARNING "Undocumented host architecture")
endif()

set(arch_name "${processor_lower}")
endif()

string(TOUPPER "${arch_name}" arch_name_upper)

set(YOKAI_HOST_ARCH_NAME "${arch_name}" PARENT_SCOPE)
set(YOKAI_HOST_ARCH_NAME_UPPER "${arch_name_upper}" PARENT_SCOPE)

# Makes possible to do that in CMake code:
# > if (YOKAI_HOST_ARCH_AMD64)
set("YOKAI_HOST_ARCH_${arch_name_upper}" ON PARENT_SCOPE)

if ("${arch_name}" STREQUAL "unknown")
message(WARNING "Unknown host architecture: ${processor_lower}")

set(arch_name "${processor_lower}")
endif()

set(arm_CHILD
"armel"
"armhf"
)

foreach(name
"arm"
)
if ("${arch_name}" STREQUAL "${name}")
message(STATUS "Parent architecture: ${name}, can be ${${name}_CHILD}")

foreach(child_name ${${name}_CHILD})
string(TOUPPER "${child_name}" child_name_upper)
set(YOKAI_HOST_ARCH_${child_name_upper}_PARENT ON PARENT_SCOPE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this variable supposed to signal?

@illwieckz illwieckz Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When YOKAI_HOST_ARCH_arm is true, then both YOKAI_HOST_ARCH_armhf_PARENT and YOKAI_HOST_ARCH_armel_PARENT are true. So when either YOKAI_TARGET_ARCH_armel_PARENT or YOKAI_TARGET_ARCH_armhf_PARENT is true we can make the assumption that we're not cross-compiling.

It's impossible to tell the ABI (armel, armhf) from uname -m (what basically CMake uses as a backend here) and the difference is mostly a compiler flag. So it's more prudent to assume it's not a cross-compilation. Guessing the host ABI would require to check what is the default ELF loader, for now I don't see the need to go this deeper (and it would be overly specific to the system… so overly complex).

Such deeper need may surface when building a host tool to run it (in fact building such host tool the static way would keep it runnable in that case), but we explicitly avoid to build and run host tool in CMake and Yokai itself is designed to avoid that for its own needs and we encourage to not do that.

endforeach()
endif()
endforeach()
endfunction()

function(yokai_detect_target_arch)
yokai_run_detection("TARGET" "ARCH" "Architecture.c" "")

set(YOKAI_TARGET_ARCH_NAME "${arch_name}" PARENT_SCOPE)
set(YOKAI_TARGET_ARCH_NAME_UPPER "${arch_name_upper}" PARENT_SCOPE)

message(STATUS "Detected target architecture: ${arch_name}")

add_definitions(-DYOKAI_ARCH_${arch_name_upper})

# Makes possible to do that in CMake code:
# > if (YOKAI_TARGET_ARCH_AMD64)
set("YOKAI_TARGET_ARCH_${arch_name_upper}" ON PARENT_SCOPE)
endfunction()

function(yokai_set_arch_intrinsics name)
Expand All @@ -50,9 +135,6 @@ function(yokai_set_arch_intrinsics name)
add_definitions(-DYOKAI_USE_ARCH_INTRINSICS_${name_upper})
endfunction()

option(USE_ARCH_INTRINSICS "Enable custom code using intrinsics functions or asm declarations" ON)
mark_as_advanced(USE_ARCH_INTRINSICS)

function(yokai_set_intrinsics)
if (USE_ARCH_INTRINSICS)
# Makes possible to do that in C++ code:
Expand All @@ -61,7 +143,6 @@ function(yokai_set_intrinsics)

# Makes possible to do that in C++ code:
# > if defined(YOKAI_USE_ARCH_INTRINSICS_AMD64)
# > if defined(YOKAI_USE_ARCH_INTRINSICS_I686)
yokai_set_arch_intrinsics("${YOKAI_TARGET_ARCH_NAME}")

set(amd64_PARENT "i686")
Expand All @@ -76,14 +157,51 @@ function(yokai_set_intrinsics)
endif()
endfunction()

yokai_detect_arch()
yokai_set_intrinsics()
yokai_detect_host_arch()
yokai_detect_target_arch()

# Makes possible to do that in CMake code:
# > if (YOKAI_TARGET_ARCH_ARM64)
set("YOKAI_TARGET_ARCH_${YOKAI_TARGET_ARCH_NAME_UPPER}" ON)
if (YOKAI_HOST_ARCH_UNKNOWN AND NOT YOKAI_TARGET_ARCH_UNKNOWN)
message(WARNING "Assuming the host architecture is the same as the target: ${YOKAI_TARGET_ARCH_NAME}")
set(YOKAI_HOST_ARCH_NAME "${YOKAI_TARGET_ARCH_NAME}")
set(YOKAI_HOST_ARCH_NAME_UPPER "${YOKAI_TARGET_ARCH_NAME_UPPER}")
set(YOKAI_HOST_ARCH_${YOKAI_HOST_ARCH_NAME_UPPER} ON)
unset(YOKAI_HOST_ARCH_UNKNOWN)
endif()

if (YOKAI_TARGET_ARCH_UNKNOWN AND NOT YOKAI_HOST_ARCH_UNKNOWN)
message(WARNING "Assuming the target architecture is the same as the host: ${YOKAI_TARGET_ARCH_NAME}")
set(YOKAI_TARGET_ARCH_NAME "${YOKAI_HOST_ARCH_NAME}")
set(YOKAI_TARGET_ARCH_NAME_UPPER "${YOKAI_HOST_ARCH_NAME_UPPER}")
set(YOKAI_TARGET_ARCH_${YOKAI_TARGET_ARCH_NAME_UPPER} ON)
unset(YOKAI_TARGET_ARCH_UNKNOWN)
endif()

if (YOKAI_HOST_ARCH_UNKNOWN)
message(WARNING "Unknown host architecture")
else()
message(STATUS "Detected host architecture: ${YOKAI_HOST_ARCH_NAME}")
endif()

if (YOKAI_TARGET_ARCH_UNKNOWN)
message(WARNING "Unknown target architecture")
else()
message(STATUS "Detected target architecture: ${YOKAI_TARGET_ARCH_NAME}")
endif()

if (NOT "${YOKAI_HOST_ARCH_NAME}" STREQUAL "${YOKAI_TARGET_ARCH_NAME}")
if ("${YOKAI_HOST_ARCH_${YOKAI_TARGET_ARCH_NAME}_PARENT}")
message(STATUS "Assuming no architecture cross-compilation")
else()
message(STATUS "Detected architecture cross-compilation")
set(YOKAI_TARGET_CROSS ON)
endif()
else()
message(STATUS "No architecture cross-compilation detected")
endif()

if (YOKAI_SOURCE_GENERATOR)
# Add printable strings to the executable.
yokai_add_buildinfo("char*" "YOKAI_ARCH_STRING" "\"${YOKAI_TARGET_ARCH_NAME}\"")
endif()

yokai_set_intrinsics()
5 changes: 5 additions & 0 deletions cmake/Yokai/Detection/Architecture.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ platform variants we cannot support anyway. */
#elif defined(Q_PROCESSOR_RISCV_64)
#pragma message(REPORT_NAME("riscv64"))

/* Devices like:
- Loongson 3A6000, 3A5000… */
#elif defined(Q_PROCESSOR_LOONGARCH_64)
#pragma message(REPORT_NAME("loong64"))

/* Remaining native NaCl architecture. */

#elif defined(Q_PROCESSOR_MIPS_32) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
Expand Down
33 changes: 27 additions & 6 deletions cmake/Yokai/Detection/qprocessordetection.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default


#if 0
Expand Down Expand Up @@ -51,8 +52,8 @@

Alpha is bi-endian, use endianness auto-detection implemented below.
*/
// #elif defined(__alpha__) || defined(_M_ALPHA)
// # define Q_PROCESSOR_ALPHA
#if defined(__alpha__) || defined(_M_ALPHA)
# define Q_PROCESSOR_ALPHA
// Q_BYTE_ORDER not defined, use endianness auto-detection

/*
Expand All @@ -61,8 +62,8 @@
ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to
auto-detection implemented below.
*/
#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) || defined(_ARM64EC_)
# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) || defined(_ARM64EC_)
# define Q_PROCESSOR_ARM_64
# define Q_PROCESSOR_WORDSIZE 8
# else
Expand All @@ -78,7 +79,8 @@
|| defined(__aarch64__) \
|| defined(__ARMv8__) \
|| defined(__ARMv8_A__) \
|| defined(_M_ARM64)
|| defined(_M_ARM64) \
|| defined (_ARM64EC_)
# define Q_PROCESSOR_ARM 8
# elif defined(__ARM_ARCH_7__) \
|| defined(__ARM_ARCH_7A__) \
Expand Down Expand Up @@ -116,7 +118,10 @@
# else
# error "ARM architecture too old"
# endif
# if defined(__ARMEL__) || defined(_M_ARM64)
# if defined(_ARM64EC_)
# define Q_PROCESSOR_ARM_64_EC
# endif
# if defined(__ARMEL__) || defined(_M_ARM64) || defined(_ARM64EC_)
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
# elif defined(__ARMEB__)
# define Q_BYTE_ORDER Q_BIG_ENDIAN
Expand Down Expand Up @@ -199,6 +204,20 @@
# define Q_PROCESSOR_WORDSIZE 8
// Q_BYTE_ORDER not defined, use endianness auto-detection

/*
LoongArch family, known variants: 32- and 64-bit

LoongArch is little-endian.
*/
#elif defined(__loongarch__)
# define Q_PROCESSOR_LOONGARCH
# if __loongarch_grlen == 64
# define Q_PROCESSOR_LOONGARCH_64
# else
# define Q_PROCESSOR_LOONGARCH_32
# endif
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN

/*
Motorola 68000 family, no revisions or variants

Expand Down Expand Up @@ -327,6 +346,8 @@
# define Q_PROCESSOR_WORDSIZE 8
#ifdef QT_COMPILER_SUPPORTS_SSE2
# define Q_PROCESSOR_X86 6 // enables SIMD support
# define Q_PROCESSOR_X86_64 // wasm64
# define Q_PROCESSOR_WASM_64
#endif

#endif
Expand Down
Loading
Loading