Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -112,9 +112,6 @@ # COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in. pythonize_bool(COMPILER_RT_DEBUG) -include(HandleCompilerRT) -include(config-ix) - if(APPLE AND SANITIZER_MIN_OSX_VERSION AND SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.9") # Mac OS X prior to 10.9 had problems with exporting symbols from # libc++/libc++abi. @@ -123,7 +120,7 @@ set(cxxabi_supported ON) endif() -option(SANITIZER_ALLOW_CXXABI "Allow use of C++ ABI details in ubsan" ON) +option(SANITIZER_ALLOW_CXXABI "Allow use of C++ ABI details in sanitizers" ON) set(SANITIZE_CAN_USE_CXXABI OFF) if (cxxabi_supported AND SANITIZER_ALLOW_CXXABI) @@ -131,48 +128,51 @@ endif() pythonize_bool(SANITIZER_CAN_USE_CXXABI) +check_link_libraries(cxx_link_libraries) + set(SANITIZER_CXX_ABI "default" CACHE STRING "Specify C++ ABI library to use.") -set(CXXABIS none default libcxxabi libstdc++ libc++) +set(CXXABIS none default libc++ libstdc++) set_property(CACHE SANITIZER_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) if (SANITIZER_CXX_ABI STREQUAL "default") - if (HAVE_LIBCXXABI AND COMPILER_RT_DEFAULT_TARGET_ONLY) - set(SANITIZER_CXX_ABI_LIBNAME "libcxxabi") - set(SANITIZER_CXX_ABI_INTREE 1) - elseif (APPLE) - set(SANITIZER_CXX_ABI_LIBNAME "libcxxabi") + if(APPLE) + set(SANITIZER_CXX_ABI_LIBNAME "libc++") set(SANITIZER_CXX_ABI_SYSTEM 1) - else() + elseif("stdc++" IN_LIST cxx_link_libraries) set(SANITIZER_CXX_ABI_LIBNAME "libstdc++") set(SANITIZER_CXX_ABI_SYSTEM 1) + elseif("c++" IN_LIST cxx_link_libraries) + set(SANITIZER_CXX_ABI_LIBNAME "libc++") endif() else() set(SANITIZER_CXX_ABI_LIBNAME "${SANITIZER_CXX_ABI}") endif() -if (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libcxxabi") - if (SANITIZER_CXX_ABI_INTREE) - if (NOT LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_shared OR HAVE_LIBUNWIND)) - list(APPEND SANITIZER_CXX_ABI_LIBRARY unwind_shared) - elseif (LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_static OR HAVE_LIBUNWIND)) - list(APPEND SANITIZER_CXX_ABI_LIBRARY unwind_static) - endif() - if (NOT LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND (TARGET cxxabi_shared OR HAVE_LIBCXXABI)) +if (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libc++") + if(SANITIZER_CXX_ABI_SYSTEM) + list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++") + else() + if(TARGET cxxabi_shared OR (HAVE_LIBCXXABI AND NOT LIBCXX_ENABLE_STATIC_ABI_LIBRARY)) list(APPEND SANITIZER_CXX_ABI_LIBRARY cxxabi_shared) - elseif (LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND (TARGET cxxabi_static OR HAVE_LIBCXXABI)) + elseif(TARGET cxxabi_shared OR (HAVE_LIBCXXABI AND LIBCXX_ENABLE_STATIC_ABI_LIBRARY)) list(APPEND SANITIZER_CXX_ABI_LIBRARY cxxabi_static) + else() + list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++") endif() - else() - list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++abi") endif() -elseif (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libc++") - list(APPEND SANITIZER_CXX_ABI_LIBRARY "c++") elseif (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libstdc++") - append_list_if(COMPILER_RT_HAS_LIBSTDCXX stdc++ SANITIZER_CXX_ABI_LIBRARY) + list(APPEND SANITIZER_CXX_ABI_LIBRARY "stdc++") endif() -option(SANITIZER_USE_COMPILER_RT "Use compiler-rt builtins instead of libgcc" OFF) +check_runtime_library(runtime_library) +if(runtime_library MATCHES ".*libgcc.*") + set(COMPILER_RT_RUNTIME_LIBRARY "libgcc") +elseif(runtime_library MATCHES ".*libclang_rt.builtins.*") + set(COMPILER_RT_RUNTIME_LIBRARY "compiler-rt") +endif() + +include(config-ix) #================================ # Setup Compiler Flags @@ -320,9 +320,7 @@ # Set common link flags. append_list_if(COMPILER_RT_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs SANITIZER_COMMON_LINK_FLAGS) -if (SANITIZER_USE_COMPILER_RT) - list(APPEND SANITIZER_COMMON_LINK_FLAGS -rtlib=compiler-rt) - find_compiler_rt_library(builtins COMPILER_RT_BUILTINS_LIBRARY) +if (COMPILER_RT_RUNTIME_LIBRARY STREQUAL "compiler-rt") list(APPEND SANITIZER_COMMON_LINK_LIBS ${COMPILER_RT_BUILTINS_LIBRARY}) else() if (ANDROID) Index: cmake/Modules/CompilerRTUtils.cmake =================================================================== --- cmake/Modules/CompilerRTUtils.cmake +++ cmake/Modules/CompilerRTUtils.cmake @@ -318,3 +318,58 @@ endforeach () set(${output_var} ${intermediate} PARENT_SCOPE) endfunction() + +function(check_runtime_library variable) + set(COMPILER_COMMAND ${CMAKE_CXX_COMPILER} ${SANITIZER_COMMON_CFLAGS} + "--print-libgcc-file-name") + if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) + list(APPEND COMPILER_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}") + endif() + execute_process( + COMMAND ${COMPILER_COMMAND} + RESULT_VARIABLE COMMAND_RESULT + OUTPUT_VARIABLE LIBRARY_FILE + ) + string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE) + if(COMMAND_RESULT EQUAL 0) + set(${variable} "${LIBRARY_FILE}" PARENT_SCOPE) + endif() +endfunction() + +function(check_link_libraries variable) + set(COMPILER_COMMAND "${CMAKE_CXX_COMPILER}" "${SANITIZER_COMMON_CFLAGS}" + "${CMAKE_ROOT}/Modules/DummyCXXFile.cxx" "-###") + if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) + list(APPEND COMPILER_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}") + endif() + execute_process( + COMMAND ${COMPILER_COMMAND} + RESULT_VARIABLE COMMAND_RESULT + ERROR_VARIABLE COMMAND_OUTPUT + ) + if(COMMAND_RESULT EQUAL 0) + get_filename_component(linker ${CMAKE_LINKER} NAME) + string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" linker "${linker}") + set(LINKER_REGEX "^( *|.*[/\\])(${linker}|([^/\\]+-)?ld|collect2)[^/\\]*( |$)") + set(EXCLUDE_REGEX "collect2 version |^[A-Za-z0-9_]+=") + string(REGEX REPLACE "\r?\n" ";" output_lines "${COMMAND_OUTPUT}") + foreach(line IN LISTS output_lines) + if(line MATCHES "${LINKER_REGEX}" AND NOT line MATCHES "${EXCLUDE_REGEX}") + separate_arguments(args NATIVE_COMMAND "${line}") + list(GET args 0 cmd) + endif() + if("${cmd}" MATCHES "${LINKER_REGEX}") + foreach(arg IN LISTS args) + if("${arg}" MATCHES "^-l([^:].*)$") + set(lib "${CMAKE_MATCH_1}") + list(APPEND libs ${lib}) + elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.a$") + list(APPEND libs ${arg}) + endif() + endforeach() + break() + endif() + endforeach() + set(${variable} "${libs}" PARENT_SCOPE) + endif() +endfunction() Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -13,7 +13,10 @@ endfunction() check_library_exists(c fopen "" COMPILER_RT_HAS_LIBC) -if (NOT SANITIZER_USE_COMPILER_RT) +if (COMPILER_RT_RUNTIME_LIBRARY STREQUAL "compiler-rt") + include(HandleCompilerRT) + find_compiler_rt_library(builtins COMPILER_RT_BUILTINS_LIBRARY) +else() if (ANDROID) check_library_exists(gcc __gcc_personality_v0 "" COMPILER_RT_HAS_GCC_LIB) else() @@ -27,9 +30,7 @@ if (COMPILER_RT_HAS_LIBC) list(APPEND CMAKE_REQUIRED_LIBRARIES c) endif () - if (SANITIZER_USE_COMPILER_RT) - list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt) - find_compiler_rt_library(builtins COMPILER_RT_BUILTINS_LIBRARY) + if (COMPILER_RT_RUNTIME_LIBRARY STREQUAL "compiler-rt") list(APPEND CMAKE_REQUIRED_LIBRARIES "${COMPILER_RT_BUILTINS_LIBRARY}") elseif (COMPILER_RT_HAS_GCC_S_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s)