File: CheckCompilerFeatures.cmake

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-10.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,999,140 kB
  • sloc: cpp: 6,951,711; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,033; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,252; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (104 lines) | stat: -rw-r--r-- 3,671 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# ------------------------------------------------------------------------------
# Compiler features definition and flags
# ------------------------------------------------------------------------------

set(
  ALL_COMPILER_FEATURES
    "builtin_ceil_floor_rint_trunc"
    "builtin_round"
    "builtin_roundeven"
    "float16"
    "float128"
    "fixed_point"
)

# Making sure ALL_COMPILER_FEATURES is sorted.
list(SORT ALL_COMPILER_FEATURES)

# Function to check whether the compiler supports the provided set of features.
# Usage:
# compiler_supports(
#   <output variable>
#   <list of cpu features>
# )
function(compiler_supports output_var features)
  _intersection(var "${LIBC_CPU_FEATURES}" "${features}")
  if("${var}" STREQUAL "${features}")
    set(${output_var} TRUE PARENT_SCOPE)
  else()
    unset(${output_var} PARENT_SCOPE)
  endif()
endfunction()

# ------------------------------------------------------------------------------
# Internal helpers and utilities.
# ------------------------------------------------------------------------------

# Computes the intersection between two lists.
function(_intersection output_var list1 list2)
  foreach(element IN LISTS list1)
    if("${list2}" MATCHES "(^|;)${element}(;|$)")
      list(APPEND tmp "${element}")
    endif()
  endforeach()
  set(${output_var} ${tmp} PARENT_SCOPE)
endfunction()

set(AVAILABLE_COMPILER_FEATURES "")

# Try compile a C file to check if flag is supported.
foreach(feature IN LISTS ALL_COMPILER_FEATURES)
  set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
  set(compile_options ${LIBC_COMPILE_OPTIONS_NATIVE})
  set(link_options "")
  if(${feature} STREQUAL "fixed_point")
    list(APPEND compile_options "-ffixed-point")
  elseif(${feature} MATCHES "^builtin_")
    set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
    set(link_options -nostdlib)
    # The compiler might handle calls to rounding builtins by generating calls
    # to the respective libc math functions, in which case we cannot use these
    # builtins in our implementations of these functions. We check that this is
    # not the case by trying to link an executable, since linking would fail due
    # to unresolved references with -nostdlib if calls to libc functions were
    # generated.
    set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
  endif()

  try_compile(
    has_feature
    ${CMAKE_CURRENT_BINARY_DIR}/compiler_features
    SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/compiler_features/check_${feature}.cpp
    COMPILE_DEFINITIONS -I${LIBC_SOURCE_DIR} ${compile_options}
    LINK_OPTIONS ${link_options}
  )
  if(has_feature)
    list(APPEND AVAILABLE_COMPILER_FEATURES ${feature})
    if(${feature} STREQUAL "float16")
      set(LIBC_TYPES_HAS_FLOAT16 TRUE)
    elseif(${feature} STREQUAL "float128")
      set(LIBC_TYPES_HAS_FLOAT128 TRUE)
    elseif(${feature} STREQUAL "fixed_point")
      set(LIBC_COMPILER_HAS_FIXED_POINT TRUE)
    elseif(${feature} STREQUAL "builtin_ceil_floor_rint_trunc")
      set(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_RINT_TRUNC TRUE)
    elseif(${feature} STREQUAL "builtin_round")
      set(LIBC_COMPILER_HAS_BUILTIN_ROUND TRUE)
    elseif(${feature} STREQUAL "builtin_roundeven")
      set(LIBC_COMPILER_HAS_BUILTIN_ROUNDEVEN TRUE)
    endif()
  endif()
endforeach()

message(STATUS "Compiler features available: ${AVAILABLE_COMPILER_FEATURES}")

### Compiler Feature Detection ###

# clang-8+, gcc-12+
check_cxx_compiler_flag("-ftrivial-auto-var-init=pattern" LIBC_CC_SUPPORTS_PATTERN_INIT)

# clang-6+, gcc-13+
check_cxx_compiler_flag("-nostdlib++" LIBC_CC_SUPPORTS_NOSTDLIBPP)

# clang-3.0+
check_cxx_compiler_flag("-nostdlibinc" LIBC_CC_SUPPORTS_NOSTDLIBINC)