1include(CMakePushCheckState) 2include(CheckCXXCompilerFlag) 3include(CheckLibraryExists) 4include(CheckSymbolExists) 5include(TestBigEndian) 6 7# CodeGen options. 8check_cxx_compiler_flag(-fPIC COMPILER_RT_HAS_FPIC_FLAG) 9check_cxx_compiler_flag(-fPIE COMPILER_RT_HAS_FPIE_FLAG) 10check_cxx_compiler_flag(-fno-builtin COMPILER_RT_HAS_FNO_BUILTIN_FLAG) 11check_cxx_compiler_flag(-fno-exceptions COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG) 12check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG) 13check_cxx_compiler_flag(-funwind-tables COMPILER_RT_HAS_FUNWIND_TABLES_FLAG) 14check_cxx_compiler_flag(-fno-stack-protector COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG) 15check_cxx_compiler_flag(-fvisibility=hidden COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG) 16check_cxx_compiler_flag(-fno-rtti COMPILER_RT_HAS_FNO_RTTI_FLAG) 17check_cxx_compiler_flag(-ffreestanding COMPILER_RT_HAS_FFREESTANDING_FLAG) 18check_cxx_compiler_flag("-Werror -fno-function-sections" COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG) 19check_cxx_compiler_flag(-std=c++11 COMPILER_RT_HAS_STD_CXX11_FLAG) 20check_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC) 21check_cxx_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG) 22check_cxx_compiler_flag(-msse3 COMPILER_RT_HAS_MSSE3_FLAG) 23 24check_cxx_compiler_flag(/GR COMPILER_RT_HAS_GR_FLAG) 25check_cxx_compiler_flag(/GS COMPILER_RT_HAS_GS_FLAG) 26check_cxx_compiler_flag(/MT COMPILER_RT_HAS_MT_FLAG) 27check_cxx_compiler_flag(/Oy COMPILER_RT_HAS_Oy_FLAG) 28 29# Debug info flags. 30check_cxx_compiler_flag(-gline-tables-only COMPILER_RT_HAS_GLINE_TABLES_ONLY_FLAG) 31check_cxx_compiler_flag(-g COMPILER_RT_HAS_G_FLAG) 32check_cxx_compiler_flag(/Zi COMPILER_RT_HAS_Zi_FLAG) 33 34# Warnings. 35check_cxx_compiler_flag(-Wall COMPILER_RT_HAS_WALL_FLAG) 36check_cxx_compiler_flag(-Werror COMPILER_RT_HAS_WERROR_FLAG) 37check_cxx_compiler_flag("-Werror -Wframe-larger-than=512" COMPILER_RT_HAS_WFRAME_LARGER_THAN_FLAG) 38check_cxx_compiler_flag("-Werror -Wglobal-constructors" COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG) 39check_cxx_compiler_flag("-Werror -Wc99-extensions" COMPILER_RT_HAS_WC99_EXTENSIONS_FLAG) 40check_cxx_compiler_flag("-Werror -Wgnu" COMPILER_RT_HAS_WGNU_FLAG) 41check_cxx_compiler_flag("-Werror -Wnon-virtual-dtor" COMPILER_RT_HAS_WNON_VIRTUAL_DTOR_FLAG) 42check_cxx_compiler_flag("-Werror -Wvariadic-macros" COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG) 43 44check_cxx_compiler_flag(/W3 COMPILER_RT_HAS_W3_FLAG) 45check_cxx_compiler_flag(/WX COMPILER_RT_HAS_WX_FLAG) 46check_cxx_compiler_flag(/wd4146 COMPILER_RT_HAS_WD4146_FLAG) 47check_cxx_compiler_flag(/wd4291 COMPILER_RT_HAS_WD4291_FLAG) 48check_cxx_compiler_flag(/wd4391 COMPILER_RT_HAS_WD4391_FLAG) 49check_cxx_compiler_flag(/wd4722 COMPILER_RT_HAS_WD4722_FLAG) 50check_cxx_compiler_flag(/wd4800 COMPILER_RT_HAS_WD4800_FLAG) 51 52# Symbols. 53check_symbol_exists(__func__ "" COMPILER_RT_HAS_FUNC_SYMBOL) 54 55# Libraries. 56check_library_exists(c printf "" COMPILER_RT_HAS_LIBC) 57check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL) 58check_library_exists(m pow "" COMPILER_RT_HAS_LIBM) 59check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) 60check_library_exists(stdc++ __cxa_throw "" COMPILER_RT_HAS_LIBSTDCXX) 61 62# Architectures. 63 64# List of all architectures we can target. 65set(COMPILER_RT_SUPPORTED_ARCH) 66 67# Try to compile a very simple source file to ensure we can target the given 68# platform. We use the results of these tests to build only the various target 69# runtime libraries supported by our current compilers cross-compiling 70# abilities. 71set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc) 72file(WRITE ${SIMPLE_SOURCE} "#include <stdlib.h>\n#include <limits>\nint main() {}\n") 73 74function(check_compile_definition def argstring out_var) 75 if("${def}" STREQUAL "") 76 set(${out_var} TRUE PARENT_SCOPE) 77 return() 78 endif() 79 cmake_push_check_state() 80 set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${argstring}") 81 check_symbol_exists(${def} "" ${out_var}) 82 cmake_pop_check_state() 83endfunction() 84 85# test_target_arch(<arch> <def> <target flags...>) 86# Checks if architecture is supported: runs host compiler with provided 87# flags to verify that: 88# 1) <def> is defined (if non-empty) 89# 2) simple file can be successfully built. 90# If successful, saves target flags for this architecture. 91macro(test_target_arch arch def) 92 set(TARGET_${arch}_CFLAGS ${ARGN}) 93 set(argstring "") 94 foreach(arg ${ARGN}) 95 set(argstring "${argstring} ${arg}") 96 endforeach() 97 check_compile_definition("${def}" "${argstring}" HAS_${arch}_DEF) 98 if(NOT HAS_${arch}_DEF) 99 set(CAN_TARGET_${arch} FALSE) 100 else() 101 set(argstring "${CMAKE_EXE_LINKER_FLAGS} ${argstring}") 102 try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE} 103 COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS}" 104 OUTPUT_VARIABLE TARGET_${arch}_OUTPUT 105 CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${argstring}") 106 endif() 107 if(${CAN_TARGET_${arch}}) 108 list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) 109 elseif("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "${arch}") 110 # Bail out if we cannot target the architecture we plan to test. 111 message(FATAL_ERROR "Cannot compile for ${arch}:\n${TARGET_${arch}_OUTPUT}") 112 endif() 113endmacro() 114 115# Add $arch as supported with no additional flags. 116macro(add_default_target_arch arch) 117 set(TARGET_${arch}_CFLAGS "") 118 set(CAN_TARGET_${arch} 1) 119 list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) 120endmacro() 121 122macro(detect_target_arch) 123 check_symbol_exists(__arm__ "" __ARM) 124 check_symbol_exists(__aarch64__ "" __AARCH64) 125 check_symbol_exists(__x86_64__ "" __X86_64) 126 check_symbol_exists(__i686__ "" __I686) 127 check_symbol_exists(__i386__ "" __I386) 128 check_symbol_exists(__mips__ "" __MIPS) 129 check_symbol_exists(__mips64__ "" __MIPS64) 130 if(__ARM) 131 add_default_target_arch(arm) 132 elseif(__AARCH64) 133 add_default_target_arch(aarch64) 134 elseif(__X86_64) 135 add_default_target_arch(x86_64) 136 elseif(__I686) 137 add_default_target_arch(i686) 138 elseif(__I386) 139 add_default_target_arch(i386) 140 elseif(__MIPS64) # must be checked before __MIPS 141 add_default_target_arch(mips64) 142 elseif(__MIPS) 143 add_default_target_arch(mips) 144 endif() 145endmacro() 146 147# Detect whether the current target platform is 32-bit or 64-bit, and setup 148# the correct commandline flags needed to attempt to target 32-bit and 64-bit. 149if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND 150 NOT CMAKE_SIZEOF_VOID_P EQUAL 8) 151 message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.") 152endif() 153 154# Generate the COMPILER_RT_SUPPORTED_ARCH list. 155if(ANDROID) 156 # Can't rely on LLVM_NATIVE_ARCH in cross-compilation. 157 # Examine compiler output instead. 158 detect_target_arch() 159 set(COMPILER_RT_OS_SUFFIX "-android") 160else() 161 if("${LLVM_NATIVE_ARCH}" STREQUAL "X86") 162 if(NOT MSVC) 163 test_target_arch(x86_64 "" "-m64") 164 # FIXME: We build runtimes for both i686 and i386, as "clang -m32" may 165 # target different variant than "$CMAKE_C_COMPILER -m32". This part should 166 # be gone after we resolve PR14109. 167 test_target_arch(i686 __i686__ "-m32") 168 test_target_arch(i386 __i386__ "-m32") 169 else() 170 test_target_arch(i386 "" "") 171 endif() 172 elseif("${LLVM_NATIVE_ARCH}" STREQUAL "PowerPC") 173 TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN) 174 if(HOST_IS_BIG_ENDIAN) 175 test_target_arch(powerpc64 "" "-m64") 176 else() 177 test_target_arch(powerpc64le "" "-m64") 178 endif() 179 elseif("${LLVM_NATIVE_ARCH}" STREQUAL "Mips") 180 if("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "mipsel|mips64el") 181 # regex for mipsel, mips64el 182 test_target_arch(mipsel "" "-m32") 183 test_target_arch(mips64el "" "-m64") 184 else() 185 test_target_arch(mips "" "-m32") 186 test_target_arch(mips64 "" "-m64") 187 endif() 188 elseif("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "arm") 189 test_target_arch(arm "" "-march=armv7-a") 190 elseif("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "aarch32") 191 test_target_arch(aarch32 "" "-march=armv8-a") 192 elseif("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "aarch64") 193 test_target_arch(aarch64 "" "-march=armv8-a") 194 endif() 195 set(COMPILER_RT_OS_SUFFIX "") 196endif() 197 198message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}") 199 200# Takes ${ARGN} and puts only supported architectures in @out_var list. 201function(filter_available_targets out_var) 202 set(archs) 203 foreach(arch ${ARGN}) 204 list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX) 205 if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch}) 206 list(APPEND archs ${arch}) 207 endif() 208 endforeach() 209 set(${out_var} ${archs} PARENT_SCOPE) 210endfunction() 211 212function(get_target_flags_for_arch arch out_var) 213 list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX) 214 if(ARCH_INDEX EQUAL -1) 215 message(FATAL_ERROR "Unsupported architecture: ${arch}") 216 else() 217 set(${out_var} ${TARGET_${arch}_CFLAGS} PARENT_SCOPE) 218 endif() 219endfunction() 220 221# Architectures supported by compiler-rt libraries. 222filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH 223 x86_64 i386 i686 powerpc64 powerpc64le arm aarch64 mips mips64 mipsel mips64el) 224# LSan and UBSan common files should be available on all architectures supported 225# by other sanitizers (even if they build into dummy object files). 226filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH 227 ${SANITIZER_COMMON_SUPPORTED_ARCH}) 228filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH 229 ${SANITIZER_COMMON_SUPPORTED_ARCH}) 230filter_available_targets(ASAN_SUPPORTED_ARCH 231 x86_64 i386 i686 powerpc64 powerpc64le arm mips mipsel mips64 mips64el) 232filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) 233filter_available_targets(LSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) 234filter_available_targets(MSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) 235filter_available_targets(PROFILE_SUPPORTED_ARCH x86_64 i386 i686 arm mips mips64 236 mipsel mips64el aarch64 powerpc64 powerpc64le) 237filter_available_targets(TSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) 238filter_available_targets(UBSAN_SUPPORTED_ARCH x86_64 i386 i686 arm aarch64 mips 239 mipsel mips64 mips64el powerpc64 powerpc64le) 240 241if(ANDROID) 242 set(OS_NAME "Android") 243else() 244 set(OS_NAME "${CMAKE_SYSTEM_NAME}") 245endif() 246 247if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND 248 (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD" OR 249 (OS_NAME MATCHES "Windows" AND MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 4))) 250 set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE) 251else() 252 set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE) 253endif() 254 255if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH) 256 set(COMPILER_RT_HAS_ASAN TRUE) 257else() 258 set(COMPILER_RT_HAS_ASAN FALSE) 259endif() 260 261if (OS_NAME MATCHES "Linux|FreeBSD|Windows") 262 set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE) 263else() 264 set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE) 265endif() 266 267# TODO: Add builtins support. 268 269if (COMPILER_RT_HAS_SANITIZER_COMMON AND DFSAN_SUPPORTED_ARCH AND 270 OS_NAME MATCHES "Linux") 271 set(COMPILER_RT_HAS_DFSAN TRUE) 272else() 273 set(COMPILER_RT_HAS_DFSAN FALSE) 274endif() 275 276if (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND 277 OS_NAME MATCHES "Darwin|Linux|FreeBSD") 278 set(COMPILER_RT_HAS_LSAN TRUE) 279else() 280 set(COMPILER_RT_HAS_LSAN FALSE) 281endif() 282 283if (COMPILER_RT_HAS_SANITIZER_COMMON AND MSAN_SUPPORTED_ARCH AND 284 OS_NAME MATCHES "Linux") 285 set(COMPILER_RT_HAS_MSAN TRUE) 286else() 287 set(COMPILER_RT_HAS_MSAN FALSE) 288endif() 289 290if (PROFILE_SUPPORTED_ARCH AND 291 OS_NAME MATCHES "Darwin|Linux|FreeBSD") 292 set(COMPILER_RT_HAS_PROFILE TRUE) 293else() 294 set(COMPILER_RT_HAS_PROFILE FALSE) 295endif() 296 297if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND 298 OS_NAME MATCHES "Linux|FreeBSD") 299 set(COMPILER_RT_HAS_TSAN TRUE) 300else() 301 set(COMPILER_RT_HAS_TSAN FALSE) 302endif() 303 304if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND 305 OS_NAME MATCHES "Darwin|Linux|FreeBSD") 306 set(COMPILER_RT_HAS_UBSAN TRUE) 307else() 308 set(COMPILER_RT_HAS_UBSAN FALSE) 309endif() 310 311# -msse3 flag is not valid for Mips therefore clang gives a warning 312# message with -msse3. But check_c_compiler_flags() checks only for 313# compiler error messages. Therefore COMPILER_RT_HAS_MSSE3_FLAG turns out to be 314# true on Mips. So we make it false here. 315if("${LLVM_NATIVE_ARCH}" STREQUAL "Mips") 316 set(COMPILER_RT_HAS_MSSE3_FLAG FALSE) 317endif() 318