Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -271,27 +271,18 @@ 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() + 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) + darwin_get_toolchain_supported_archs(toolchain_arches) + + # 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) string(REGEX MATCH "-mmacosx-version-min=([.0-9]+)" MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}") @@ -302,29 +293,73 @@ endif() else() set(SANITIZER_MIN_OSX_VERSION 10.7) - if(IOSSIM_SDK_DIR) - list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim) - endif() endif() - set(CMAKE_OSX_DEPLOYMENT_TARGET "") # We're setting the flag manually below. - 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_COMMON_CFLAGS -stdlib=libc++) + set(DARWIN_COMMON_LINKFLAGS + ${DARWIN_COMMON_CFLAGS} + -lc++ + -lc++abi) + + set(DARWIN_osx_CFLAGS + ${DARWIN_COMMON_CFLAGS} + -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}) set(DARWIN_osx_LINKFLAGS -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION} - -stdlib=libc++ -lc++ -lc++abi) + ${DARWIN_COMMON_LINKFLAGS}) + + set(DARWIN_iossim_CFLAGS + ${DARWIN_COMMON_CFLAGS} + -mios-simulator-version-min=7.0 + -isysroot ${IOSSIM_SDK_DIR}) set(DARWIN_iossim_LINKFLAGS - -stdlib=libc++ -lc++ -lc++abi + ${DARWIN_COMMON_LINKFLAGS} -Wl,-ios_simulator_version_min,7.0.0 -mios-simulator-version-min=7.0 -isysroot ${IOSSIM_SDK_DIR}) + set(DARWIN_ios_CFLAGS + ${DARWIN_COMMON_CFLAGS} + -miphoneos-version-min=7.0 + -isysroot ${IOS_SDK_DIR}) + set(DARWIN_ios_LINKFLAGS + ${DARWIN_COMMON_LINKFLAGS} + -Wl,-ios_version_min,7.0.0 + -miphoneos-version-min=7.0 + -isysroot ${IOS_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() + + message(STATUS "Toolchain supported arches: ${toolchain_arches}") + + # these tests have to happen after the flag variables are setup + if(NOT MACOSX_VERSION_MIN_FLAG) + darwin_test_archs(osx + SANITIZER_COMMON_DARWIN_osx_ARCHES + ${toolchain_arches}) + message(STATUS "OSX supported arches: ${SANITIZER_COMMON_DARWIN_osx_ARCHES}") + + if(IOSSIM_SDK_DIR) + list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim) + darwin_test_archs(iossim + SANITIZER_COMMON_DARWIN_iossim_ARCHES + ${toolchain_arches}) + message(STATUS "iOS Simulator supported arches: ${SANITIZER_COMMON_DARWIN_iossim_ARCHES}") + endif() + + if(IOS_SDK_DIR AND COMPILER_RT_ENABLE_IOS) + list(APPEND SANITIZER_COMMON_SUPPORTED_OS ios) + darwin_test_archs(ios + SANITIZER_COMMON_DARWIN_ios_ARCHES + ${toolchain_arches}) + message(STATUS "iOS supported arches: ${SANITIZER_COMMON_DARWIN_ios_ARCHES}") + endif() + endif() + + set(CMAKE_OSX_DEPLOYMENT_TARGET "") # We're setting the flag manually below. + endif() add_subdirectory(include) Index: cmake/Modules/AddCompilerRT.cmake =================================================================== --- cmake/Modules/AddCompilerRT.cmake +++ cmake/Modules/AddCompilerRT.cmake @@ -19,6 +19,8 @@ set(libname "${name}.${os}") set(libnames ${libnames} ${libname}) set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS}) + set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS}) + set(LIB_ARCHS_${libname} ${SANITIZER_COMMON_DARWIN_${os}_ARCHES}) endforeach() else() foreach(arch ${LIB_ARCHS}) @@ -39,7 +41,9 @@ 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}}" + LINK_FLAGS "${extra_linkflags_${libname}}") endif() endforeach() endfunction() Index: cmake/Modules/CompilerRTDarwinUtils.cmake =================================================================== --- /dev/null +++ cmake/Modules/CompilerRTDarwinUtils.cmake @@ -0,0 +1,74 @@ +# 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(FIND ${LINKER_VERSION} "configured to support archs:" LINE_START) + string(SUBSTRING ${LINKER_VERSION} ${LINE_START} -1 ARCHES_LINE) + string(SUBSTRING ${ARCHES_LINE} 28 -1 ARCHES_LINE) + string(FIND ${ARCHES_LINE} "\n" LINE_END) + string(SUBSTRING ${ARCHES_LINE} 0 ${LINE_END} ARCHES_LINE) + string(STRIP ${ARCHES_LINE} ARCHES_LINE) + string(REPLACE " " ";" ARCHES ${ARCHES_LINE}) + + 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). + if(${os} STREQUAL "iossim") + list(REMOVE_ITEM archs "x86_64h") + endif() + + set(WORKING_ARCHES) + 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_ARCHES ${arch}) + endif() + endforeach() + set(${valid_archs} ${WORKING_ARCHES} PARENT_SCOPE) +endfunction() \ No newline at end of file Index: lib/asan/CMakeLists.txt =================================================================== --- lib/asan/CMakeLists.txt +++ lib/asan/CMakeLists.txt @@ -113,7 +113,7 @@ if(APPLE) foreach (os ${SANITIZER_COMMON_SUPPORTED_OS}) add_compiler_rt_darwin_dynamic_runtime(clang_rt.asan_${os}_dynamic ${os} - ARCHS ${ASAN_SUPPORTED_ARCH} + ARCHS ${SANITIZER_COMMON_DARWIN_${os}_ARCHES} SOURCES $ $ $ Index: lib/ubsan/CMakeLists.txt =================================================================== --- lib/ubsan/CMakeLists.txt +++ lib/ubsan/CMakeLists.txt @@ -44,7 +44,7 @@ CFLAGS ${UBSAN_STANDALONE_CFLAGS}) foreach(os ${SANITIZER_COMMON_SUPPORTED_OS}) add_compiler_rt_darwin_dynamic_runtime(clang_rt.ubsan_${os}_dynamic ${os} - ARCHS ${UBSAN_SUPPORTED_ARCH} + ARCHS ${SANITIZER_COMMON_DARWIN_${os}_ARCHES} SOURCES $ $ $)