xref: /openbsd-src/gnu/llvm/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrickinclude(CMakeParseArguments)
23cab2bb3Spatrickinclude(CompilerRTUtils)
33cab2bb3Spatrickinclude(BuiltinTests)
43cab2bb3Spatrick
53cab2bb3Spatrickset(CMAKE_LIPO "lipo" CACHE PATH "path to the lipo tool")
63cab2bb3Spatrick
73cab2bb3Spatrick# On OS X SDKs can be installed anywhere on the base system and xcode-select can
83cab2bb3Spatrick# set the default Xcode to use. This function finds the SDKs that are present in
93cab2bb3Spatrick# the current Xcode.
103cab2bb3Spatrickfunction(find_darwin_sdk_dir var sdk_name)
113cab2bb3Spatrick  set(DARWIN_${sdk_name}_CACHED_SYSROOT "" CACHE STRING "Darwin SDK path for SDK ${sdk_name}.")
123cab2bb3Spatrick  set(DARWIN_PREFER_PUBLIC_SDK OFF CACHE BOOL "Prefer Darwin public SDK, even when an internal SDK is present.")
133cab2bb3Spatrick
143cab2bb3Spatrick  if(DARWIN_${sdk_name}_CACHED_SYSROOT)
153cab2bb3Spatrick    set(${var} ${DARWIN_${sdk_name}_CACHED_SYSROOT} PARENT_SCOPE)
163cab2bb3Spatrick    return()
173cab2bb3Spatrick  endif()
183cab2bb3Spatrick  if(NOT DARWIN_PREFER_PUBLIC_SDK)
193cab2bb3Spatrick    # Let's first try the internal SDK, otherwise use the public SDK.
203cab2bb3Spatrick    execute_process(
213cab2bb3Spatrick      COMMAND xcrun --sdk ${sdk_name}.internal --show-sdk-path
223cab2bb3Spatrick      RESULT_VARIABLE result_process
233cab2bb3Spatrick      OUTPUT_VARIABLE var_internal
243cab2bb3Spatrick      OUTPUT_STRIP_TRAILING_WHITESPACE
253cab2bb3Spatrick      ERROR_FILE /dev/null
263cab2bb3Spatrick    )
273cab2bb3Spatrick  endif()
283cab2bb3Spatrick  if((NOT result_process EQUAL 0) OR "" STREQUAL "${var_internal}")
293cab2bb3Spatrick    execute_process(
303cab2bb3Spatrick      COMMAND xcrun --sdk ${sdk_name} --show-sdk-path
313cab2bb3Spatrick      RESULT_VARIABLE result_process
323cab2bb3Spatrick      OUTPUT_VARIABLE var_internal
333cab2bb3Spatrick      OUTPUT_STRIP_TRAILING_WHITESPACE
343cab2bb3Spatrick      ERROR_FILE /dev/null
353cab2bb3Spatrick    )
363cab2bb3Spatrick  else()
373cab2bb3Spatrick    set(${var}_INTERNAL ${var_internal} PARENT_SCOPE)
383cab2bb3Spatrick  endif()
393cab2bb3Spatrick  if(result_process EQUAL 0)
403cab2bb3Spatrick    set(${var} ${var_internal} PARENT_SCOPE)
413cab2bb3Spatrick  endif()
423cab2bb3Spatrick  message(STATUS "Checking DARWIN_${sdk_name}_SYSROOT - '${var_internal}'")
433cab2bb3Spatrick  set(DARWIN_${sdk_name}_CACHED_SYSROOT ${var_internal} CACHE STRING "Darwin SDK path for SDK ${sdk_name}." FORCE)
443cab2bb3Spatrickendfunction()
453cab2bb3Spatrick
463cab2bb3Spatrickfunction(find_darwin_sdk_version var sdk_name)
471f9cb04fSpatrick  if (DARWIN_${sdk_name}_OVERRIDE_SDK_VERSION)
481f9cb04fSpatrick    message(WARNING "Overriding ${sdk_name} SDK version to ${DARWIN_${sdk_name}_OVERRIDE_SDK_VERSION}")
491f9cb04fSpatrick    set(${var} "${DARWIN_${sdk_name}_OVERRIDE_SDK_VERSION}" PARENT_SCOPE)
501f9cb04fSpatrick    return()
511f9cb04fSpatrick  endif()
523cab2bb3Spatrick  set(result_process 1)
533cab2bb3Spatrick  if(NOT DARWIN_PREFER_PUBLIC_SDK)
543cab2bb3Spatrick    # Let's first try the internal SDK, otherwise use the public SDK.
553cab2bb3Spatrick    execute_process(
563cab2bb3Spatrick      COMMAND xcrun --sdk ${sdk_name}.internal --show-sdk-version
573cab2bb3Spatrick      RESULT_VARIABLE result_process
583cab2bb3Spatrick      OUTPUT_VARIABLE var_internal
593cab2bb3Spatrick      OUTPUT_STRIP_TRAILING_WHITESPACE
603cab2bb3Spatrick      ERROR_FILE /dev/null
613cab2bb3Spatrick    )
623cab2bb3Spatrick  endif()
633cab2bb3Spatrick  if((NOT ${result_process} EQUAL 0) OR "" STREQUAL "${var_internal}")
643cab2bb3Spatrick    execute_process(
653cab2bb3Spatrick      COMMAND xcrun --sdk ${sdk_name} --show-sdk-version
663cab2bb3Spatrick      RESULT_VARIABLE result_process
673cab2bb3Spatrick      OUTPUT_VARIABLE var_internal
683cab2bb3Spatrick      OUTPUT_STRIP_TRAILING_WHITESPACE
693cab2bb3Spatrick      ERROR_FILE /dev/null
703cab2bb3Spatrick    )
713cab2bb3Spatrick  endif()
723cab2bb3Spatrick  if(NOT result_process EQUAL 0)
733cab2bb3Spatrick    message(FATAL_ERROR
743cab2bb3Spatrick      "Failed to determine SDK version for \"${sdk_name}\" SDK")
753cab2bb3Spatrick  endif()
763cab2bb3Spatrick  # Check reported version looks sane.
773cab2bb3Spatrick  if (NOT "${var_internal}" MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+)?$")
783cab2bb3Spatrick    message(FATAL_ERROR
793cab2bb3Spatrick      "Reported SDK version \"${var_internal}\" does not look like a version")
803cab2bb3Spatrick  endif()
813cab2bb3Spatrick  set(${var} ${var_internal} PARENT_SCOPE)
823cab2bb3Spatrickendfunction()
833cab2bb3Spatrick
843cab2bb3Spatrick# There isn't a clear mapping of what architectures are supported with a given
853cab2bb3Spatrick# target platform, but ld's version output does list the architectures it can
863cab2bb3Spatrick# link for.
873cab2bb3Spatrickfunction(darwin_get_toolchain_supported_archs output_var)
883cab2bb3Spatrick  execute_process(
893cab2bb3Spatrick    COMMAND "${CMAKE_LINKER}" -v
903cab2bb3Spatrick    ERROR_VARIABLE LINKER_VERSION)
913cab2bb3Spatrick
923cab2bb3Spatrick  string(REGEX MATCH "configured to support archs: ([^\n]+)"
933cab2bb3Spatrick         ARCHES_MATCHED "${LINKER_VERSION}")
943cab2bb3Spatrick  if(ARCHES_MATCHED)
953cab2bb3Spatrick    set(ARCHES "${CMAKE_MATCH_1}")
963cab2bb3Spatrick    message(STATUS "Got ld supported ARCHES: ${ARCHES}")
973cab2bb3Spatrick    string(REPLACE " " ";" ARCHES ${ARCHES})
983cab2bb3Spatrick  else()
993cab2bb3Spatrick    # If auto-detecting fails, fall back to a default set
1003cab2bb3Spatrick    message(WARNING "Detecting supported architectures from 'ld -v' failed. Returning default set.")
1013cab2bb3Spatrick    set(ARCHES "i386;x86_64;armv7;armv7s;arm64")
1023cab2bb3Spatrick  endif()
1033cab2bb3Spatrick
1043cab2bb3Spatrick  set(${output_var} ${ARCHES} PARENT_SCOPE)
1053cab2bb3Spatrickendfunction()
1063cab2bb3Spatrick
1073cab2bb3Spatrick# This function takes an OS and a list of architectures and identifies the
1083cab2bb3Spatrick# subset of the architectures list that the installed toolchain can target.
1093cab2bb3Spatrickfunction(darwin_test_archs os valid_archs)
1103cab2bb3Spatrick  if(${valid_archs})
1113cab2bb3Spatrick    message(STATUS "Using cached valid architectures for ${os}.")
1123cab2bb3Spatrick    return()
1133cab2bb3Spatrick  endif()
1143cab2bb3Spatrick
1153cab2bb3Spatrick  set(archs ${ARGN})
1163cab2bb3Spatrick  if(NOT TEST_COMPILE_ONLY)
1173cab2bb3Spatrick    message(STATUS "Finding valid architectures for ${os}...")
1183cab2bb3Spatrick    set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c)
119*810390e3Srobert    file(WRITE ${SIMPLE_C} "#include <stdio.h>\nint main(void) { printf(__FILE__); return 0; }\n")
1203cab2bb3Spatrick
1213cab2bb3Spatrick    set(os_linker_flags)
1223cab2bb3Spatrick    foreach(flag ${DARWIN_${os}_LINK_FLAGS})
1233cab2bb3Spatrick      set(os_linker_flags "${os_linker_flags} ${flag}")
1243cab2bb3Spatrick    endforeach()
1253cab2bb3Spatrick
1263cab2bb3Spatrick    # Disable building for i386 for macOS SDK >= 10.15. The SDK doesn't support
1273cab2bb3Spatrick    # linking for i386 and the corresponding OS doesn't allow running macOS i386
1283cab2bb3Spatrick    # binaries.
1293cab2bb3Spatrick    if ("${os}" STREQUAL "osx")
1303cab2bb3Spatrick      find_darwin_sdk_version(macosx_sdk_version "macosx")
1313cab2bb3Spatrick      if ("${macosx_sdk_version}" VERSION_GREATER 10.15 OR "${macosx_sdk_version}" VERSION_EQUAL 10.15)
1323cab2bb3Spatrick        message(STATUS "Disabling i386 slice for ${valid_archs}")
1333cab2bb3Spatrick        list(REMOVE_ITEM archs "i386")
1343cab2bb3Spatrick      endif()
1353cab2bb3Spatrick    endif()
1363cab2bb3Spatrick  endif()
1373cab2bb3Spatrick
1383cab2bb3Spatrick  # The simple program will build for x86_64h on the simulator because it is
1393cab2bb3Spatrick  # compatible with x86_64 libraries (mostly), but since x86_64h isn't actually
1403cab2bb3Spatrick  # a valid or useful architecture for the iOS simulator we should drop it.
1413cab2bb3Spatrick  if(${os} MATCHES "^(iossim|tvossim|watchossim)$")
1423cab2bb3Spatrick    list(REMOVE_ITEM archs "x86_64h")
1433cab2bb3Spatrick  endif()
1443cab2bb3Spatrick
145*810390e3Srobert  if(${os} MATCHES "iossim")
146*810390e3Srobert    message(STATUS "Disabling i386 slice for iossim")
147*810390e3Srobert    list(REMOVE_ITEM archs "i386")
148*810390e3Srobert  endif()
149*810390e3Srobert
1503cab2bb3Spatrick  set(working_archs)
1513cab2bb3Spatrick  foreach(arch ${archs})
1523cab2bb3Spatrick
1533cab2bb3Spatrick    set(arch_linker_flags "-arch ${arch} ${os_linker_flags}")
1543cab2bb3Spatrick    if(TEST_COMPILE_ONLY)
1553cab2bb3Spatrick      # `-w` is used to surpress compiler warnings which `try_compile_only()` treats as an error.
1563cab2bb3Spatrick      try_compile_only(CAN_TARGET_${os}_${arch} FLAGS -v -arch ${arch} ${DARWIN_${os}_CFLAGS} -w)
1573cab2bb3Spatrick    else()
1583cab2bb3Spatrick      set(SAVED_CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
1593cab2bb3Spatrick      set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${arch_linker_flags}")
1603cab2bb3Spatrick      try_compile(CAN_TARGET_${os}_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_C}
1613cab2bb3Spatrick                  COMPILE_DEFINITIONS "-v -arch ${arch}" ${DARWIN_${os}_CFLAGS}
1623cab2bb3Spatrick                  OUTPUT_VARIABLE TEST_OUTPUT)
1633cab2bb3Spatrick      set(CMAKE_EXE_LINKER_FLAGS ${SAVED_CMAKE_EXE_LINKER_FLAGS})
1643cab2bb3Spatrick    endif()
1653cab2bb3Spatrick    if(${CAN_TARGET_${os}_${arch}})
1663cab2bb3Spatrick      list(APPEND working_archs ${arch})
1673cab2bb3Spatrick    else()
1683cab2bb3Spatrick      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
1693cab2bb3Spatrick        "Testing compiler for supporting ${os}-${arch}:\n"
1703cab2bb3Spatrick        "${TEST_OUTPUT}\n")
1713cab2bb3Spatrick    endif()
1723cab2bb3Spatrick  endforeach()
1733cab2bb3Spatrick  set(${valid_archs} ${working_archs}
1743cab2bb3Spatrick    CACHE STRING "List of valid architectures for platform ${os}." FORCE)
1753cab2bb3Spatrickendfunction()
1763cab2bb3Spatrick
1771f9cb04fSpatrick# This function checks the host cputype/cpusubtype to filter supported
1781f9cb04fSpatrick# architecture for the host OS. This is used to determine which tests are
1791f9cb04fSpatrick# available for the host.
1803cab2bb3Spatrickfunction(darwin_filter_host_archs input output)
1813cab2bb3Spatrick  list_intersect(tmp_var DARWIN_osx_ARCHS ${input})
1823cab2bb3Spatrick  execute_process(
1831f9cb04fSpatrick    COMMAND sysctl hw.cputype
1841f9cb04fSpatrick    OUTPUT_VARIABLE CPUTYPE)
1851f9cb04fSpatrick  string(REGEX MATCH "hw.cputype: ([0-9]*)"
1861f9cb04fSpatrick         CPUTYPE_MATCHED "${CPUTYPE}")
1871f9cb04fSpatrick  set(ARM_HOST Off)
1881f9cb04fSpatrick  if(CPUTYPE_MATCHED)
1891f9cb04fSpatrick    # ARM cputype is (0x01000000 | 12) and X86(_64) is always 7.
1901f9cb04fSpatrick    if(${CMAKE_MATCH_1} GREATER 11)
1911f9cb04fSpatrick      set(ARM_HOST On)
1921f9cb04fSpatrick    endif()
1931f9cb04fSpatrick  endif()
1941f9cb04fSpatrick
1951f9cb04fSpatrick  if(ARM_HOST)
1961f9cb04fSpatrick    list(REMOVE_ITEM tmp_var i386)
197*810390e3Srobert    list(REMOVE_ITEM tmp_var x86_64)
198*810390e3Srobert    list(REMOVE_ITEM tmp_var x86_64h)
1991f9cb04fSpatrick  else()
2001f9cb04fSpatrick    list(REMOVE_ITEM tmp_var arm64)
2011f9cb04fSpatrick    list(REMOVE_ITEM tmp_var arm64e)
2021f9cb04fSpatrick    execute_process(
2033cab2bb3Spatrick      COMMAND sysctl hw.cpusubtype
2043cab2bb3Spatrick      OUTPUT_VARIABLE SUBTYPE)
2053cab2bb3Spatrick    string(REGEX MATCH "hw.cpusubtype: ([0-9]*)"
2063cab2bb3Spatrick           SUBTYPE_MATCHED "${SUBTYPE}")
2071f9cb04fSpatrick
2083cab2bb3Spatrick    set(HASWELL_SUPPORTED Off)
2093cab2bb3Spatrick    if(SUBTYPE_MATCHED)
2103cab2bb3Spatrick      if(${CMAKE_MATCH_1} GREATER 7)
2113cab2bb3Spatrick        set(HASWELL_SUPPORTED On)
2123cab2bb3Spatrick      endif()
2133cab2bb3Spatrick    endif()
2143cab2bb3Spatrick    if(NOT HASWELL_SUPPORTED)
2153cab2bb3Spatrick      list(REMOVE_ITEM tmp_var x86_64h)
2163cab2bb3Spatrick    endif()
2171f9cb04fSpatrick  endif()
2181f9cb04fSpatrick
2193cab2bb3Spatrick  set(${output} ${tmp_var} PARENT_SCOPE)
2203cab2bb3Spatrickendfunction()
2213cab2bb3Spatrick
2223cab2bb3Spatrick# Read and process the exclude file into a list of symbols
2233cab2bb3Spatrickfunction(darwin_read_list_from_file output_var file)
2243cab2bb3Spatrick  if(EXISTS ${file})
2253cab2bb3Spatrick    file(READ ${file} EXCLUDES)
2263cab2bb3Spatrick    string(REPLACE "\n" ";" EXCLUDES ${EXCLUDES})
2273cab2bb3Spatrick    set(${output_var} ${EXCLUDES} PARENT_SCOPE)
2283cab2bb3Spatrick  endif()
2293cab2bb3Spatrickendfunction()
2303cab2bb3Spatrick
2313cab2bb3Spatrick# this function takes an OS, architecture and minimum version and provides a
2323cab2bb3Spatrick# list of builtin functions to exclude
2333cab2bb3Spatrickfunction(darwin_find_excluded_builtins_list output_var)
2343cab2bb3Spatrick  cmake_parse_arguments(LIB
2353cab2bb3Spatrick    ""
2363cab2bb3Spatrick    "OS;ARCH;MIN_VERSION"
2373cab2bb3Spatrick    ""
2383cab2bb3Spatrick    ${ARGN})
2393cab2bb3Spatrick
2403cab2bb3Spatrick  if(NOT LIB_OS OR NOT LIB_ARCH)
2413cab2bb3Spatrick    message(FATAL_ERROR "Must specify OS and ARCH to darwin_find_excluded_builtins_list!")
2423cab2bb3Spatrick  endif()
2433cab2bb3Spatrick
2443cab2bb3Spatrick  darwin_read_list_from_file(${LIB_OS}_BUILTINS
2453cab2bb3Spatrick    ${DARWIN_EXCLUDE_DIR}/${LIB_OS}.txt)
2463cab2bb3Spatrick  darwin_read_list_from_file(${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS
2473cab2bb3Spatrick    ${DARWIN_EXCLUDE_DIR}/${LIB_OS}-${LIB_ARCH}.txt)
2483cab2bb3Spatrick
2493cab2bb3Spatrick  if(LIB_MIN_VERSION)
2503cab2bb3Spatrick    file(GLOB builtin_lists ${DARWIN_EXCLUDE_DIR}/${LIB_OS}*-${LIB_ARCH}.txt)
2513cab2bb3Spatrick    foreach(builtin_list ${builtin_lists})
2523cab2bb3Spatrick      string(REGEX MATCH "${LIB_OS}([0-9\\.]*)-${LIB_ARCH}.txt" VERSION_MATCHED "${builtin_list}")
2533cab2bb3Spatrick      if (VERSION_MATCHED AND NOT CMAKE_MATCH_1 VERSION_LESS LIB_MIN_VERSION)
2543cab2bb3Spatrick        if(NOT smallest_version)
2553cab2bb3Spatrick          set(smallest_version ${CMAKE_MATCH_1})
2563cab2bb3Spatrick        elseif(CMAKE_MATCH_1 VERSION_LESS smallest_version)
2573cab2bb3Spatrick          set(smallest_version ${CMAKE_MATCH_1})
2583cab2bb3Spatrick        endif()
2593cab2bb3Spatrick      endif()
2603cab2bb3Spatrick    endforeach()
2613cab2bb3Spatrick
2623cab2bb3Spatrick    if(smallest_version)
2633cab2bb3Spatrick      darwin_read_list_from_file(${LIB_ARCH}_${LIB_OS}_BUILTINS
2643cab2bb3Spatrick        ${DARWIN_EXCLUDE_DIR}/${LIB_OS}${smallest_version}-${LIB_ARCH}.txt)
2653cab2bb3Spatrick    endif()
2663cab2bb3Spatrick  endif()
2673cab2bb3Spatrick
2683cab2bb3Spatrick  set(${output_var}
2693cab2bb3Spatrick      ${${LIB_ARCH}_${LIB_OS}_BUILTINS}
2703cab2bb3Spatrick      ${${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS}
2713cab2bb3Spatrick      ${${LIB_OS}_BUILTINS} PARENT_SCOPE)
2723cab2bb3Spatrickendfunction()
2733cab2bb3Spatrick
2743cab2bb3Spatrick# adds a single builtin library for a single OS & ARCH
2753cab2bb3Spatrickmacro(darwin_add_builtin_library name suffix)
2763cab2bb3Spatrick  cmake_parse_arguments(LIB
2773cab2bb3Spatrick    ""
2783cab2bb3Spatrick    "PARENT_TARGET;OS;ARCH"
2793cab2bb3Spatrick    "SOURCES;CFLAGS;DEFS;INCLUDE_DIRS"
2803cab2bb3Spatrick    ${ARGN})
2813cab2bb3Spatrick  set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}")
2823cab2bb3Spatrick  add_library(${libname} STATIC ${LIB_SOURCES})
2833cab2bb3Spatrick  if(DARWIN_${LIB_OS}_SYSROOT)
2843cab2bb3Spatrick    set(sysroot_flag -isysroot ${DARWIN_${LIB_OS}_SYSROOT})
2853cab2bb3Spatrick  endif()
2863cab2bb3Spatrick
2873cab2bb3Spatrick  # Make a copy of the compilation flags.
2883cab2bb3Spatrick  set(builtin_cflags ${LIB_CFLAGS})
2893cab2bb3Spatrick
2903cab2bb3Spatrick  # Strip out any inappropriate flags for the target.
2913cab2bb3Spatrick  if("${LIB_ARCH}" MATCHES "^(armv7|armv7k|armv7s)$")
2923cab2bb3Spatrick    set(builtin_cflags "")
2933cab2bb3Spatrick    foreach(cflag "${LIB_CFLAGS}")
2943cab2bb3Spatrick      string(REPLACE "-fomit-frame-pointer" "" cflag "${cflag}")
2953cab2bb3Spatrick      list(APPEND builtin_cflags ${cflag})
2963cab2bb3Spatrick    endforeach(cflag)
2973cab2bb3Spatrick  endif()
2983cab2bb3Spatrick
299d89ec533Spatrick  if ("${LIB_OS}" MATCHES ".*sim$")
300d89ec533Spatrick    # Pass an explicit -simulator environment to the -target option to ensure
301d89ec533Spatrick    # that we don't rely on the architecture to infer whether we're building
302d89ec533Spatrick    # for the simulator.
303d89ec533Spatrick    string(REGEX REPLACE "sim" "" base_os "${LIB_OS}")
304d89ec533Spatrick    list(APPEND builtin_cflags
305d89ec533Spatrick         -target "${LIB_ARCH}-apple-${base_os}${DARWIN_${LIBOS}_BUILTIN_MIN_VER}-simulator")
306d89ec533Spatrick  endif()
307d89ec533Spatrick
308*810390e3Srobert  if ("${COMPILER_RT_ENABLE_MACCATALYST}" AND
309*810390e3Srobert      "${LIB_OS}" MATCHES "^osx$")
310*810390e3Srobert    # Build the macOS builtins with Mac Catalyst support.
311*810390e3Srobert    list(APPEND builtin_cflags
312*810390e3Srobert      "SHELL:-target ${LIB_ARCH}-apple-macos${DARWIN_osx_BUILTIN_MIN_VER} -darwin-target-variant ${LIB_ARCH}-apple-ios13.1-macabi")
313*810390e3Srobert  endif()
314*810390e3Srobert
3153cab2bb3Spatrick  set_target_compile_flags(${libname}
3163cab2bb3Spatrick    ${sysroot_flag}
3173cab2bb3Spatrick    ${DARWIN_${LIB_OS}_BUILTIN_MIN_VER_FLAG}
3183cab2bb3Spatrick    ${builtin_cflags})
3193cab2bb3Spatrick  target_include_directories(${libname}
3203cab2bb3Spatrick    PRIVATE ${LIB_INCLUDE_DIRS})
3213cab2bb3Spatrick  set_property(TARGET ${libname} APPEND PROPERTY
3223cab2bb3Spatrick      COMPILE_DEFINITIONS ${LIB_DEFS})
3233cab2bb3Spatrick  set_target_properties(${libname} PROPERTIES
3243cab2bb3Spatrick      OUTPUT_NAME ${libname}${COMPILER_RT_OS_SUFFIX})
3253cab2bb3Spatrick  set_target_properties(${libname} PROPERTIES
3263cab2bb3Spatrick    OSX_ARCHITECTURES ${LIB_ARCH})
3273cab2bb3Spatrick
3283cab2bb3Spatrick  if(LIB_PARENT_TARGET)
3293cab2bb3Spatrick    add_dependencies(${LIB_PARENT_TARGET} ${libname})
3303cab2bb3Spatrick  endif()
3313cab2bb3Spatrick
3323cab2bb3Spatrick  list(APPEND ${LIB_OS}_${suffix}_libs ${libname})
3333cab2bb3Spatrick  list(APPEND ${LIB_OS}_${suffix}_lipo_flags -arch ${arch} $<TARGET_FILE:${libname}>)
3343cab2bb3Spatrick  set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
3353cab2bb3Spatrickendmacro()
3363cab2bb3Spatrick
3373cab2bb3Spatrickfunction(darwin_lipo_libs name)
3383cab2bb3Spatrick  cmake_parse_arguments(LIB
3393cab2bb3Spatrick    ""
3403cab2bb3Spatrick    "PARENT_TARGET;OUTPUT_DIR;INSTALL_DIR"
3413cab2bb3Spatrick    "LIPO_FLAGS;DEPENDS"
3423cab2bb3Spatrick    ${ARGN})
3433cab2bb3Spatrick  if(LIB_DEPENDS AND LIB_LIPO_FLAGS)
3443cab2bb3Spatrick    add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a
3453cab2bb3Spatrick      COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
3463cab2bb3Spatrick      COMMAND ${CMAKE_LIPO} -output
3473cab2bb3Spatrick              ${LIB_OUTPUT_DIR}/lib${name}.a
3483cab2bb3Spatrick              -create ${LIB_LIPO_FLAGS}
3493cab2bb3Spatrick      DEPENDS ${LIB_DEPENDS}
3503cab2bb3Spatrick      )
3513cab2bb3Spatrick    add_custom_target(${name}
3523cab2bb3Spatrick      DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)
3533cab2bb3Spatrick    set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc")
3543cab2bb3Spatrick    add_dependencies(${LIB_PARENT_TARGET} ${name})
3553cab2bb3Spatrick
3563cab2bb3Spatrick    if(CMAKE_CONFIGURATION_TYPES)
3573cab2bb3Spatrick      set(install_component ${LIB_PARENT_TARGET})
3583cab2bb3Spatrick    else()
3593cab2bb3Spatrick      set(install_component ${name})
3603cab2bb3Spatrick    endif()
3613cab2bb3Spatrick    install(FILES ${LIB_OUTPUT_DIR}/lib${name}.a
3623cab2bb3Spatrick      DESTINATION ${LIB_INSTALL_DIR}
3633cab2bb3Spatrick      COMPONENT ${install_component})
3643cab2bb3Spatrick    add_compiler_rt_install_targets(${name} PARENT_TARGET ${LIB_PARENT_TARGET})
3653cab2bb3Spatrick  else()
3663cab2bb3Spatrick    message(WARNING "Not generating lipo target for ${name} because no input libraries exist.")
3673cab2bb3Spatrick  endif()
3683cab2bb3Spatrickendfunction()
3693cab2bb3Spatrick
3701f9cb04fSpatrick# Filter the list of builtin sources for Darwin, then delegate to the generic
3711f9cb04fSpatrick# filtering.
3721f9cb04fSpatrick#
3731f9cb04fSpatrick# `exclude_or_include` must be one of:
3741f9cb04fSpatrick#  - EXCLUDE: remove every item whose name (w/o extension) matches a name in
3751f9cb04fSpatrick#    `excluded_list`.
3761f9cb04fSpatrick#  - INCLUDE: keep only items whose name (w/o extension) matches something
3771f9cb04fSpatrick#    in `excluded_list`.
3781f9cb04fSpatrickfunction(darwin_filter_builtin_sources output_var name exclude_or_include excluded_list)
3791f9cb04fSpatrick  if(exclude_or_include STREQUAL "EXCLUDE")
3801f9cb04fSpatrick    set(filter_action GREATER)
3811f9cb04fSpatrick    set(filter_value -1)
3821f9cb04fSpatrick  elseif(exclude_or_include STREQUAL "INCLUDE")
3831f9cb04fSpatrick    set(filter_action LESS)
3841f9cb04fSpatrick    set(filter_value 0)
3851f9cb04fSpatrick  else()
3861f9cb04fSpatrick    message(FATAL_ERROR "darwin_filter_builtin_sources called without EXCLUDE|INCLUDE")
3871f9cb04fSpatrick  endif()
3881f9cb04fSpatrick
3891f9cb04fSpatrick  set(intermediate ${ARGN})
3901f9cb04fSpatrick  foreach(_file ${intermediate})
3911f9cb04fSpatrick    get_filename_component(_name_we ${_file} NAME_WE)
3921f9cb04fSpatrick    list(FIND ${excluded_list} ${_name_we} _found)
3931f9cb04fSpatrick    if(_found ${filter_action} ${filter_value})
3941f9cb04fSpatrick      list(REMOVE_ITEM intermediate ${_file})
3951f9cb04fSpatrick    endif()
3961f9cb04fSpatrick  endforeach()
3971f9cb04fSpatrick
3981f9cb04fSpatrick  filter_builtin_sources(intermediate ${name})
3991f9cb04fSpatrick  set(${output_var} ${intermediate} PARENT_SCOPE)
4001f9cb04fSpatrickendfunction()
4011f9cb04fSpatrick
4023cab2bb3Spatrick# Generates builtin libraries for all operating systems specified in ARGN. Each
4033cab2bb3Spatrick# OS library is constructed by lipo-ing together single-architecture libraries.
4043cab2bb3Spatrickmacro(darwin_add_builtin_libraries)
4053cab2bb3Spatrick  set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes)
4063cab2bb3Spatrick
407*810390e3Srobert  set(CFLAGS -fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer)
4083cab2bb3Spatrick  set(CMAKE_C_FLAGS "")
4093cab2bb3Spatrick  set(CMAKE_CXX_FLAGS "")
4103cab2bb3Spatrick  set(CMAKE_ASM_FLAGS "")
4113cab2bb3Spatrick
412*810390e3Srobert  append_list_if(COMPILER_RT_HAS_ASM_LSE -DHAS_ASM_LSE CFLAGS)
413d89ec533Spatrick
414d89ec533Spatrick  set(PROFILE_SOURCES ../profile/InstrProfiling.c
415d89ec533Spatrick                      ../profile/InstrProfilingBuffer.c
416d89ec533Spatrick                      ../profile/InstrProfilingPlatformDarwin.c
417d89ec533Spatrick                      ../profile/InstrProfilingWriter.c
418d89ec533Spatrick                      ../profile/InstrProfilingInternal.c
419d89ec533Spatrick                      ../profile/InstrProfilingVersionVar.c)
4203cab2bb3Spatrick  foreach (os ${ARGN})
421*810390e3Srobert    set(macosx_sdk_version 99999)
422*810390e3Srobert    if ("${os}" STREQUAL "osx")
423*810390e3Srobert      find_darwin_sdk_version(macosx_sdk_version "macosx")
424*810390e3Srobert    endif()
425*810390e3Srobert    add_security_warnings(CFLAGS ${macosx_sdk_version})
426*810390e3Srobert
4273cab2bb3Spatrick    list_intersect(DARWIN_BUILTIN_ARCHS DARWIN_${os}_BUILTIN_ARCHS BUILTIN_SUPPORTED_ARCH)
428d89ec533Spatrick
429d89ec533Spatrick    if((arm64 IN_LIST DARWIN_BUILTIN_ARCHS OR arm64e IN_LIST DARWIN_BUILTIN_ARCHS) AND NOT TARGET lse_builtin_symlinks)
430d89ec533Spatrick      add_custom_target(
431d89ec533Spatrick        lse_builtin_symlinks
432d89ec533Spatrick        BYPRODUCTS ${lse_builtins}
433d89ec533Spatrick        ${arm64_lse_commands}
434d89ec533Spatrick      )
435d89ec533Spatrick
436d89ec533Spatrick      set(deps_arm64 lse_builtin_symlinks)
437d89ec533Spatrick      set(deps_arm64e lse_builtin_symlinks)
438d89ec533Spatrick    endif()
439d89ec533Spatrick
4403cab2bb3Spatrick    foreach (arch ${DARWIN_BUILTIN_ARCHS})
4413cab2bb3Spatrick      darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
4423cab2bb3Spatrick                              OS ${os}
4433cab2bb3Spatrick                              ARCH ${arch}
4443cab2bb3Spatrick                              MIN_VERSION ${DARWIN_${os}_BUILTIN_MIN_VER})
4453cab2bb3Spatrick
4461f9cb04fSpatrick      darwin_filter_builtin_sources(filtered_sources
4471f9cb04fSpatrick        ${os}_${arch}
4483cab2bb3Spatrick        EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS
4493cab2bb3Spatrick        ${${arch}_SOURCES})
4503cab2bb3Spatrick
4513cab2bb3Spatrick      darwin_add_builtin_library(clang_rt builtins
4523cab2bb3Spatrick                              OS ${os}
4533cab2bb3Spatrick                              ARCH ${arch}
454d89ec533Spatrick                              DEPS ${deps_${arch}}
4553cab2bb3Spatrick                              SOURCES ${filtered_sources}
4563cab2bb3Spatrick                              CFLAGS ${CFLAGS} -arch ${arch}
4573cab2bb3Spatrick                              PARENT_TARGET builtins)
4583cab2bb3Spatrick    endforeach()
4593cab2bb3Spatrick
4603cab2bb3Spatrick    # Don't build cc_kext libraries for simulator platforms
4613cab2bb3Spatrick    if(NOT DARWIN_${os}_SKIP_CC_KEXT)
4623cab2bb3Spatrick      foreach (arch ${DARWIN_BUILTIN_ARCHS})
4633cab2bb3Spatrick        # By not specifying MIN_VERSION this only reads the OS and OS-arch lists.
4643cab2bb3Spatrick        # We don't want to filter out the builtins that are present in libSystem
4653cab2bb3Spatrick        # because kexts can't link libSystem.
4663cab2bb3Spatrick        darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
4673cab2bb3Spatrick                              OS ${os}
4683cab2bb3Spatrick                              ARCH ${arch})
4693cab2bb3Spatrick
4701f9cb04fSpatrick        darwin_filter_builtin_sources(filtered_sources
4711f9cb04fSpatrick          cc_kext_${os}_${arch}
4723cab2bb3Spatrick          EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS
4733cab2bb3Spatrick          ${${arch}_SOURCES})
4743cab2bb3Spatrick
4753cab2bb3Spatrick        # In addition to the builtins cc_kext includes some profile sources
4763cab2bb3Spatrick        darwin_add_builtin_library(clang_rt cc_kext
4773cab2bb3Spatrick                                OS ${os}
4783cab2bb3Spatrick                                ARCH ${arch}
479d89ec533Spatrick                                DEPS ${deps_${arch}}
4803cab2bb3Spatrick                                SOURCES ${filtered_sources} ${PROFILE_SOURCES}
4813cab2bb3Spatrick                                CFLAGS ${CFLAGS} -arch ${arch} -mkernel
4823cab2bb3Spatrick                                DEFS KERNEL_USE
4833cab2bb3Spatrick                                INCLUDE_DIRS ../../include
4843cab2bb3Spatrick                                PARENT_TARGET builtins)
4853cab2bb3Spatrick      endforeach()
4863cab2bb3Spatrick      set(archive_name clang_rt.cc_kext_${os})
4873cab2bb3Spatrick      if(${os} STREQUAL "osx")
4883cab2bb3Spatrick        set(archive_name clang_rt.cc_kext)
4893cab2bb3Spatrick      endif()
4903cab2bb3Spatrick      darwin_lipo_libs(${archive_name}
4913cab2bb3Spatrick                      PARENT_TARGET builtins
4923cab2bb3Spatrick                      LIPO_FLAGS ${${os}_cc_kext_lipo_flags}
4933cab2bb3Spatrick                      DEPENDS ${${os}_cc_kext_libs}
494d89ec533Spatrick                      OUTPUT_DIR ${COMPILER_RT_OUTPUT_LIBRARY_DIR}
495d89ec533Spatrick                      INSTALL_DIR ${COMPILER_RT_INSTALL_LIBRARY_DIR})
4963cab2bb3Spatrick    endif()
4973cab2bb3Spatrick  endforeach()
4983cab2bb3Spatrick
4993cab2bb3Spatrick  foreach (os ${ARGN})
5003cab2bb3Spatrick    darwin_lipo_libs(clang_rt.${os}
5013cab2bb3Spatrick                     PARENT_TARGET builtins
502d89ec533Spatrick                     LIPO_FLAGS ${${os}_builtins_lipo_flags}
503d89ec533Spatrick                     DEPENDS ${${os}_builtins_libs}
504d89ec533Spatrick                     OUTPUT_DIR ${COMPILER_RT_OUTPUT_LIBRARY_DIR}
505d89ec533Spatrick                     INSTALL_DIR ${COMPILER_RT_INSTALL_LIBRARY_DIR})
5063cab2bb3Spatrick  endforeach()
5073cab2bb3Spatrick  darwin_add_embedded_builtin_libraries()
5083cab2bb3Spatrickendmacro()
5093cab2bb3Spatrick
5103cab2bb3Spatrickmacro(darwin_add_embedded_builtin_libraries)
5113cab2bb3Spatrick  # this is a hacky opt-out. If you can't target both intel and arm
5123cab2bb3Spatrick  # architectures we bail here.
5133cab2bb3Spatrick  set(DARWIN_SOFT_FLOAT_ARCHS armv6m armv7m armv7em armv7)
5143cab2bb3Spatrick  set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7)
5153cab2bb3Spatrick  if(COMPILER_RT_SUPPORTED_ARCH MATCHES ".*armv.*")
5163cab2bb3Spatrick    list(FIND COMPILER_RT_SUPPORTED_ARCH i386 i386_idx)
5173cab2bb3Spatrick    if(i386_idx GREATER -1)
5183cab2bb3Spatrick      list(APPEND DARWIN_HARD_FLOAT_ARCHS i386)
5193cab2bb3Spatrick    endif()
5203cab2bb3Spatrick
5213cab2bb3Spatrick    list(FIND COMPILER_RT_SUPPORTED_ARCH x86_64 x86_64_idx)
5223cab2bb3Spatrick    if(x86_64_idx GREATER -1)
5233cab2bb3Spatrick      list(APPEND DARWIN_HARD_FLOAT_ARCHS x86_64)
5243cab2bb3Spatrick    endif()
5253cab2bb3Spatrick
5263cab2bb3Spatrick    set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded)
5273cab2bb3Spatrick
528*810390e3Srobert    set(CFLAGS -Oz -Wall -fomit-frame-pointer -ffreestanding)
5293cab2bb3Spatrick    set(CMAKE_C_FLAGS "")
5303cab2bb3Spatrick    set(CMAKE_CXX_FLAGS "")
5313cab2bb3Spatrick    set(CMAKE_ASM_FLAGS "")
5323cab2bb3Spatrick
5333cab2bb3Spatrick    set(SOFT_FLOAT_FLAG -mfloat-abi=soft)
5343cab2bb3Spatrick    set(HARD_FLOAT_FLAG -mfloat-abi=hard)
5353cab2bb3Spatrick
5363cab2bb3Spatrick    set(ENABLE_PIC Off)
5373cab2bb3Spatrick    set(PIC_FLAG -fPIC)
5383cab2bb3Spatrick    set(STATIC_FLAG -static)
5393cab2bb3Spatrick
5403cab2bb3Spatrick    set(DARWIN_macho_embedded_ARCHS armv6m armv7m armv7em armv7 i386 x86_64)
5413cab2bb3Spatrick
5423cab2bb3Spatrick    set(DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR
543d89ec533Spatrick      ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/macho_embedded)
5443cab2bb3Spatrick    set(DARWIN_macho_embedded_LIBRARY_INSTALL_DIR
545d89ec533Spatrick      ${COMPILER_RT_INSTALL_LIBRARY_DIR}/macho_embedded)
5463cab2bb3Spatrick
547*810390e3Srobert    set(CFLAGS_armv7 -target thumbv7-apple-darwin-eabi)
548*810390e3Srobert    set(CFLAGS_i386 -march=pentium)
5493cab2bb3Spatrick
5503cab2bb3Spatrick    darwin_read_list_from_file(common_FUNCTIONS ${MACHO_SYM_DIR}/common.txt)
5513cab2bb3Spatrick    darwin_read_list_from_file(thumb2_FUNCTIONS ${MACHO_SYM_DIR}/thumb2.txt)
5523cab2bb3Spatrick    darwin_read_list_from_file(thumb2_64_FUNCTIONS ${MACHO_SYM_DIR}/thumb2-64.txt)
5533cab2bb3Spatrick    darwin_read_list_from_file(arm_FUNCTIONS ${MACHO_SYM_DIR}/arm.txt)
5543cab2bb3Spatrick    darwin_read_list_from_file(i386_FUNCTIONS ${MACHO_SYM_DIR}/i386.txt)
5553cab2bb3Spatrick
5563cab2bb3Spatrick
5573cab2bb3Spatrick    set(armv6m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS})
5583cab2bb3Spatrick    set(armv7m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
5593cab2bb3Spatrick    set(armv7em_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
5603cab2bb3Spatrick    set(armv7_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS} ${thumb2_64_FUNCTIONS})
5613cab2bb3Spatrick    set(i386_FUNCTIONS ${common_FUNCTIONS} ${i386_FUNCTIONS})
5623cab2bb3Spatrick    set(x86_64_FUNCTIONS ${common_FUNCTIONS})
5633cab2bb3Spatrick
5643cab2bb3Spatrick    foreach(arch ${DARWIN_macho_embedded_ARCHS})
5651f9cb04fSpatrick      darwin_filter_builtin_sources(${arch}_filtered_sources
5661f9cb04fSpatrick        macho_embedded_${arch}
5673cab2bb3Spatrick        INCLUDE ${arch}_FUNCTIONS
5683cab2bb3Spatrick        ${${arch}_SOURCES})
5693cab2bb3Spatrick      if(NOT ${arch}_filtered_sources)
5703cab2bb3Spatrick        message(WARNING "${arch}_SOURCES: ${${arch}_SOURCES}")
5713cab2bb3Spatrick        message(WARNING "${arch}_FUNCTIONS: ${${arch}_FUNCTIONS}")
5723cab2bb3Spatrick        message(FATAL_ERROR "Empty filtered sources!")
5733cab2bb3Spatrick      endif()
5743cab2bb3Spatrick    endforeach()
5753cab2bb3Spatrick
5763cab2bb3Spatrick    foreach(float_type SOFT HARD)
5773cab2bb3Spatrick      foreach(type PIC STATIC)
5783cab2bb3Spatrick        string(TOLOWER "${float_type}_${type}" lib_suffix)
5793cab2bb3Spatrick        foreach(arch ${DARWIN_${float_type}_FLOAT_ARCHS})
5803cab2bb3Spatrick          set(DARWIN_macho_embedded_SYSROOT ${DARWIN_osx_SYSROOT})
5813cab2bb3Spatrick          set(float_flag)
5823cab2bb3Spatrick          if(${arch} MATCHES "^arm")
5833cab2bb3Spatrick            # x86 targets are hard float by default, but the complain about the
5843cab2bb3Spatrick            # float ABI flag, so don't pass it unless we're targeting arm.
5853cab2bb3Spatrick            set(float_flag ${${float_type}_FLOAT_FLAG})
5863cab2bb3Spatrick          endif()
5873cab2bb3Spatrick          darwin_add_builtin_library(clang_rt ${lib_suffix}
5883cab2bb3Spatrick                                OS macho_embedded
5893cab2bb3Spatrick                                ARCH ${arch}
5903cab2bb3Spatrick                                SOURCES ${${arch}_filtered_sources}
5913cab2bb3Spatrick                                CFLAGS ${CFLAGS} -arch ${arch} ${${type}_FLAG} ${float_flag} ${CFLAGS_${arch}}
5923cab2bb3Spatrick                                PARENT_TARGET builtins)
5933cab2bb3Spatrick        endforeach()
5943cab2bb3Spatrick        foreach(lib ${macho_embedded_${lib_suffix}_libs})
5953cab2bb3Spatrick          set_target_properties(${lib} PROPERTIES LINKER_LANGUAGE C)
5963cab2bb3Spatrick        endforeach()
5973cab2bb3Spatrick        darwin_lipo_libs(clang_rt.${lib_suffix}
5983cab2bb3Spatrick                      PARENT_TARGET builtins
5993cab2bb3Spatrick                      LIPO_FLAGS ${macho_embedded_${lib_suffix}_lipo_flags}
6003cab2bb3Spatrick                      DEPENDS ${macho_embedded_${lib_suffix}_libs}
6013cab2bb3Spatrick                      OUTPUT_DIR ${DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR}
6023cab2bb3Spatrick                      INSTALL_DIR ${DARWIN_macho_embedded_LIBRARY_INSTALL_DIR})
6033cab2bb3Spatrick      endforeach()
6043cab2bb3Spatrick    endforeach()
6053cab2bb3Spatrick  endif()
6063cab2bb3Spatrickendmacro()
607