xref: /llvm-project/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake (revision b11529bfa26fe8f2abc7d57cd96716a494198327)
1if(NOT DEFINED LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE)
2  if(CMAKE_COMPILER_IS_GNUCXX)
3    set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE ON)
4  elseif( MSVC )
5    set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE OFF)
6  elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
7    set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE ON)
8  elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" )
9    set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE ON)
10  endif()
11endif()
12
13function(_get_compile_options_from_flags output_var)
14  set(compile_options "")
15
16  if(LIBC_TARGET_ARCHITECTURE_IS_RISCV64 OR(LIBC_CPU_FEATURES MATCHES "FMA"))
17    check_flag(ADD_FMA_FLAG ${FMA_OPT_FLAG} ${ARGN})
18  endif()
19  check_flag(ADD_ROUND_OPT_FLAG ${ROUND_OPT_FLAG} ${ARGN})
20  check_flag(ADD_EXPLICIT_SIMD_OPT_FLAG ${EXPLICIT_SIMD_OPT_FLAG} ${ARGN})
21  check_flag(ADD_MISC_MATH_BASIC_OPS_OPT_FLAG ${MISC_MATH_BASIC_OPS_OPT_FLAG} ${ARGN})
22
23  if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE)
24    if(ADD_FMA_FLAG)
25      if(LIBC_TARGET_ARCHITECTURE_IS_X86_64)
26        list(APPEND compile_options "-mavx2")
27        list(APPEND compile_options "-mfma")
28      elseif(LIBC_TARGET_ARCHITECTURE_IS_RISCV64)
29        list(APPEND compile_options "-D__LIBC_RISCV_USE_FMA")
30      endif()
31      # For clang, we will build the math functions with `-fno-math-errno` so that
32      # __builtin_fma* will generate the fused-mutliply-add instructions.  We
33      # don't put the control flag to the public config yet, and see if it makes
34      # sense to just enable this flag by default.
35      if(LIBC_ADD_FNO_MATH_ERRNO)
36        list(APPEND compile_options "-fno-math-errno")
37      endif()
38    endif()
39    if(ADD_ROUND_OPT_FLAG)
40      if(LIBC_TARGET_ARCHITECTURE_IS_X86_64)
41        # ROUND_OPT_FLAG is only enabled if SSE4.2 is detected, not just SSE4.1,
42        # because there was code to check for SSE4.2 already, and few CPUs only
43        # have SSE4.1.
44        list(APPEND compile_options "-msse4.2")
45      endif()
46      if(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_RINT_TRUNC)
47        list(APPEND compile_options
48             "-D__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC")
49      endif()
50      if(LIBC_COMPILER_HAS_BUILTIN_ROUND)
51        list(APPEND compile_options "-D__LIBC_USE_BUILTIN_ROUND")
52      endif()
53      if(LIBC_COMPILER_HAS_BUILTIN_ROUNDEVEN)
54        list(APPEND compile_options "-D__LIBC_USE_BUILTIN_ROUNDEVEN")
55      endif()
56    endif()
57    if(ADD_EXPLICIT_SIMD_OPT_FLAG)
58      list(APPEND compile_options "-D__LIBC_EXPLICIT_SIMD_OPT")
59    endif()
60    if(ADD_MISC_MATH_BASIC_OPS_OPT_FLAG)
61      list(APPEND compile_options "-D__LIBC_MISC_MATH_BASIC_OPS_OPT")
62      if(LIBC_COMPILER_HAS_BUILTIN_FMAX_FMIN)
63        list(APPEND compile_options "-D__LIBC_USE_BUILTIN_FMAX_FMIN")
64      endif()
65      if(LIBC_COMPILER_HAS_BUILTIN_FMAXF16_FMINF16)
66        list(APPEND compile_options "-D__LIBC_USE_BUILTIN_FMAXF16_FMINF16")
67      endif()
68      if("FullFP16" IN_LIST LIBC_CPU_FEATURES AND
69         CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
70        list(APPEND compile_options
71             "SHELL:-Xclang -target-feature -Xclang +fullfp16")
72      endif()
73    endif()
74  elseif(MSVC)
75    if(ADD_FMA_FLAG)
76      list(APPEND compile_options "/arch:AVX2")
77    endif()
78    if(ADD_EXPLICIT_SIMD_OPT_FLAG)
79      list(APPEND compile_options "/D__LIBC_EXPLICIT_SIMD_OPT")
80    endif()
81  endif()
82
83  set(${output_var} ${compile_options} PARENT_SCOPE)
84endfunction(_get_compile_options_from_flags)
85
86function(_get_compile_options_from_config output_var)
87  set(config_options "")
88
89  if(LIBC_CONF_QSORT_IMPL)
90    list(APPEND config_options "-DLIBC_QSORT_IMPL=${LIBC_CONF_QSORT_IMPL}")
91  endif()
92
93  if(LIBC_TYPES_TIME_T_IS_32_BIT AND LLVM_LIBC_FULL_BUILD)
94    list(APPEND config_options "-DLIBC_TYPES_TIME_T_IS_32_BIT")
95  endif()
96
97  if(LIBC_ADD_NULL_CHECKS)
98    list(APPEND config_options "-DLIBC_ADD_NULL_CHECKS")
99  endif()
100
101  if(NOT "${LIBC_CONF_FREXP_INF_NAN_EXPONENT}" STREQUAL "")
102    list(APPEND config_options "-DLIBC_FREXP_INF_NAN_EXPONENT=${LIBC_CONF_FREXP_INF_NAN_EXPONENT}")
103  endif()
104
105  if(LIBC_CONF_MATH_OPTIMIZATIONS)
106    list(APPEND config_options "-DLIBC_MATH=${LIBC_CONF_MATH_OPTIMIZATIONS}")
107  endif()
108
109  set(${output_var} ${config_options} PARENT_SCOPE)
110endfunction(_get_compile_options_from_config)
111
112function(_get_common_compile_options output_var flags)
113  _get_compile_options_from_flags(compile_flags ${flags})
114  _get_compile_options_from_config(config_flags)
115
116  set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${compile_flags} ${config_flags})
117
118  if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE)
119    list(APPEND compile_options "-fpie")
120
121    if(LLVM_LIBC_FULL_BUILD)
122      # Only add -ffreestanding flag in non-GPU full build mode.
123      if(NOT LIBC_TARGET_OS_IS_GPU)
124        list(APPEND compile_options "-ffreestanding")
125      endif()
126      list(APPEND compile_options "-DLIBC_FULL_BUILD")
127      # Manually disable standard include paths to prevent system headers from
128      # being included.
129      if(LIBC_CC_SUPPORTS_NOSTDLIBINC)
130        list(APPEND compile_options "-nostdlibinc")
131      elseif(COMPILER_RESOURCE_DIR)
132        # TODO: We should require COMPILER_RESOURCE_DIR to be set.
133        list(APPEND compile_options "-isystem${COMPILER_RESOURCE_DIR}/include")
134        list(APPEND compile_options "-nostdinc")
135      endif()
136      # TODO: We should set this unconditionally on Linux.
137      if(LIBC_TARGET_OS_IS_LINUX AND
138         (LIBC_CC_SUPPORTS_NOSTDLIBINC OR COMPILER_RESOURCE_DIR))
139        # We use -idirafter to avoid preempting libc's own headers in case the
140        # directory (e.g. /usr/include) contains other headers.
141        if(CMAKE_CROSSCOMPILING)
142          list(APPEND compile_options "-idirafter=${LIBC_KERNEL_HEADERS}")
143        else()
144          list(APPEND compile_options "-idirafter${LIBC_KERNEL_HEADERS}")
145        endif()
146      endif()
147    endif()
148
149    if(LIBC_COMPILER_HAS_FIXED_POINT)
150      list(APPEND compile_options "-ffixed-point")
151    endif()
152
153    if(NOT LIBC_TARGET_OS_IS_GPU)
154      list(APPEND compile_options "-fno-builtin")
155    endif()
156
157    list(APPEND compile_options "-fno-exceptions")
158    list(APPEND compile_options "-fno-lax-vector-conversions")
159    list(APPEND compile_options "-fno-unwind-tables")
160    list(APPEND compile_options "-fno-asynchronous-unwind-tables")
161    list(APPEND compile_options "-fno-rtti")
162    if (LIBC_CC_SUPPORTS_PATTERN_INIT)
163      list(APPEND compile_options "-ftrivial-auto-var-init=pattern")
164    endif()
165    if (LIBC_CONF_KEEP_FRAME_POINTER)
166      list(APPEND compile_options "-fno-omit-frame-pointer")
167      if (LIBC_TARGET_ARCHITECTURE_IS_X86_64)
168        list(APPEND compile_options "-mno-omit-leaf-frame-pointer")
169      endif()
170    endif()
171    if (LIBC_CONF_ENABLE_STACK_PROTECTOR)
172      list(APPEND compile_options "-fstack-protector-strong")
173    endif()
174    list(APPEND compile_options "-Wall")
175    list(APPEND compile_options "-Wextra")
176    # -DLIBC_WNO_ERROR=ON if you can't build cleanly with -Werror.
177    if(NOT LIBC_WNO_ERROR)
178      list(APPEND compile_options "-Werror")
179    endif()
180    list(APPEND compile_options "-Wconversion")
181    list(APPEND compile_options "-Wno-sign-conversion")
182    # Silence this warning because _Complex is a part of C99.
183    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
184      list(APPEND compile_options "-fext-numeric-literals")
185    else()
186      list(APPEND compile_options "-Wno-c99-extensions")
187      list(APPEND compile_options "-Wno-gnu-imaginary-constant")
188    endif()
189    list(APPEND compile_options "-Wno-pedantic")
190    list(APPEND compile_options "-Wimplicit-fallthrough")
191    list(APPEND compile_options "-Wwrite-strings")
192    list(APPEND compile_options "-Wextra-semi")
193    if(NOT CMAKE_COMPILER_IS_GNUCXX)
194      list(APPEND compile_options "-Wnewline-eof")
195      list(APPEND compile_options "-Wnonportable-system-include-path")
196      list(APPEND compile_options "-Wstrict-prototypes")
197      list(APPEND compile_options "-Wthread-safety")
198      list(APPEND compile_options "-Wglobal-constructors")
199    endif()
200  elseif(MSVC)
201    list(APPEND compile_options "/EHs-c-")
202    list(APPEND compile_options "/GR-")
203  endif()
204  if (LIBC_TARGET_OS_IS_GPU)
205    list(APPEND compile_options "-nogpulib")
206    list(APPEND compile_options "-fvisibility=hidden")
207    list(APPEND compile_options "-fconvergent-functions")
208    list(APPEND compile_options "-flto")
209    list(APPEND compile_options "-Wno-multi-gpu")
210
211    if(LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
212      list(APPEND compile_options "-Wno-unknown-cuda-version")
213      list(APPEND compile_options "--cuda-feature=+ptx63")
214      if(LIBC_CUDA_ROOT)
215        list(APPEND compile_options "--cuda-path=${LIBC_CUDA_ROOT}")
216      endif()
217    elseif(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
218      list(APPEND compile_options "SHELL:-Xclang -mcode-object-version=none")
219    endif()
220  endif()
221  set(${output_var} ${compile_options} PARENT_SCOPE)
222endfunction()
223