1# CMake build for CompilerRT. 2# 3# An important constraint of the build is that it only produces libraries 4# based on the ability of the host toolchain to target various platforms. 5 6cmake_minimum_required(VERSION 3.13.4) 7 8# Check if compiler-rt is built as a standalone project. 9if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR COMPILER_RT_STANDALONE_BUILD) 10 project(CompilerRT C CXX ASM) 11 set(COMPILER_RT_STANDALONE_BUILD TRUE) 12 set_property(GLOBAL PROPERTY USE_FOLDERS ON) 13endif() 14 15set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") 16 17# Add path for custom compiler-rt modules. 18list(INSERT CMAKE_MODULE_PATH 0 19 "${CMAKE_CURRENT_SOURCE_DIR}/cmake" 20 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" 21 "${LLVM_COMMON_CMAKE_UTILS}" 22 "${LLVM_COMMON_CMAKE_UTILS}/Modules" 23 ) 24 25if(CMAKE_CONFIGURATION_TYPES) 26 set(CMAKE_CFG_RESOLVED_INTDIR "${CMAKE_CFG_INTDIR}/") 27else() 28 set(CMAKE_CFG_RESOLVED_INTDIR "") 29endif() 30 31include(SetPlatformToolchainTools) 32include(base-config-ix) 33include(CompilerRTUtils) 34include(CMakeDependentOption) 35 36option(COMPILER_RT_BUILD_BUILTINS "Build builtins" ON) 37mark_as_advanced(COMPILER_RT_BUILD_BUILTINS) 38option(COMPILER_RT_BUILD_CRT "Build crtbegin.o/crtend.o" ON) 39mark_as_advanced(COMPILER_RT_BUILD_CRT) 40option(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY "Use eh_frame in crtbegin.o/crtend.o" ON) 41mark_as_advanced(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY) 42option(COMPILER_RT_BUILD_SANITIZERS "Build sanitizers" ON) 43mark_as_advanced(COMPILER_RT_BUILD_SANITIZERS) 44option(COMPILER_RT_BUILD_XRAY "Build xray" ON) 45mark_as_advanced(COMPILER_RT_BUILD_XRAY) 46option(COMPILER_RT_BUILD_LIBFUZZER "Build libFuzzer" ON) 47mark_as_advanced(COMPILER_RT_BUILD_LIBFUZZER) 48option(COMPILER_RT_BUILD_PROFILE "Build profile runtime" ON) 49mark_as_advanced(COMPILER_RT_BUILD_PROFILE) 50option(COMPILER_RT_BUILD_MEMPROF "Build memory profiling runtime" ON) 51mark_as_advanced(COMPILER_RT_BUILD_MEMPROF) 52option(COMPILER_RT_BUILD_XRAY_NO_PREINIT "Build xray with no preinit patching" OFF) 53mark_as_advanced(COMPILER_RT_BUILD_XRAY_NO_PREINIT) 54option(COMPILER_RT_BUILD_ORC "Build ORC runtime" ON) 55mark_as_advanced(COMPILER_RT_BUILD_ORC) 56option(COMPILER_RT_BUILD_GWP_ASAN "Build GWP-ASan, and link it into SCUDO" ON) 57mark_as_advanced(COMPILER_RT_BUILD_GWP_ASAN) 58option(COMPILER_RT_ENABLE_CET "Build Compiler RT with CET enabled" OFF) 59 60if(FUCHSIA) 61 set(COMPILER_RT_HWASAN_WITH_INTERCEPTORS_DEFAULT OFF) 62else() 63 set(COMPILER_RT_HWASAN_WITH_INTERCEPTORS_DEFAULT ON) 64endif() 65set(COMPILER_RT_HWASAN_WITH_INTERCEPTORS ${COMPILER_RT_HWASAN_WITH_INTERCEPTORS_DEFAULT} CACHE BOOL "Enable libc interceptors in HWASan (testing mode)") 66 67set(COMPILER_RT_BAREMETAL_BUILD OFF CACHE BOOL 68 "Build for a bare-metal target.") 69 70if (COMPILER_RT_STANDALONE_BUILD) 71 load_llvm_config() 72 if (TARGET intrinsics_gen) 73 # Loading the llvm config causes this target to be imported so place it 74 # under the appropriate folder in an IDE. 75 set_target_properties(intrinsics_gen PROPERTIES FOLDER "Compiler-RT Misc") 76 endif() 77 78 find_package(Python3 COMPONENTS Interpreter) 79 if(NOT Python3_Interpreter_FOUND) 80 message(WARNING "Python3 not found, using python2 as a fallback") 81 find_package(Python2 COMPONENTS Interpreter REQUIRED) 82 if(Python2_VERSION VERSION_LESS 2.7) 83 message(SEND_ERROR "Python 2.7 or newer is required") 84 endif() 85 86 # Treat python2 as python3 87 add_executable(Python3::Interpreter IMPORTED) 88 set_target_properties(Python3::Interpreter PROPERTIES 89 IMPORTED_LOCATION ${Python2_EXECUTABLE}) 90 set(Python3_EXECUTABLE ${Python2_EXECUTABLE}) 91 endif() 92 93 # Ensure that fat libraries are built correctly on Darwin 94 if(APPLE) 95 include(UseLibtool) 96 endif() 97 98 # Define default arguments to lit. 99 set(LIT_ARGS_DEFAULT "-sv") 100 if (MSVC OR XCODE) 101 set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") 102 endif() 103 set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") 104 set(LLVM_LIT_OUTPUT_DIR "${COMPILER_RT_EXEC_OUTPUT_DIR}") 105endif() 106 107construct_compiler_rt_default_triple() 108if ("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES ".*hf$") 109 if (${COMPILER_RT_DEFAULT_TARGET_ARCH} MATCHES "^arm") 110 set(COMPILER_RT_DEFAULT_TARGET_ARCH "armhf") 111 CHECK_SYMBOL_EXISTS (__thumb__ "" COMPILER_RT_ARM_THUMB) 112 endif() 113endif() 114if ("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES ".*android.*") 115 set(ANDROID 1) 116 string(REGEX MATCH "-target(=| +)[^ ]+android[a-z]*([0-9]+)" ANDROID_API_LEVEL "${CMAKE_C_FLAGS}") 117 set(ANDROID_API_LEVEL ${CMAKE_MATCH_2}) 118endif() 119pythonize_bool(ANDROID) 120 121set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 122set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) 123 124pythonize_bool(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR) 125 126# We support running instrumented tests when we're not cross compiling 127# and target a UNIX-like system or Windows. 128# We can run tests on Android even when we are cross-compiling. 129if(("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND (UNIX OR WIN32)) OR ANDROID 130 OR COMPILER_RT_EMULATOR) 131 option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" ON) 132else() 133 option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" OFF) 134endif() 135 136option(COMPILER_RT_DEBUG "Build runtimes with full debug info" OFF) 137option(COMPILER_RT_EXTERNALIZE_DEBUGINFO 138 "Generate dSYM files and strip executables and libraries (Darwin Only)" OFF) 139# COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in. 140pythonize_bool(COMPILER_RT_DEBUG) 141 142option(COMPILER_RT_INTERCEPT_LIBDISPATCH 143 "Support interception of libdispatch (GCD). Requires '-fblocks'" OFF) 144option(COMPILER_RT_LIBDISPATCH_INSTALL_PATH 145 "Specify if libdispatch is installed in a custom location" "") 146if (COMPILER_RT_INTERCEPT_LIBDISPATCH AND NOT APPLE) 147 set(COMPILER_RT_LIBDISPATCH_CFLAGS -fblocks) 148 set(COMPILER_RT_TEST_LIBDISPATCH_CFLAGS) 149 if (COMPILER_RT_LIBDISPATCH_INSTALL_PATH) 150 list(APPEND COMPILER_RT_TEST_LIBDISPATCH_CFLAGS 151 -I${COMPILER_RT_LIBDISPATCH_INSTALL_PATH}/include 152 -L${COMPILER_RT_LIBDISPATCH_INSTALL_PATH}/lib 153 -Wl,-rpath=${COMPILER_RT_LIBDISPATCH_INSTALL_PATH}/lib) 154 endif() 155 list(APPEND COMPILER_RT_TEST_LIBDISPATCH_CFLAGS -lBlocksRuntime -ldispatch) 156endif() 157if (APPLE) # Always enable on Apple platforms. 158 set(COMPILER_RT_INTERCEPT_LIBDISPATCH ON) 159endif() 160pythonize_bool(COMPILER_RT_INTERCEPT_LIBDISPATCH) 161 162if(APPLE AND SANITIZER_MIN_OSX_VERSION AND SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.9") 163 # Mac OS X prior to 10.9 had problems with exporting symbols from 164 # libc++/libc++abi. 165 set(cxxabi_supported OFF) 166else() 167 set(cxxabi_supported ON) 168endif() 169 170option(SANITIZER_ALLOW_CXXABI "Allow use of C++ ABI details in ubsan" ON) 171 172set(SANITIZER_CAN_USE_CXXABI OFF) 173if (cxxabi_supported AND SANITIZER_ALLOW_CXXABI) 174 set(SANITIZER_CAN_USE_CXXABI ON) 175endif() 176pythonize_bool(SANITIZER_CAN_USE_CXXABI) 177 178macro(handle_default_cxx_lib var) 179 # Specifying -stdlib= in CMAKE_CXX_FLAGS overrides the defaults. 180 if (CMAKE_CXX_FLAGS MATCHES "-stdlib=([a-zA-Z+]*)") 181 set(${var}_LIBNAME "${CMAKE_MATCH_1}") 182 set(${var}_SYSTEM 1) 183 elseif (${var} STREQUAL "default") 184 if (APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") 185 set(${var}_LIBNAME "libc++") 186 set(${var}_SYSTEM 1) 187 elseif (FUCHSIA) 188 set(${var}_LIBNAME "libc++") 189 set(${var}_INTREE 1) 190 else() 191 set(${var}_LIBNAME "libstdc++") 192 set(${var}_SYSTEM 1) 193 endif() 194 else() 195 set(${var}_LIBNAME "${${var}}") 196 set(${var}_SYSTEM 1) 197 endif() 198endmacro() 199 200# This is either directly the C++ ABI library or the full C++ library 201# which pulls in the ABI transitively. 202# TODO: Mark this as internal flag, most users should use COMPILER_RT_CXX_LIBRARY. 203set(SANITIZER_CXX_ABI "default" CACHE STRING 204 "Specify C++ ABI library to use.") 205set(CXXABIS none default libstdc++ libc++ libcxxabi) 206set_property(CACHE SANITIZER_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) 207handle_default_cxx_lib(SANITIZER_CXX_ABI) 208 209# This needs to be a full C++ library for linking gtest and unit tests. 210# TODO: Mark this as internal flag, most users should use COMPILER_RT_CXX_LIBRARY. 211set(SANITIZER_TEST_CXX "default" CACHE STRING 212 "Specify C++ library to use for tests.") 213set(CXXLIBS none default libstdc++ libc++) 214set_property(CACHE SANITIZER_TEST_CXX PROPERTY STRINGS ;${CXXLIBS}) 215handle_default_cxx_lib(SANITIZER_TEST_CXX) 216 217option(COMPILER_RT_USE_LLVM_UNWINDER "Use the LLVM unwinder." OFF) 218cmake_dependent_option(COMPILER_RT_ENABLE_STATIC_UNWINDER 219 "Statically link the LLVM unwinder." OFF 220 "COMPILER_RT_USE_LLVM_UNWINDER" OFF) 221 222set(DEFAULT_SANITIZER_USE_STATIC_LLVM_UNWINDER OFF) 223if (FUCHSIA) 224 set(DEFAULT_SANITIZER_USE_STATIC_LLVM_UNWINDER ON) 225elseif (DEFINED LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_SHARED) 226 set(DEFAULT_SANITIZER_USE_STATIC_LLVM_UNWINDER ON) 227endif() 228 229option(SANITIZER_USE_STATIC_LLVM_UNWINDER 230 "Use static LLVM unwinder." ${DEFAULT_SANITIZER_USE_STATIC_LLVM_UNWINDER}) 231pythonize_bool(SANITIZER_USE_STATIC_LLVM_UNWINDER) 232 233set(DEFAULT_SANITIZER_USE_STATIC_CXX_ABI OFF) 234if (DEFINED LIBCXXABI_ENABLE_SHARED AND NOT LIBCXXABI_ENABLE_SHARED) 235 set(DEFAULT_SANITIZER_USE_STATIC_CXX_ABI ON) 236endif() 237 238option(SANITIZER_USE_STATIC_CXX_ABI 239 "Use static libc++abi." ${DEFAULT_SANITIZER_USE_STATIC_CXX_ABI}) 240pythonize_bool(SANITIZER_USE_STATIC_CXX_ABI) 241 242set(DEFAULT_SANITIZER_USE_STATIC_TEST_CXX OFF) 243if (DEFINED LIBCXX_ENABLE_SHARED AND NOT LIBCXX_ENABLE_SHARED) 244 set(DEFAULT_SANITIZER_USE_STATIC_TEST_CXX ON) 245endif() 246 247option(SANITIZER_USE_STATIC_TEST_CXX 248 "Use static libc++ for tests." ${DEFAULT_SANITIZER_USE_STATIC_TEST_CXX}) 249pythonize_bool(SANITIZER_USE_STATIC_TEST_CXX) 250 251set(COMPILER_RT_SUPPORTED_CXX_LIBRARIES none default libcxx) 252set(COMPILER_RT_CXX_LIBRARY "default" CACHE STRING "Specify C++ library to use. Supported values are ${COMPILER_RT_SUPPORTED_CXX_LIBRARIES}.") 253if (NOT "${COMPILER_RT_CXX_LIBRARY}" IN_LIST COMPILER_RT_SUPPORTED_CXX_LIBRARIES) 254 message(FATAL_ERROR "Unsupported C++ library: '${COMPILER_RT_CXX_LIBRARY}'. Supported values are ${COMPILER_RT_SUPPORTED_CXX_LIBRARIES}.") 255endif() 256cmake_dependent_option(COMPILER_RT_STATIC_CXX_LIBRARY 257 "Statically link the C++ library." OFF 258 "COMPILER_RT_CXX_LIBRARY" OFF) 259 260set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY OFF) 261if (FUCHSIA) 262 set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY ON) 263endif() 264 265option(COMPILER_RT_USE_BUILTINS_LIBRARY 266 "Use compiler-rt builtins instead of libgcc" ${DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY}) 267 268include(config-ix) 269 270#================================ 271# Setup Compiler Flags 272#================================ 273 274# fcf-protection is a gcc/clang option for CET support on Linux platforms. 275# We need to handle MSVC CET option on Windows platforms. 276if (NOT MSVC) 277 if (COMPILER_RT_ENABLE_CET AND NOT COMPILER_RT_HAS_FCF_PROTECTION_FLAG) 278 message(FATAL_ERROR "Compiler used to build compiler-rt doesn't support CET!") 279 endif() 280endif() 281 282if(MSVC) 283 # Override any existing /W flags with /W4. This is what LLVM does. Failing to 284 # remove other /W[0-4] flags will result in a warning about overriding a 285 # previous flag. 286 if (COMPILER_RT_HAS_W4_FLAG) 287 string(REGEX REPLACE " /W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") 288 string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 289 append_string_if(COMPILER_RT_HAS_W4_FLAG /W4 CMAKE_C_FLAGS CMAKE_CXX_FLAGS) 290 endif() 291else() 292 append_string_if(COMPILER_RT_HAS_WALL_FLAG -Wall CMAKE_C_FLAGS CMAKE_CXX_FLAGS) 293endif() 294if(COMPILER_RT_ENABLE_WERROR) 295 append_string_if(COMPILER_RT_HAS_WERROR_FLAG -Werror CMAKE_C_FLAGS CMAKE_CXX_FLAGS) 296 append_string_if(COMPILER_RT_HAS_WX_FLAG /WX CMAKE_C_FLAGS CMAKE_CXX_FLAGS) 297endif() 298 299append_string_if(COMPILER_RT_HAS_STD_CXX14_FLAG -std=c++14 CMAKE_CXX_FLAGS) 300 301# Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP. 302if(NOT COMPILER_RT_HAS_FUNC_SYMBOL) 303 add_definitions(-D__func__=__FUNCTION__) 304endif() 305 306# Provide some common commandline flags for Sanitizer runtimes. 307if("${ANDROID_API_LEVEL}" GREATER_EQUAL 29) 308 list(APPEND SANITIZER_COMMON_CFLAGS -fno-emulated-tls) 309 string(APPEND COMPILER_RT_TEST_COMPILER_CFLAGS " -fno-emulated-tls") 310endif() 311if(NOT WIN32) 312 append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC SANITIZER_COMMON_CFLAGS) 313endif() 314append_list_if(COMPILER_RT_HAS_FNO_BUILTIN_FLAG -fno-builtin SANITIZER_COMMON_CFLAGS) 315append_list_if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions SANITIZER_COMMON_CFLAGS) 316if(NOT COMPILER_RT_DEBUG AND NOT APPLE) 317 append_list_if(COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG -fomit-frame-pointer SANITIZER_COMMON_CFLAGS) 318endif() 319append_list_if(COMPILER_RT_HAS_FUNWIND_TABLES_FLAG -funwind-tables SANITIZER_COMMON_CFLAGS) 320append_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS) 321append_list_if(COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG -fno-sanitize=safe-stack SANITIZER_COMMON_CFLAGS) 322append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANITIZER_COMMON_CFLAGS) 323if(NOT COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG) 324 append_list_if(COMPILER_RT_HAS_FVISIBILITY_INLINES_HIDDEN_FLAG -fvisibility-inlines-hidden SANITIZER_COMMON_CFLAGS) 325endif() 326append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS) 327 328# By default do not instrument or use profdata for compiler-rt. 329if(NOT COMPILER_RT_ENABLE_PGO) 330 if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG) 331 list(APPEND SANITIZER_COMMON_CFLAGS "-fno-profile-instr-use") 332 endif() 333 if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG) 334 list(APPEND SANITIZER_COMMON_CFLAGS "-fno-profile-generate") 335 elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG) 336 list(APPEND SANITIZER_COMMON_CFLAGS "-fno-profile-instr-generate") 337 if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG) 338 list(APPEND SANITIZER_COMMON_CFLAGS "-fno-coverage-mapping") 339 endif() 340 endif() 341endif() 342 343# The following is a workaround for powerpc64le. This is the only architecture 344# that requires -fno-function-sections to work properly. If lacking, the ASan 345# Linux test function-sections-are-bad.cpp fails with the following error: 346# 'undefined symbol: __sanitizer_unaligned_load32'. 347if(DEFINED TARGET_powerpc64le_CFLAGS) 348 if(CMAKE_CXX_COMPILER_ID MATCHES "XL") 349 append("-qnofuncsect" TARGET_powerpc64le_CFLAGS) 350 else() 351 append_list_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG -fno-function-sections TARGET_powerpc64le_CFLAGS) 352 endif() 353endif() 354 355# The following is a workaround for s390x. This avoids creation of "partial 356# inline" function fragments when building the asan libraries with certain 357# GCC versions. The presence of those fragments, in particular for the 358# interceptors, changes backtraces seen in asan error cases, which causes 359# testsuite failures. 360if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x") 361 append_list_if(COMPILER_RT_HAS_FNO_PARTIAL_INLINING_FLAG -fno-partial-inlining SANITIZER_COMMON_CFLAGS) 362endif() 363 364if(MSVC) 365 # Replace the /M[DT][d] flags with /MT, and strip any definitions of _DEBUG, 366 # which cause definition mismatches at link time. 367 # FIXME: In fact, sanitizers should support both /MT and /MD, see PR20214. 368 if(COMPILER_RT_HAS_MT_FLAG) 369 foreach(flag_var 370 CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE 371 CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO 372 CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE 373 CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) 374 string(REGEX REPLACE "/M[DT]d" "/MT" ${flag_var} "${${flag_var}}") 375 string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") 376 string(REGEX REPLACE "/D_DEBUG" "" ${flag_var} "${${flag_var}}") 377 endforeach() 378 endif() 379 append_list_if(COMPILER_RT_HAS_Oy_FLAG /Oy- SANITIZER_COMMON_CFLAGS) 380 append_list_if(COMPILER_RT_HAS_GS_FLAG /GS- SANITIZER_COMMON_CFLAGS) 381 382 # Disable thread safe initialization for static locals. ASan shouldn't need 383 # it. Thread safe initialization assumes that the CRT has already been 384 # initialized, but ASan initializes before the CRT. 385 list(APPEND SANITIZER_COMMON_CFLAGS /Zc:threadSafeInit-) 386endif() 387 388append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 SANITIZER_COMMON_CFLAGS) 389 390if(CMAKE_CXX_COMPILER_ID MATCHES Clang) 391 list(APPEND THREAD_SAFETY_FLAGS 392 "-Wthread-safety" 393 "-Wthread-safety-reference" 394 "-Wthread-safety-beta" 395 ) 396 list(APPEND SANITIZER_COMMON_CFLAGS ${THREAD_SAFETY_FLAGS}) 397 string(REPLACE ";" " " thread_safety_flags_space_sep "${THREAD_SAFETY_FLAGS}") 398 string(APPEND COMPILER_RT_TEST_COMPILER_CFLAGS " ${thread_safety_flags_space_sep}") 399endif() 400 401# If we're using MSVC, 402# always respect the optimization flags set by CMAKE_BUILD_TYPE instead. 403if (NOT MSVC) 404 405 # Build with optimization, unless we're in debug mode. 406 if(COMPILER_RT_DEBUG) 407 list(APPEND SANITIZER_COMMON_CFLAGS -O1) 408 else() 409 list(APPEND SANITIZER_COMMON_CFLAGS -O3) 410 endif() 411endif() 412 413# Determine if we should restrict stack frame sizes. 414# Stack frames on PowerPC, Mips, SystemZ and in debug build can be much larger than 415# anticipated. 416# FIXME: Fix all sanitizers and add -Wframe-larger-than to 417# SANITIZER_COMMON_FLAGS 418if(COMPILER_RT_HAS_WFRAME_LARGER_THAN_FLAG AND NOT COMPILER_RT_DEBUG 419 AND NOT ${COMPILER_RT_DEFAULT_TARGET_ARCH} MATCHES "powerpc|mips|s390x") 420 set(SANITIZER_LIMIT_FRAME_SIZE TRUE) 421else() 422 set(SANITIZER_LIMIT_FRAME_SIZE FALSE) 423endif() 424 425if(FUCHSIA OR UNIX) 426 set(SANITIZER_USE_SYMBOLS TRUE) 427else() 428 set(SANITIZER_USE_SYMBOLS FALSE) 429endif() 430 431# Build sanitizer runtimes with debug info. 432if(MSVC) 433 # Use /Z7 instead of /Zi for the asan runtime. This avoids the LNK4099 434 # warning from the MS linker complaining that it can't find the 'vc140.pdb' 435 # file used by our object library compilations. 436 list(APPEND SANITIZER_COMMON_CFLAGS /Z7) 437 foreach(var_to_update 438 CMAKE_CXX_FLAGS 439 CMAKE_CXX_FLAGS_DEBUG 440 CMAKE_CXX_FLAGS_RELWITHDEBINFO) 441 string(REGEX REPLACE "(^| )/Z[i7I]($| )" " /Z7 " 442 "${var_to_update}" "${${var_to_update}}") 443 endforeach() 444elseif(APPLE) 445 # On Apple platforms use full debug info (i.e. not `-gline-tables-only`) 446 # for all build types so that the runtime can be debugged. 447 if(NOT COMPILER_RT_HAS_G_FLAG) 448 message(FATAL_ERROR "-g is not supported by host compiler") 449 endif() 450 list(APPEND SANITIZER_COMMON_CFLAGS -g) 451elseif(COMPILER_RT_HAS_GLINE_TABLES_ONLY_FLAG AND NOT COMPILER_RT_DEBUG) 452 list(APPEND SANITIZER_COMMON_CFLAGS -gline-tables-only) 453elseif(COMPILER_RT_HAS_G_FLAG) 454 list(APPEND SANITIZER_COMMON_CFLAGS -g) 455endif() 456 457if(LLVM_ENABLE_MODULES) 458 # Sanitizers cannot be built with -fmodules. The interceptors intentionally 459 # don't include system headers, which is incompatible with modules. 460 list(APPEND SANITIZER_COMMON_CFLAGS -fno-modules) 461endif() 462 463# Turn off several warnings. 464append_list_if(COMPILER_RT_HAS_WGNU_FLAG -Wno-gnu SANITIZER_COMMON_CFLAGS) 465append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros SANITIZER_COMMON_CFLAGS) 466append_list_if(COMPILER_RT_HAS_WC99_EXTENSIONS_FLAG -Wno-c99-extensions SANITIZER_COMMON_CFLAGS) 467# format-pedantic warns about passing T* for %p, which is not useful. 468append_list_if(COMPILER_RT_HAS_WD4146_FLAG /wd4146 SANITIZER_COMMON_CFLAGS) 469append_list_if(COMPILER_RT_HAS_WD4291_FLAG /wd4291 SANITIZER_COMMON_CFLAGS) 470append_list_if(COMPILER_RT_HAS_WD4391_FLAG /wd4391 SANITIZER_COMMON_CFLAGS) 471append_list_if(COMPILER_RT_HAS_WD4722_FLAG /wd4722 SANITIZER_COMMON_CFLAGS) 472append_list_if(COMPILER_RT_HAS_WD4800_FLAG /wd4800 SANITIZER_COMMON_CFLAGS) 473 474append_list_if(MINGW -fms-extensions SANITIZER_COMMON_CFLAGS) 475 476# Set common link flags. 477# TODO: We should consider using the same model as libc++, that is use either 478# -nostdlib++ and --unwindlib=none if supported, or -nodefaultlibs otherwise. 479append_list_if(C_SUPPORTS_NODEFAULTLIBS_FLAG -nodefaultlibs SANITIZER_COMMON_LINK_FLAGS) 480append_list_if(COMPILER_RT_HAS_Z_TEXT -Wl,-z,text SANITIZER_COMMON_LINK_FLAGS) 481 482if (COMPILER_RT_USE_BUILTINS_LIBRARY) 483 string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") 484else() 485 if (ANDROID) 486 append_list_if(COMPILER_RT_HAS_GCC_LIB gcc SANITIZER_COMMON_LINK_LIBS) 487 else() 488 append_list_if(COMPILER_RT_HAS_GCC_S_LIB gcc_s SANITIZER_COMMON_LINK_LIBS) 489 endif() 490endif() 491 492append_list_if(COMPILER_RT_HAS_LIBC c SANITIZER_COMMON_LINK_LIBS) 493if("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") 494 list(APPEND SANITIZER_COMMON_LINK_LIBS zircon) 495endif() 496 497if("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") 498 set(SANITIZER_NO_UNDEFINED_SYMBOLS_DEFAULT ON) 499else() 500 set(SANITIZER_NO_UNDEFINED_SYMBOLS_DEFAULT OFF) 501endif() 502option(SANITIZER_NO_UNDEFINED_SYMBOLS "Report error on unresolved symbol references" ${SANITIZER_NO_UNDEFINED_SYMBOLS_DEFAULT}) 503if (SANITIZER_NO_UNDEFINED_SYMBOLS) 504 list(APPEND SANITIZER_COMMON_LINK_FLAGS -Wl,-z,defs) 505endif() 506 507# TODO: COMPILER_RT_COMMON_CFLAGS and COMPILER_RT_COMMON_LINK_FLAGS are 508# intended for use in non-sanitizer runtimes such as libFuzzer, profile or XRay, 509# move these higher to include common flags, then derive SANITIZER_COMMON_CFLAGS 510# and SANITIZER_COMMON_LINK_FLAGS from those and append sanitizer-specific flags. 511set(COMPILER_RT_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS}) 512set(COMPILER_RT_COMMON_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}) 513 514# We don't use the C++ standard library, so avoid including it by mistake. 515append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ SANITIZER_COMMON_CFLAGS) 516append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ SANITIZER_COMMON_LINK_FLAGS) 517 518# Remove -stdlib= which is unused when passing -nostdinc++... 519string(REGEX MATCHALL "-stdlib=[a-zA-Z+]*" stdlib_flag "${CMAKE_CXX_FLAGS}") 520string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 521 522# ...we need it to build some runtimes and tests so readd it where appropriate. 523list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag}) 524list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag}) 525 526# TODO: There's a lot of duplication across lib/*/tests/CMakeLists.txt files, 527# move some of the common flags to COMPILER_RT_UNITTEST_CFLAGS. 528 529# Unittests need access to C++ standard library. 530string(APPEND COMPILER_RT_TEST_COMPILER_CFLAGS " ${stdlib_flag}") 531 532# When cross-compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help in compilation 533# and linking of unittests. 534string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}") 535set(COMPILER_RT_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_CFLAGS}) 536 537if(COMPILER_RT_USE_LLVM_UNWINDER) 538 # We're linking directly against the libunwind that we're building so don't 539 # try to link in the toolchain's default libunwind which may be missing. 540 append_list_if(CXX_SUPPORTS_UNWINDLIB_NONE_FLAG --unwindlib=none COMPILER_RT_COMMON_LINK_FLAGS) 541 append_list_if(CXX_SUPPORTS_UNWINDLIB_NONE_FLAG --unwindlib=none COMPILER_RT_UNITTEST_LINK_FLAGS) 542 if (COMPILER_RT_ENABLE_STATIC_UNWINDER) 543 list(APPEND COMPILER_RT_UNWINDER_LINK_LIBS "$<TARGET_LINKER_FILE:unwind_static>") 544 else() 545 list(APPEND COMPILER_RT_UNWINDER_LINK_LIBS "$<TARGET_LINKER_FILE:$<IF:$<TARGET_EXISTS:unwind_shared>,unwind_shared,unwind_static>>") 546 endif() 547endif() 548 549if (COMPILER_RT_CXX_LIBRARY STREQUAL "libcxx") 550 # We are using the in-tree libc++ so avoid including the default one. 551 append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ COMPILER_RT_COMMON_CFLAGS) 552 append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ COMPILER_RT_COMMON_LINK_FLAGS) 553 # Use the in-tree libc++ through explicit include and library paths. 554 set(COMPILER_RT_CXX_CFLAGS "$<$<TARGET_EXISTS:cxx-headers>:-isystem$<JOIN:$<TARGET_PROPERTY:cxx-headers,INTERFACE_INCLUDE_DIRECTORIES>,$<SEMICOLON>-isystem>>") 555 if (COMPILER_RT_STATIC_CXX_LIBRARY) 556 set(COMPILER_RT_CXX_LINK_LIBS "$<TARGET_LINKER_FILE:cxx_static>") 557 else() 558 set(COMPILER_RT_CXX_LINK_LIBS "$<TARGET_LINKER_FILE:$<IF:$<TARGET_EXISTS:cxx_shared>,cxx_shared,cxx_static>>") 559 endif() 560elseif (COMPILER_RT_CXX_LIBRARY STREQUAL "none") 561 # We aren't using any C++ standard library so avoid including the default one. 562 append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ COMPILER_RT_COMMON_CFLAGS) 563 append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ COMPILER_RT_COMMON_LINK_FLAGS) 564else() 565 # Nothing to be done for `default`. 566endif() 567 568macro(append_libcxx_libs var) 569 if (${var}_INTREE) 570 # TODO: We don't need to add --unwindlib=none to SANITIZER_COMMON_LINK_FLAGS 571 # because we added -nodefaultlibs there earlier, and adding would result in 572 # a warning, but if we switch to -nostdlib++, we would need to add it here. 573 # append_list_if(CXX_SUPPORTS_UNWINDLIB_NONE_FLAG --unwindlib=none SANITIZER_COMMON_LINK_FLAGS) 574 575 if (SANITIZER_USE_STATIC_LLVM_UNWINDER AND (TARGET unwind_static OR HAVE_LIBUNWIND)) 576 list(APPEND ${var}_LIBRARIES unwind_static) 577 elseif (TARGET unwind_shared OR HAVE_LIBUNWIND) 578 list(APPEND ${var}_LIBRARIES unwind_shared) 579 endif() 580 581 if (SANITIZER_USE_STATIC_CXX_ABI AND (TARGET cxxabi_static OR HAVE_LIBCXXABI)) 582 list(APPEND ${var}_LIBRARIES cxxabi_static) 583 elseif (TARGET cxxabi_shared OR HAVE_LIBCXXABI) 584 list(APPEND ${var}_LIBRARIES cxxabi_shared) 585 endif() 586 else() 587 append_list_if(COMPILER_RT_HAS_LIBCXX c++ ${var}_LIBRARIES) 588 endif() 589endmacro() 590 591if (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libc++") 592 append_libcxx_libs(SANITIZER_CXX_ABI) 593elseif (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libcxxabi") 594 list(APPEND SANITIZER_CXX_ABI_LIBRARIES "c++abi") 595elseif (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libstdc++") 596 append_list_if(COMPILER_RT_HAS_LIBSTDCXX stdc++ SANITIZER_CXX_ABI_LIBRARIES) 597endif() 598 599if (SANITIZER_TEST_CXX_LIBNAME STREQUAL "libc++") 600 if (SANITIZER_TEST_CXX_INTREE) 601 list(APPEND SANITIZER_TEST_CXX_CFLAGS "$<$<TARGET_EXISTS:cxx-headers>:-isystem$<JOIN:$<TARGET_PROPERTY:cxx-headers,INTERFACE_INCLUDE_DIRECTORIES>,$<SEMICOLON>-isystem>>") 602 if (SANITIZER_USE_STATIC_TEST_CXX) 603 list(APPEND SANITIZER_TEST_CXX_LIBRARIES "$<TARGET_LINKER_FILE:cxx_static>") 604 else() 605 list(APPEND SANITIZER_TEST_CXX_LIBRARIES "$<TARGET_LINKER_FILE:$<IF:$<TARGET_EXISTS:cxx_shared>,cxx_shared,cxx_static>>") 606 endif() 607 # We are using the in tree libc++ so avoid including the default one. 608 append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ COMPILER_RT_UNITTEST_CFLAGS) 609 append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ COMPILER_RT_UNITTEST_LINK_FLAGS) 610 else() 611 append_list_if(COMPILER_RT_HAS_LIBCXX -lc++ SANITIZER_TEST_CXX_LIBRARIES) 612 endif() 613elseif (SANITIZER_TEST_CXX_LIBNAME STREQUAL "libstdc++") 614 append_list_if(COMPILER_RT_HAS_LIBSTDCXX -lstdc++ SANITIZER_TEST_CXX_LIBRARIES) 615endif() 616 617# Unittests support. 618set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest) 619set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc) 620set(COMPILER_RT_GTEST_CFLAGS 621 -DGTEST_NO_LLVM_SUPPORT=1 622 -DGTEST_HAS_RTTI=0 623 -I${COMPILER_RT_GTEST_PATH}/include 624 -I${COMPILER_RT_GTEST_PATH} 625) 626 627# Mocking support. 628set(COMPILER_RT_GMOCK_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock) 629set(COMPILER_RT_GMOCK_SOURCE ${COMPILER_RT_GMOCK_PATH}/src/gmock-all.cc) 630set(COMPILER_RT_GMOCK_CFLAGS 631 -DGTEST_NO_LLVM_SUPPORT=1 632 -DGTEST_HAS_RTTI=0 633 -I${COMPILER_RT_GMOCK_PATH}/include 634 -I${COMPILER_RT_GMOCK_PATH} 635) 636 637if(COMPILER_RT_HAS_G_FLAG) 638 list(APPEND COMPILER_RT_UNITTEST_CFLAGS -g) 639endif() 640append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS) 641append_list_if(COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG -Wno-covered-switch-default COMPILER_RT_UNITTEST_CFLAGS) 642append_list_if(COMPILER_RT_HAS_WSUGGEST_OVERRIDE_FLAG -Wno-suggest-override COMPILER_RT_UNITTEST_CFLAGS) 643 644if(MSVC) 645 # gtest use a lot of stuff marked as deprecated on Windows. 646 list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations) 647endif() 648 649# Warnings to turn off for all libraries, not just sanitizers. 650append_string_if(COMPILER_RT_HAS_WUNUSED_PARAMETER_FLAG -Wno-unused-parameter CMAKE_C_FLAGS CMAKE_CXX_FLAGS) 651 652if (CMAKE_LINKER MATCHES "link.exe$") 653 # Silence MSVC linker warnings caused by empty object files. The 654 # sanitizer libraries intentionally use ifdefs that result in empty 655 # files, rather than skipping these files in the build system. 656 # Ideally, we would pass this flag only for the libraries that need 657 # it, but CMake doesn't seem to have a way to set linker flags for 658 # individual static libraries, so we enable the suppression flag for 659 # the whole compiler-rt project. 660 set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221") 661endif() 662 663add_subdirectory(include) 664 665option(COMPILER_RT_USE_LIBCXX 666 "Enable compiler-rt to use libc++ from the source tree" ON) 667if(COMPILER_RT_USE_LIBCXX) 668 if(LLVM_ENABLE_PROJECTS_USED) 669 # Don't use libcxx if LLVM_ENABLE_PROJECTS does not enable it. 670 set(COMPILER_RT_LIBCXX_PATH ${LLVM_EXTERNAL_LIBCXX_SOURCE_DIR}) 671 set(COMPILER_RT_LIBCXXABI_PATH ${LLVM_EXTERNAL_LIBCXXABI_SOURCE_DIR}) 672 else() 673 foreach(path IN ITEMS ${LLVM_MAIN_SRC_DIR}/projects/libcxx 674 ${LLVM_MAIN_SRC_DIR}/runtimes/libcxx 675 ${LLVM_MAIN_SRC_DIR}/../libcxx 676 ${LLVM_EXTERNAL_LIBCXX_SOURCE_DIR}) 677 if(IS_DIRECTORY ${path}) 678 set(COMPILER_RT_LIBCXX_PATH ${path}) 679 break() 680 endif() 681 endforeach() 682 foreach(path IN ITEMS ${LLVM_MAIN_SRC_DIR}/projects/libcxxabi 683 ${LLVM_MAIN_SRC_DIR}/runtimes/libcxxabi 684 ${LLVM_MAIN_SRC_DIR}/../libcxxabi 685 ${LLVM_EXTERNAL_LIBCXXABI_SOURCE_DIR}) 686 if(IS_DIRECTORY ${path}) 687 set(COMPILER_RT_LIBCXXABI_PATH ${path}) 688 break() 689 endif() 690 endforeach() 691 endif() 692endif() 693 694set(COMPILER_RT_LLD_PATH ${LLVM_MAIN_SRC_DIR}/tools/lld) 695if(EXISTS ${COMPILER_RT_LLD_PATH}/ AND LLVM_TOOL_LLD_BUILD) 696 set(COMPILER_RT_HAS_LLD TRUE) 697else() 698 set(COMPILER_RT_LLD_PATH ${LLVM_MAIN_SRC_DIR}/../lld) 699 if(EXISTS ${COMPILER_RT_LLD_PATH}/ AND LLVM_TOOL_LLD_BUILD) 700 set(COMPILER_RT_HAS_LLD TRUE) 701 endif() 702endif() 703 704if(ANDROID) 705 set(COMPILER_RT_HAS_LLD TRUE) 706 set(COMPILER_RT_TEST_USE_LLD TRUE) 707 append_list_if(COMPILER_RT_HAS_FUSE_LD_LLD_FLAG -fuse-ld=lld SANITIZER_COMMON_LINK_FLAGS) 708 append_list_if(COMPILER_RT_HAS_LLD -fuse-ld=lld COMPILER_RT_UNITTEST_LINK_FLAGS) 709endif() 710pythonize_bool(COMPILER_RT_HAS_LLD) 711pythonize_bool(COMPILER_RT_TEST_USE_LLD) 712 713add_subdirectory(lib) 714 715if(COMPILER_RT_INCLUDE_TESTS) 716 add_subdirectory(unittests) 717 add_subdirectory(test) 718 # Don't build llvm-lit for runtimes-build, it will clean up map_config. 719 if (COMPILER_RT_STANDALONE_BUILD AND NOT LLVM_RUNTIMES_BUILD) 720 # If we have a valid source tree, generate llvm-lit into the bin directory. 721 # The user can still choose to have the check targets *use* a different lit 722 # by specifying -DLLVM_EXTERNAL_LIT, but we generate it regardless. 723 if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/llvm-lit) 724 # Needed for lit support in standalone builds. 725 include(AddLLVM) 726 add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit ${CMAKE_CURRENT_BINARY_DIR}/llvm-lit) 727 elseif(NOT EXISTS ${LLVM_EXTERNAL_LIT}) 728 message(WARNING "Could not find LLVM source directory and LLVM_EXTERNAL_LIT does not" 729 "point to a valid file. You will not be able to run tests.") 730 endif() 731 endif() 732endif() 733 734add_subdirectory(tools) 735