1# detect-arch.cmake -- Detect compiler architecture and set ARCH and BASEARCH
2# Copyright (C) 2019 Hans Kristian Rosbach
3# Licensed under the Zlib license, see LICENSE.md for details
4set(ARCHDETECT_FOUND TRUE)
5
6if(CMAKE_OSX_ARCHITECTURES)
7    # If multiple architectures are requested (universal build), pick only the first
8    list(GET CMAKE_OSX_ARCHITECTURES 0 ARCH)
9elseif(MSVC)
10    if("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "X86")
11        set(ARCH "i686")
12    elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "x64")
13        set(ARCH "x86_64")
14    elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARMV7")
15        set(ARCH "arm")
16    elseif ("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64")
17        set(ARCH "aarch64")
18    endif()
19elseif(CMAKE_CROSSCOMPILING)
20    set(ARCH ${CMAKE_C_COMPILER_TARGET})
21else()
22    # Let preprocessor parse archdetect.c and raise an error containing the arch identifier
23    enable_language(C)
24    try_run(
25        run_result_unused
26        compile_result_unused
27        ${CMAKE_CURRENT_BINARY_DIR}
28        ${CMAKE_CURRENT_LIST_DIR}/detect-arch.c
29        COMPILE_OUTPUT_VARIABLE RAWOUTPUT
30        CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
31    )
32
33    # Find basearch tag, and extract the arch word into BASEARCH variable
34    string(REGEX REPLACE ".*archfound ([a-zA-Z0-9_]+).*" "\\1" ARCH "${RAWOUTPUT}")
35    if(NOT ARCH)
36        set(ARCH unknown)
37    endif()
38endif()
39
40# Make sure we have ARCH set
41if(NOT ARCH OR ARCH STREQUAL "unknown")
42    set(ARCH ${CMAKE_SYSTEM_PROCESSOR})
43    message(STATUS "Arch not recognized, falling back to cmake arch: '${ARCH}'")
44else()
45    message(STATUS "Arch detected: '${ARCH}'")
46endif()
47
48# Base arch detection
49if("${ARCH}" MATCHES "(x86_64|AMD64|i[3-6]86)")
50    set(BASEARCH "x86")
51    set(BASEARCH_X86_FOUND TRUE)
52elseif("${ARCH}" MATCHES "(arm(v[0-9])?|aarch64)")
53    set(BASEARCH "arm")
54    set(BASEARCH_ARM_FOUND TRUE)
55elseif("${ARCH}" MATCHES "ppc(64(le)?)?|powerpc(64(le)?)?")
56    set(BASEARCH "ppc")
57    set(BASEARCH_PPC_FOUND TRUE)
58elseif("${ARCH}" MATCHES "alpha")
59    set(BASEARCH "alpha")
60    set(BASEARCH_ALPHA_FOUND TRUE)
61elseif("${ARCH}" MATCHES "blackfin")
62    set(BASEARCH "blackfin")
63    set(BASEARCH_BLACKFIN_FOUND TRUE)
64elseif("${ARCH}" MATCHES "ia64")
65    set(BASEARCH "ia64")
66    set(BASEARCH_IA64_FOUND TRUE)
67elseif("${ARCH}" MATCHES "mips")
68    set(BASEARCH "mips")
69    set(BASEARCH_MIPS_FOUND TRUE)
70elseif("${ARCH}" MATCHES "m68k")
71    set(BASEARCH "m68k")
72    set(BASEARCH_M68K_FOUND TRUE)
73elseif("${ARCH}" MATCHES "sh")
74    set(BASEARCH "sh")
75    set(BASEARCH_SH_FOUND TRUE)
76elseif("${ARCH}" MATCHES "sparc[89]?")
77    set(BASEARCH "sparc")
78    set(BASEARCH_SPARC_FOUND TRUE)
79elseif("${ARCH}" MATCHES "s3[679]0x?")
80    set(BASEARCH "s360")
81    set(BASEARCH_S360_FOUND TRUE)
82elseif("${ARCH}" MATCHES "parisc")
83    set(BASEARCH "parisc")
84    set(BASEARCH_PARISC_FOUND TRUE)
85elseif("${ARCH}" MATCHES "rs6000")
86    set(BASEARCH "rs6000")
87    set(BASEARCH_RS6000_FOUND TRUE)
88elseif("${ARCH}" MATCHES "riscv(32|64)")
89    set(BASEARCH "riscv")
90    set(BASEARCH_RISCV_FOUND TRUE)
91else()
92    set(BASEARCH "x86")
93    set(BASEARCH_X86_FOUND TRUE)
94    message(STATUS "Basearch '${ARCH}' not recognized, defaulting to 'x86'.")
95endif()
96message(STATUS "Basearch of '${ARCH}' has been detected as: '${BASEARCH}'")
97