Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -276,66 +276,6 @@ append_list_if(COMPILER_RT_HAS_WD4391_FLAG /wd4391 SANITIZER_COMMON_CFLAGS) append_list_if(COMPILER_RT_HAS_WD4722_FLAG /wd4722 SANITIZER_COMMON_CFLAGS) append_list_if(COMPILER_RT_HAS_WD4800_FLAG /wd4800 SANITIZER_COMMON_CFLAGS) -if(APPLE) - macro(find_darwin_sdk_dir var sdk_name) - # Let's first try the internal SDK, otherwise use the public SDK. - execute_process( - COMMAND xcodebuild -version -sdk ${sdk_name}.internal Path - OUTPUT_VARIABLE ${var} - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_FILE /dev/null - ) - if(${var} STREQUAL "") - execute_process( - COMMAND xcodebuild -version -sdk ${sdk_name} Path - OUTPUT_VARIABLE ${var} - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_FILE /dev/null - ) - endif() - endmacro() - - find_darwin_sdk_dir(OSX_SDK_DIR macosx) - find_darwin_sdk_dir(IOSSIM_SDK_DIR iphonesimulator) - - set(SANITIZER_COMMON_SUPPORTED_OS osx) - if(NOT SANITIZER_MIN_OSX_VERSION) - string(REGEX MATCH "-mmacosx-version-min=([.0-9]+)" - MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}") - if(MACOSX_VERSION_MIN_FLAG) - set(SANITIZER_MIN_OSX_VERSION "${CMAKE_MATCH_1}") - elseif(CMAKE_OSX_DEPLOYMENT_TARGET) - set(SANITIZER_MIN_OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET}) - else() - set(SANITIZER_MIN_OSX_VERSION 10.9) - if(IOSSIM_SDK_DIR) - list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim) - endif() - endif() - endif() - if(SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.7") - message(FATAL_ERROR "Too old OS X version: ${SANITIZER_MIN_OSX_VERSION}") - endif() - - set(CMAKE_OSX_DEPLOYMENT_TARGET "") # We evaluate target OS X version above. - set(DARWIN_osx_CFLAGS -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION} - -stdlib=libc++) - set(DARWIN_iossim_CFLAGS - -stdlib=libc++ - -mios-simulator-version-min=7.0 -isysroot ${IOSSIM_SDK_DIR}) - set(DARWIN_osx_LINKFLAGS -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION} - -stdlib=libc++ -lc++ -lc++abi) - set(DARWIN_iossim_LINKFLAGS - -stdlib=libc++ -lc++ -lc++abi - -Wl,-ios_simulator_version_min,7.0.0 - -mios-simulator-version-min=7.0 - -isysroot ${IOSSIM_SDK_DIR}) - - if(OSX_SDK_DIR) - list(APPEND DARWIN_osx_CFLAGS -isysroot ${OSX_SDK_DIR}) - list(APPEND DARWIN_osx_LINKFLAGS -isysroot ${OSX_SDK_DIR}) - endif() -endif() if(APPLE AND SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.9") # Mac OS X prior to 10.9 had problems with exporting symbols from Index: cmake/Modules/AddCompilerRT.cmake =================================================================== --- cmake/Modules/AddCompilerRT.cmake +++ cmake/Modules/AddCompilerRT.cmake @@ -19,6 +19,7 @@ set(libname "${name}.${os}") set(libnames ${libnames} ${libname}) set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS}) + list_union(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) endforeach() else() foreach(arch ${LIB_ARCHS}) @@ -39,7 +40,8 @@ set_property(TARGET ${libname} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) if(APPLE) - set_target_properties(${libname} PROPERTIES OSX_ARCHITECTURES "${LIB_ARCHS}") + set_target_properties(${libname} PROPERTIES + OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") endif() endforeach() endfunction() @@ -118,8 +120,9 @@ set_target_link_flags(${name} ${LIB_LINKFLAGS} ${DARWIN_${os}_LINKFLAGS}) set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) + list_union(filtered_arches DARWIN_${os}_ARCHS LIB_ARCHS) set_target_properties(${name} PROPERTIES - OSX_ARCHITECTURES "${LIB_ARCHS}" + OSX_ARCHITECTURES "${filtered_arches}" LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) install(TARGETS ${name} LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) Index: cmake/Modules/CompilerRTDarwinUtils.cmake =================================================================== --- /dev/null +++ cmake/Modules/CompilerRTDarwinUtils.cmake @@ -0,0 +1,79 @@ +# On OS X SDKs can be installed anywhere on the base system and xcode-select can +# set the default Xcode to use. This function finds the SDKs that are present in +# the current Xcode. +function(find_darwin_sdk_dir var sdk_name) + # Let's first try the internal SDK, otherwise use the public SDK. + execute_process( + COMMAND xcodebuild -version -sdk ${sdk_name}.internal Path + OUTPUT_VARIABLE var_internal + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_FILE /dev/null + ) + if("" STREQUAL "${var_internal}") + execute_process( + COMMAND xcodebuild -version -sdk ${sdk_name} Path + OUTPUT_VARIABLE var_internal + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_FILE /dev/null + ) + endif() + set(${var} ${var_internal} PARENT_SCOPE) +endfunction() + +# There isn't a clear mapping of what architectures are supported with a given +# target platform, but ld's version output does list the architectures it can +# link for. +function(darwin_get_toolchain_supported_archs output_var) + execute_process( + COMMAND ld -v + ERROR_VARIABLE LINKER_VERSION) + + string(REGEX MATCH "configured to support archs: ([^\n]+)" + ARCHES_MATCHED "${LINKER_VERSION}") + if(ARCHES_MATCHED) + set(ARCHES "${CMAKE_MATCH_1}") + message("Matched ARCHES: ${ARCHES}") + string(REPLACE " " ";" ARCHES ${ARCHES}) + else() + # If auto-detecting fails, fall back to a default set + message(WARNING "Detecting supported architectures from 'ld -v' failed. Returning default set.") + set(ARCHES "i386;x86_64;armv7;armv7s;arm64") + endif() + + set(${output_var} ${ARCHES} PARENT_SCOPE) +endfunction() + +# This function takes an OS and a list of architectures and identifies the +# subset of the architectures list that the installed toolchain can target. +function(darwin_test_archs os valid_archs) + set(archs ${ARGN}) + message(STATUS "Finding valid architectures for ${os}...") + set(SIMPLE_CPP ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.cpp) + file(WRITE ${SIMPLE_CPP} "#include \nint main() { return 0; }\n") + + set(os_linker_flags) + foreach(flag ${DARWIN_${os}_LINKFLAGS}) + set(os_linker_flags "${os_linker_flags} ${flag}") + endforeach() + + # The simple program will build for x86_64h on the simulator because it is + # compatible with x86_64 libraries (mostly), but since x86_64h isn't actually + # a valid or useful architecture for the iOS simulator we should drop it. + if(${os} STREQUAL "iossim") + list(REMOVE_ITEM archs "x86_64h") + endif() + + set(working_archs) + foreach(arch ${archs}) + + set(arch_linker_flags "-arch ${arch} ${os_linker_flags}") + try_compile(CAN_TARGET_${os}_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_CPP} + COMPILE_DEFINITIONS "-v -arch ${arch}" ${DARWIN_${os}_CFLAGS} + CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${arch_linker_flags}" + OUTPUT_VARIABLE TEST_OUTPUT) + if(${CAN_TARGET_${os}_${arch}}) + list(APPEND working_archs ${arch}) + endif() + endforeach() + set(${valid_archs} ${working_archs} PARENT_SCOPE) +endfunction() Index: cmake/Modules/CompilerRTUtils.cmake =================================================================== --- cmake/Modules/CompilerRTUtils.cmake +++ cmake/Modules/CompilerRTUtils.cmake @@ -57,3 +57,13 @@ endif() list(APPEND ${list} "${varname}=${${varname}}") endmacro() + +macro(list_union output input1 input2) + set(${output}) + foreach(it ${${input1}}) + list(FIND ${input2} ${it} index) + if( NOT (index EQUAL -1)) + list(APPEND ${output} ${it}) + endif() + endforeach() +endmacro() Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -173,7 +173,7 @@ # Examine compiler output instead. detect_target_arch() set(COMPILER_RT_OS_SUFFIX "-android") -else() +elseif(NOT APPLE) # Supported archs for Apple platforms are generated later if("${LLVM_NATIVE_ARCH}" STREQUAL "X86") if(NOT MSVC) test_target_arch(x86_64 "" "-m64") @@ -220,8 +220,6 @@ set(COMPILER_RT_OS_SUFFIX "") endif() -message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}") - # Takes ${ARGN} and puts only supported architectures in @out_var list. function(filter_available_targets out_var) set(archs ${${out_var}}) @@ -244,26 +242,190 @@ endif() endfunction() -# Architectures supported by compiler-rt libraries. -filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH - x86_64 i386 i686 powerpc64 powerpc64le arm aarch64 mips mips64 mipsel mips64el) -# LSan and UBSan common files should be available on all architectures supported -# by other sanitizers (even if they build into dummy object files). -filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH - ${SANITIZER_COMMON_SUPPORTED_ARCH}) -filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH - ${SANITIZER_COMMON_SUPPORTED_ARCH}) -filter_available_targets(ASAN_SUPPORTED_ARCH - x86_64 i386 i686 powerpc64 powerpc64le arm mips mipsel mips64 mips64el aarch64) -filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64 mips64 mips64el aarch64) -filter_available_targets(LSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) -filter_available_targets(MSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) -filter_available_targets(PROFILE_SUPPORTED_ARCH x86_64 i386 i686 arm mips mips64 - mipsel mips64el aarch64 powerpc64 powerpc64le) -filter_available_targets(TSAN_SUPPORTED_ARCH x86_64 mips64 mips64el) -filter_available_targets(UBSAN_SUPPORTED_ARCH x86_64 i386 i686 arm aarch64 mips - mipsel mips64 mips64el powerpc64 powerpc64le) -filter_available_targets(SAFESTACK_SUPPORTED_ARCH x86_64 i386 i686) +set(ARM64 aarch64) +set(ARM32 arm) +set(X86_64 x86_64) +if(APPLE) + set(ARM64 arm64) + set(ARM32 armv7 armv7s) + set(X86_64 x86_64 x86_64h) +endif() + +set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86_64} i386 i686 powerpc64 + powerpc64le ${ARM32} ${ARM64} mips mips64 mipsel mips64el) +set(ALL_ASAN_SUPPORTED_ARCH ${X86_64} i386 i686 powerpc64 powerpc64le ${ARM32} + ${ARM64} mips mipsel mips64 mips64el) +set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el ${ARM64}) +set(ALL_LSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el) +set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el) +set(ALL_PROFILE_SUPPORTED_ARCH ${X86_64} i386 i686 ${ARM32} mips mips64 + mipsel mips64el ${ARM64} powerpc64 powerpc64le) +set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el) +set(ALL_UBSAN_SUPPORTED_ARCH ${X86_64} i386 i686 ${ARM32} ${ARM64} mips + mipsel mips64 mips64el powerpc64 powerpc64le) +set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86_64} i386 i686) + +if(APPLE) + include(CompilerRTDarwinUtils) + + option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off) + + find_darwin_sdk_dir(OSX_SDK_DIR macosx) + find_darwin_sdk_dir(IOSSIM_SDK_DIR iphonesimulator) + find_darwin_sdk_dir(IOS_SDK_DIR iphoneos) + + # Note: In order to target x86_64h on OS X the minimum deployment target must + # be 10.8 or higher. + set(SANITIZER_COMMON_SUPPORTED_OS osx) + if(NOT SANITIZER_MIN_OSX_VERSION) + string(REGEX MATCH "-mmacosx-version-min=([.0-9]+)" + MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}") + if(MACOSX_VERSION_MIN_FLAG) + set(SANITIZER_MIN_OSX_VERSION "${CMAKE_MATCH_1}") + elseif(CMAKE_OSX_DEPLOYMENT_TARGET) + set(SANITIZER_MIN_OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET}) + else() + set(SANITIZER_MIN_OSX_VERSION 10.9) + endif() + if(SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.7") + message(FATAL_ERROR "Too old OS X version: ${SANITIZER_MIN_OSX_VERSION}") + endif() + endif() + + # We're setting the flag manually for each target OS + set(CMAKE_OSX_DEPLOYMENT_TARGET "") + + set(DARWIN_COMMON_CFLAGS -stdlib=libc++) + set(DARWIN_COMMON_LINKFLAGS + -stdlib=libc++ + -lc++ + -lc++abi) + + set(DARWIN_osx_CFLAGS + ${DARWIN_COMMON_CFLAGS} + -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}) + set(DARWIN_osx_LINKFLAGS + ${DARWIN_COMMON_LINKFLAGS} + -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}) + + if(OSX_SDK_DIR) + list(APPEND DARWIN_osx_CFLAGS -isysroot ${OSX_SDK_DIR}) + list(APPEND DARWIN_osx_LINKFLAGS -isysroot ${OSX_SDK_DIR}) + endif() + + # Figure out which arches to use for each OS + darwin_get_toolchain_supported_archs(toolchain_arches) + message(STATUS "Toolchain supported arches: ${toolchain_arches}") + + if(NOT MACOSX_VERSION_MIN_FLAG) + darwin_test_archs(osx + DARWIN_osx_ARCHS + ${toolchain_arches}) + message(STATUS "OSX supported arches: ${DARWIN_osx_ARCHS}") + foreach(arch ${DARWIN_osx_ARCHS}) + list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) + set(CAN_TARGET_${arch} 1) + endforeach() + + if(IOSSIM_SDK_DIR) + set(DARWIN_iossim_CFLAGS + ${DARWIN_COMMON_CFLAGS} + -mios-simulator-version-min=7.0 + -isysroot ${IOSSIM_SDK_DIR}) + set(DARWIN_iossim_LINKFLAGS + ${DARWIN_COMMON_LINKFLAGS} + -mios-simulator-version-min=7.0 + -isysroot ${IOSSIM_SDK_DIR}) + + list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim) + darwin_test_archs(iossim + DARWIN_iossim_ARCHS + ${toolchain_arches}) + message(STATUS "iOS Simulator supported arches: ${DARWIN_iossim_ARCHS}") + foreach(arch ${DARWIN_iossim_ARCHS}) + list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) + set(CAN_TARGET_${arch} 1) + endforeach() + endif() + + if(IOS_SDK_DIR AND COMPILER_RT_ENABLE_IOS) + set(DARWIN_ios_CFLAGS + ${DARWIN_COMMON_CFLAGS} + -miphoneos-version-min=7.0 + -isysroot ${IOS_SDK_DIR}) + set(DARWIN_ios_LINKFLAGS + ${DARWIN_COMMON_LINKFLAGS} + -miphoneos-version-min=7.0 + -isysroot ${IOS_SDK_DIR}) + + list(APPEND SANITIZER_COMMON_SUPPORTED_OS ios) + darwin_test_archs(ios + DARWIN_ios_ARCHS + ${toolchain_arches}) + message(STATUS "iOS supported arches: ${DARWIN_ios_ARCHS}") + foreach(arch ${DARWIN_ios_ARCHS}) + list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) + set(CAN_TARGET_${arch} 1) + endforeach() + endif() + endif() + + # for list_union + include(CompilerRTUtils) + + list_union(SANITIZER_COMMON_SUPPORTED_ARCH + ALL_SANITIZER_COMMON_SUPPORTED_ARCH + COMPILER_RT_SUPPORTED_ARCH + ) + set(LSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}) + set(UBSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}) + list_union(ASAN_SUPPORTED_ARCH + ALL_ASAN_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) + list_union(DFSAN_SUPPORTED_ARCH + ALL_DFSAN_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) + list_union(LSAN_SUPPORTED_ARCH + ALL_LSAN_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) + list_union(MSAN_SUPPORTED_ARCH + ALL_MSAN_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) + # Note: profiles is only built for OS X + list_union(PROFILE_SUPPORTED_ARCH + ALL_PROFILE_SUPPORTED_ARCH + DARWIN_osx_ARCHS) + list_union(TSAN_SUPPORTED_ARCH + ALL_TSAN_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) + list_union(UBSAN_SUPPORTED_ARCH + ALL_UBSAN_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) + list_union(SAFESTACK_SUPPORTED_ARCH + ALL_SAFESTACK_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) +else() + # Architectures supported by compiler-rt libraries. + filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH + ${ALL_SANITIZER_COMMON_SUPPORTED_ARCH}) + # LSan and UBSan common files should be available on all architectures + # supported by other sanitizers (even if they build into dummy object files). + filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH + ${SANITIZER_COMMON_SUPPORTED_ARCH}) + filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH + ${SANITIZER_COMMON_SUPPORTED_ARCH}) + filter_available_targets(ASAN_SUPPORTED_ARCH ${ALL_ASAN_SUPPORTED_ARCH}) + filter_available_targets(DFSAN_SUPPORTED_ARCH ${ALL_DFSAN_SUPPORTED_ARCH}) + filter_available_targets(LSAN_SUPPORTED_ARCH ${ALL_LSAN_SUPPORTED_ARCH}) + filter_available_targets(MSAN_SUPPORTED_ARCH ${ALL_MSAN_SUPPORTED_ARCH}) + filter_available_targets(PROFILE_SUPPORTED_ARCH ${ALL_PROFILE_SUPPORTED_ARCH}) + filter_available_targets(TSAN_SUPPORTED_ARCH ${ALL_TSAN_SUPPORTED_ARCH}) + filter_available_targets(UBSAN_SUPPORTED_ARCH ${ALL_UBSAN_SUPPORTED_ARCH}) + filter_available_targets(SAFESTACK_SUPPORTED_ARCH + ${ALL_SAFESTACK_SUPPORTED_ARCH}) +endif() + +message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}") if(ANDROID) set(OS_NAME "Android")