xref: /openbsd-src/gnu/llvm/compiler-rt/cmake/Modules/AddCompilerRT.cmake (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrickinclude(ExternalProject)
23cab2bb3Spatrickinclude(CompilerRTUtils)
31f9cb04fSpatrickinclude(HandleCompilerRT)
43cab2bb3Spatrick
5*810390e3Srobert# CMP0114: ExternalProject step targets fully adopt their steps.
6*810390e3Srobert# New in CMake 3.19: https://cmake.org/cmake/help/latest/policy/CMP0114.html
7*810390e3Srobertif(POLICY CMP0114)
8*810390e3Srobert  cmake_policy(SET CMP0114 OLD)
9*810390e3Srobertendif()
10*810390e3Srobert
113cab2bb3Spatrickfunction(set_target_output_directories target output_dir)
123cab2bb3Spatrick  # For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators
133cab2bb3Spatrick  # append a per-configuration subdirectory to the specified directory.
143cab2bb3Spatrick  # To avoid the appended folder, the configuration specific variable must be
153cab2bb3Spatrick  # set 'RUNTIME_OUTPUT_DIRECTORY_${CONF}':
163cab2bb3Spatrick  # RUNTIME_OUTPUT_DIRECTORY_DEBUG, RUNTIME_OUTPUT_DIRECTORY_RELEASE, ...
173cab2bb3Spatrick  if(CMAKE_CONFIGURATION_TYPES)
183cab2bb3Spatrick    foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
193cab2bb3Spatrick      string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
203cab2bb3Spatrick      set_target_properties("${target}" PROPERTIES
213cab2bb3Spatrick          "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
223cab2bb3Spatrick          "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
233cab2bb3Spatrick          "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir})
243cab2bb3Spatrick    endforeach()
253cab2bb3Spatrick  else()
263cab2bb3Spatrick    set_target_properties("${target}" PROPERTIES
273cab2bb3Spatrick        ARCHIVE_OUTPUT_DIRECTORY ${output_dir}
283cab2bb3Spatrick        LIBRARY_OUTPUT_DIRECTORY ${output_dir}
293cab2bb3Spatrick        RUNTIME_OUTPUT_DIRECTORY ${output_dir})
303cab2bb3Spatrick  endif()
313cab2bb3Spatrickendfunction()
323cab2bb3Spatrick
333cab2bb3Spatrick# Tries to add an "object library" target for a given list of OSs and/or
343cab2bb3Spatrick# architectures with name "<name>.<arch>" for non-Darwin platforms if
353cab2bb3Spatrick# architecture can be targeted, and "<name>.<os>" for Darwin platforms.
363cab2bb3Spatrick# add_compiler_rt_object_libraries(<name>
373cab2bb3Spatrick#                                  OS <os names>
383cab2bb3Spatrick#                                  ARCHS <architectures>
393cab2bb3Spatrick#                                  SOURCES <source files>
403cab2bb3Spatrick#                                  CFLAGS <compile flags>
413cab2bb3Spatrick#                                  DEFS <compile definitions>
423cab2bb3Spatrick#                                  DEPS <dependencies>
433cab2bb3Spatrick#                                  ADDITIONAL_HEADERS <header files>)
443cab2bb3Spatrickfunction(add_compiler_rt_object_libraries name)
453cab2bb3Spatrick  cmake_parse_arguments(LIB "" "" "OS;ARCHS;SOURCES;CFLAGS;DEFS;DEPS;ADDITIONAL_HEADERS"
463cab2bb3Spatrick    ${ARGN})
473cab2bb3Spatrick  set(libnames)
483cab2bb3Spatrick  if(APPLE)
493cab2bb3Spatrick    foreach(os ${LIB_OS})
503cab2bb3Spatrick      set(libname "${name}.${os}")
513cab2bb3Spatrick      set(libnames ${libnames} ${libname})
523cab2bb3Spatrick      set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})
533cab2bb3Spatrick      list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
543cab2bb3Spatrick    endforeach()
553cab2bb3Spatrick  else()
563cab2bb3Spatrick    foreach(arch ${LIB_ARCHS})
573cab2bb3Spatrick      set(libname "${name}.${arch}")
583cab2bb3Spatrick      set(libnames ${libnames} ${libname})
593cab2bb3Spatrick      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS})
603cab2bb3Spatrick      if(NOT CAN_TARGET_${arch})
613cab2bb3Spatrick        message(FATAL_ERROR "Architecture ${arch} can't be targeted")
623cab2bb3Spatrick        return()
633cab2bb3Spatrick      endif()
643cab2bb3Spatrick    endforeach()
653cab2bb3Spatrick  endif()
663cab2bb3Spatrick
673cab2bb3Spatrick  # Add headers to LIB_SOURCES for IDEs
683cab2bb3Spatrick  compiler_rt_process_sources(LIB_SOURCES
693cab2bb3Spatrick    ${LIB_SOURCES}
703cab2bb3Spatrick    ADDITIONAL_HEADERS
713cab2bb3Spatrick      ${LIB_ADDITIONAL_HEADERS}
723cab2bb3Spatrick  )
733cab2bb3Spatrick
743cab2bb3Spatrick  foreach(libname ${libnames})
753cab2bb3Spatrick    add_library(${libname} OBJECT ${LIB_SOURCES})
763cab2bb3Spatrick    if(LIB_DEPS)
773cab2bb3Spatrick      add_dependencies(${libname} ${LIB_DEPS})
783cab2bb3Spatrick    endif()
793cab2bb3Spatrick
803cab2bb3Spatrick    # Strip out -msse3 if this isn't macOS.
813cab2bb3Spatrick    set(target_flags ${LIB_CFLAGS})
823cab2bb3Spatrick    if(APPLE AND NOT "${libname}" MATCHES ".*\.osx.*")
833cab2bb3Spatrick      list(REMOVE_ITEM target_flags "-msse3")
843cab2bb3Spatrick    endif()
853cab2bb3Spatrick
86*810390e3Srobert    # Build the macOS sanitizers with Mac Catalyst support.
87*810390e3Srobert    if (APPLE AND
88*810390e3Srobert        "${COMPILER_RT_ENABLE_MACCATALYST}" AND
89*810390e3Srobert        "${libname}" MATCHES ".*\.osx.*")
90*810390e3Srobert      foreach(arch ${LIB_ARCHS_${libname}})
91*810390e3Srobert        list(APPEND target_flags
92*810390e3Srobert          "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi")
93*810390e3Srobert      endforeach()
94*810390e3Srobert    endif()
95*810390e3Srobert
963cab2bb3Spatrick    set_target_compile_flags(${libname}
973cab2bb3Spatrick      ${extra_cflags_${libname}} ${target_flags})
983cab2bb3Spatrick    set_property(TARGET ${libname} APPEND PROPERTY
993cab2bb3Spatrick      COMPILE_DEFINITIONS ${LIB_DEFS})
1003cab2bb3Spatrick    set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
1013cab2bb3Spatrick    if(APPLE)
1023cab2bb3Spatrick      set_target_properties(${libname} PROPERTIES
1033cab2bb3Spatrick        OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
1043cab2bb3Spatrick    endif()
1053cab2bb3Spatrick  endforeach()
1063cab2bb3Spatrickendfunction()
1073cab2bb3Spatrick
1083cab2bb3Spatrick# Takes a list of object library targets, and a suffix and appends the proper
1093cab2bb3Spatrick# TARGET_OBJECTS string to the output variable.
1103cab2bb3Spatrick# format_object_libs(<output> <suffix> ...)
1113cab2bb3Spatrickmacro(format_object_libs output suffix)
1123cab2bb3Spatrick  foreach(lib ${ARGN})
1133cab2bb3Spatrick    list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>)
1143cab2bb3Spatrick  endforeach()
1153cab2bb3Spatrickendmacro()
1163cab2bb3Spatrick
1173cab2bb3Spatrickfunction(add_compiler_rt_component name)
1183cab2bb3Spatrick  add_custom_target(${name})
1193cab2bb3Spatrick  set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc")
1203cab2bb3Spatrick  if(COMMAND runtime_register_component)
1213cab2bb3Spatrick    runtime_register_component(${name})
1223cab2bb3Spatrick  endif()
1233cab2bb3Spatrick  add_dependencies(compiler-rt ${name})
1243cab2bb3Spatrickendfunction()
1253cab2bb3Spatrick
1263cab2bb3Spatrickfunction(add_asm_sources output)
1273cab2bb3Spatrick  set(${output} ${ARGN} PARENT_SCOPE)
128d89ec533Spatrick  # CMake doesn't pass the correct architecture for Apple prior to CMake 3.19. https://gitlab.kitware.com/cmake/cmake/-/issues/20771
129d89ec533Spatrick  # MinGW didn't work correctly with assembly prior to CMake 3.17. https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4287 and https://reviews.llvm.org/rGb780df052dd2b246a760d00e00f7de9ebdab9d09
130d89ec533Spatrick  # Workaround these two issues by compiling as C.
131d89ec533Spatrick  # Same workaround used in libunwind. Also update there if changed here.
132d89ec533Spatrick  if((APPLE AND CMAKE_VERSION VERSION_LESS 3.19) OR (MINGW AND CMAKE_VERSION VERSION_LESS 3.17))
1333cab2bb3Spatrick    set_source_files_properties(${ARGN} PROPERTIES LANGUAGE C)
1343cab2bb3Spatrick  endif()
1353cab2bb3Spatrickendfunction()
1363cab2bb3Spatrick
1373cab2bb3Spatrickmacro(set_output_name output name arch)
1383cab2bb3Spatrick  if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
1393cab2bb3Spatrick    set(${output} ${name})
1403cab2bb3Spatrick  else()
1413cab2bb3Spatrick    if(ANDROID AND ${arch} STREQUAL "i386")
1423cab2bb3Spatrick      set(${output} "${name}-i686${COMPILER_RT_OS_SUFFIX}")
143d89ec533Spatrick    elseif("${arch}" MATCHES "^arm")
144d89ec533Spatrick      if(COMPILER_RT_DEFAULT_TARGET_ONLY)
145d89ec533Spatrick        set(triple "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}")
146d89ec533Spatrick      else()
147*810390e3Srobert        set(triple "${LLVM_TARGET_TRIPLE}")
148d89ec533Spatrick      endif()
149*810390e3Srobert      # Except for baremetal, when using arch-suffixed runtime library names,
150*810390e3Srobert      # clang only looks for libraries named "arm" or "armhf", see
151*810390e3Srobert      # getArchNameForCompilerRTLib in clang. Therefore, try to inspect both
152*810390e3Srobert      # the arch name and the triple if it seems like we're building an armhf
153*810390e3Srobert      # target.
154*810390e3Srobert      if (COMPILER_RT_BAREMETAL_BUILD)
155*810390e3Srobert        set(${output} "${name}-${arch}${COMPILER_RT_OS_SUFFIX}")
156*810390e3Srobert      elseif ("${arch}" MATCHES "hf$" OR "${triple}" MATCHES "hf$")
157d89ec533Spatrick        set(${output} "${name}-armhf${COMPILER_RT_OS_SUFFIX}")
158d89ec533Spatrick      else()
159d89ec533Spatrick        set(${output} "${name}-arm${COMPILER_RT_OS_SUFFIX}")
160d89ec533Spatrick      endif()
1613cab2bb3Spatrick    else()
1623cab2bb3Spatrick      set(${output} "${name}-${arch}${COMPILER_RT_OS_SUFFIX}")
1633cab2bb3Spatrick    endif()
1643cab2bb3Spatrick  endif()
1653cab2bb3Spatrickendmacro()
1663cab2bb3Spatrick
1673cab2bb3Spatrick# Adds static or shared runtime for a list of architectures and operating
1683cab2bb3Spatrick# systems and puts it in the proper directory in the build and install trees.
1693cab2bb3Spatrick# add_compiler_rt_runtime(<name>
170d89ec533Spatrick#                         {OBJECT|STATIC|SHARED|MODULE}
1713cab2bb3Spatrick#                         ARCHS <architectures>
1723cab2bb3Spatrick#                         OS <os list>
1733cab2bb3Spatrick#                         SOURCES <source files>
1743cab2bb3Spatrick#                         CFLAGS <compile flags>
1753cab2bb3Spatrick#                         LINK_FLAGS <linker flags>
1763cab2bb3Spatrick#                         DEFS <compile definitions>
177d89ec533Spatrick#                         DEPS <dependencies>
1783cab2bb3Spatrick#                         LINK_LIBS <linked libraries> (only for shared library)
1793cab2bb3Spatrick#                         OBJECT_LIBS <object libraries to use as sources>
1803cab2bb3Spatrick#                         PARENT_TARGET <convenience parent target>
1813cab2bb3Spatrick#                         ADDITIONAL_HEADERS <header files>)
1823cab2bb3Spatrickfunction(add_compiler_rt_runtime name type)
183d89ec533Spatrick  if(NOT type MATCHES "^(OBJECT|STATIC|SHARED|MODULE)$")
184d89ec533Spatrick    message(FATAL_ERROR
185d89ec533Spatrick            "type argument must be OBJECT, STATIC, SHARED or MODULE")
1863cab2bb3Spatrick    return()
1873cab2bb3Spatrick  endif()
1883cab2bb3Spatrick  cmake_parse_arguments(LIB
1893cab2bb3Spatrick    ""
1903cab2bb3Spatrick    "PARENT_TARGET"
191d89ec533Spatrick    "OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;DEPS;LINK_LIBS;OBJECT_LIBS;ADDITIONAL_HEADERS"
1923cab2bb3Spatrick    ${ARGN})
1933cab2bb3Spatrick  set(libnames)
1943cab2bb3Spatrick  # Until we support this some other way, build compiler-rt runtime without LTO
1953cab2bb3Spatrick  # to allow non-LTO projects to link with it.
1963cab2bb3Spatrick  if(COMPILER_RT_HAS_FNO_LTO_FLAG)
1973cab2bb3Spatrick    set(NO_LTO_FLAGS "-fno-lto")
1983cab2bb3Spatrick  else()
1993cab2bb3Spatrick    set(NO_LTO_FLAGS "")
2003cab2bb3Spatrick  endif()
2013cab2bb3Spatrick
2021f9cb04fSpatrick  # By default do not instrument or use profdata for compiler-rt.
2031f9cb04fSpatrick  set(NO_PGO_FLAGS "")
2041f9cb04fSpatrick  if(NOT COMPILER_RT_ENABLE_PGO)
2051f9cb04fSpatrick    if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)
2061f9cb04fSpatrick      list(APPEND NO_PGO_FLAGS "-fno-profile-instr-use")
2071f9cb04fSpatrick    endif()
2081f9cb04fSpatrick    if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG)
2091f9cb04fSpatrick      list(APPEND NO_PGO_FLAGS "-fno-profile-generate")
210*810390e3Srobert    elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)
2111f9cb04fSpatrick      list(APPEND NO_PGO_FLAGS "-fno-profile-instr-generate")
212*810390e3Srobert      if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG)
213*810390e3Srobert        list(APPEND NO_PGO_FLAGS "-fno-coverage-mapping")
214*810390e3Srobert      endif()
2151f9cb04fSpatrick    endif()
2161f9cb04fSpatrick  endif()
2171f9cb04fSpatrick
2183cab2bb3Spatrick  list(LENGTH LIB_SOURCES LIB_SOURCES_LENGTH)
2193cab2bb3Spatrick  if (${LIB_SOURCES_LENGTH} GREATER 0)
2203cab2bb3Spatrick    # Add headers to LIB_SOURCES for IDEs. It doesn't make sense to
2213cab2bb3Spatrick    # do this for a runtime library that only consists of OBJECT
2223cab2bb3Spatrick    # libraries, so only add the headers when source files are present.
2233cab2bb3Spatrick    compiler_rt_process_sources(LIB_SOURCES
2243cab2bb3Spatrick      ${LIB_SOURCES}
2253cab2bb3Spatrick      ADDITIONAL_HEADERS
2263cab2bb3Spatrick        ${LIB_ADDITIONAL_HEADERS}
2273cab2bb3Spatrick    )
2283cab2bb3Spatrick  endif()
2293cab2bb3Spatrick
2303cab2bb3Spatrick  if(APPLE)
2313cab2bb3Spatrick    foreach(os ${LIB_OS})
2323cab2bb3Spatrick      # Strip out -msse3 if this isn't macOS.
2333cab2bb3Spatrick      list(LENGTH LIB_CFLAGS HAS_EXTRA_CFLAGS)
2343cab2bb3Spatrick      if(HAS_EXTRA_CFLAGS AND NOT "${os}" MATCHES "^(osx)$")
2353cab2bb3Spatrick        list(REMOVE_ITEM LIB_CFLAGS "-msse3")
2363cab2bb3Spatrick      endif()
2373cab2bb3Spatrick      if(type STREQUAL "STATIC")
2383cab2bb3Spatrick        set(libname "${name}_${os}")
2393cab2bb3Spatrick      else()
2403cab2bb3Spatrick        set(libname "${name}_${os}_dynamic")
2413cab2bb3Spatrick        set(extra_link_flags_${libname} ${DARWIN_${os}_LINK_FLAGS} ${LIB_LINK_FLAGS})
2423cab2bb3Spatrick      endif()
2433cab2bb3Spatrick      list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
2443cab2bb3Spatrick      if(LIB_ARCHS_${libname})
2453cab2bb3Spatrick        list(APPEND libnames ${libname})
2461f9cb04fSpatrick        set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${NO_LTO_FLAGS} ${NO_PGO_FLAGS} ${LIB_CFLAGS})
2473cab2bb3Spatrick        set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
2483cab2bb3Spatrick        set(sources_${libname} ${LIB_SOURCES})
2493cab2bb3Spatrick        format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS})
2503cab2bb3Spatrick        get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir_${libname})
2513cab2bb3Spatrick        get_compiler_rt_install_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} install_dir_${libname})
2523cab2bb3Spatrick      endif()
253*810390e3Srobert
254*810390e3Srobert      # Build the macOS sanitizers with Mac Catalyst support.
255*810390e3Srobert      if ("${COMPILER_RT_ENABLE_MACCATALYST}" AND
256*810390e3Srobert          "${os}" MATCHES "^(osx)$")
257*810390e3Srobert        foreach(arch ${LIB_ARCHS_${libname}})
258*810390e3Srobert          list(APPEND extra_cflags_${libname}
259*810390e3Srobert            "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi")
260*810390e3Srobert          list(APPEND extra_link_flags_${libname}
261*810390e3Srobert            "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi")
262*810390e3Srobert        endforeach()
263*810390e3Srobert      endif()
2643cab2bb3Spatrick    endforeach()
2653cab2bb3Spatrick  else()
2663cab2bb3Spatrick    foreach(arch ${LIB_ARCHS})
2673cab2bb3Spatrick      if(NOT CAN_TARGET_${arch})
2683cab2bb3Spatrick        message(FATAL_ERROR "Architecture ${arch} can't be targeted")
2693cab2bb3Spatrick        return()
2703cab2bb3Spatrick      endif()
2713cab2bb3Spatrick      if(type STREQUAL "OBJECT")
2723cab2bb3Spatrick        set(libname "${name}-${arch}")
2733cab2bb3Spatrick        set_output_name(output_name_${libname} ${name}${COMPILER_RT_OS_SUFFIX} ${arch})
2743cab2bb3Spatrick      elseif(type STREQUAL "STATIC")
2753cab2bb3Spatrick        set(libname "${name}-${arch}")
2763cab2bb3Spatrick        set_output_name(output_name_${libname} ${name} ${arch})
2773cab2bb3Spatrick      else()
2783cab2bb3Spatrick        set(libname "${name}-dynamic-${arch}")
2793cab2bb3Spatrick        set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
2803cab2bb3Spatrick        set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS})
2813cab2bb3Spatrick        if(WIN32)
2823cab2bb3Spatrick          set_output_name(output_name_${libname} ${name}_dynamic ${arch})
2833cab2bb3Spatrick        else()
2843cab2bb3Spatrick          set_output_name(output_name_${libname} ${name} ${arch})
2853cab2bb3Spatrick        endif()
2863cab2bb3Spatrick      endif()
2871f9cb04fSpatrick      if(COMPILER_RT_USE_BUILTINS_LIBRARY AND NOT type STREQUAL "OBJECT" AND
2881f9cb04fSpatrick         NOT name STREQUAL "clang_rt.builtins")
2891f9cb04fSpatrick        get_compiler_rt_target(${arch} target)
290*810390e3Srobert        find_compiler_rt_library(builtins builtins_${libname} TARGET ${target})
2911f9cb04fSpatrick        if(builtins_${libname} STREQUAL "NOTFOUND")
2921f9cb04fSpatrick          message(FATAL_ERROR "Cannot find builtins library for the target architecture")
2931f9cb04fSpatrick        endif()
2941f9cb04fSpatrick      endif()
2953cab2bb3Spatrick      set(sources_${libname} ${LIB_SOURCES})
2963cab2bb3Spatrick      format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS})
2973cab2bb3Spatrick      set(libnames ${libnames} ${libname})
2981f9cb04fSpatrick      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${NO_LTO_FLAGS} ${NO_PGO_FLAGS} ${LIB_CFLAGS})
2993cab2bb3Spatrick      get_compiler_rt_output_dir(${arch} output_dir_${libname})
3003cab2bb3Spatrick      get_compiler_rt_install_dir(${arch} install_dir_${libname})
3013cab2bb3Spatrick    endforeach()
3023cab2bb3Spatrick  endif()
3033cab2bb3Spatrick
3043cab2bb3Spatrick  if(NOT libnames)
3053cab2bb3Spatrick    return()
3063cab2bb3Spatrick  endif()
3073cab2bb3Spatrick
3083cab2bb3Spatrick  if(LIB_PARENT_TARGET)
3093cab2bb3Spatrick    # If the parent targets aren't created we should create them
3103cab2bb3Spatrick    if(NOT TARGET ${LIB_PARENT_TARGET})
3113cab2bb3Spatrick      add_custom_target(${LIB_PARENT_TARGET})
3123cab2bb3Spatrick      set_target_properties(${LIB_PARENT_TARGET} PROPERTIES
3133cab2bb3Spatrick                            FOLDER "Compiler-RT Misc")
3143cab2bb3Spatrick    endif()
3153cab2bb3Spatrick  endif()
3163cab2bb3Spatrick
3173cab2bb3Spatrick  foreach(libname ${libnames})
3183cab2bb3Spatrick    # If you are using a multi-configuration generator we don't generate
3193cab2bb3Spatrick    # per-library install rules, so we fall back to the parent target COMPONENT
3203cab2bb3Spatrick    if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET)
3213cab2bb3Spatrick      set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})
3223cab2bb3Spatrick    else()
3233cab2bb3Spatrick      set(COMPONENT_OPTION COMPONENT ${libname})
3243cab2bb3Spatrick    endif()
3253cab2bb3Spatrick
3263cab2bb3Spatrick    if(type STREQUAL "OBJECT")
3273cab2bb3Spatrick      if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET)
3283cab2bb3Spatrick        list(APPEND extra_cflags_${libname} "--target=${CMAKE_C_COMPILER_TARGET}")
3293cab2bb3Spatrick      endif()
3303cab2bb3Spatrick      if(CMAKE_SYSROOT)
3313cab2bb3Spatrick        list(APPEND extra_cflags_${libname} "--sysroot=${CMAKE_SYSROOT}")
3323cab2bb3Spatrick      endif()
3333cab2bb3Spatrick      string(REPLACE ";" " " extra_cflags_${libname} "${extra_cflags_${libname}}")
3343cab2bb3Spatrick      string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions
3353cab2bb3Spatrick             ${CMAKE_C_COMPILE_OBJECT})
3363cab2bb3Spatrick      set(compile_command_${libname} "${CMAKE_C_COMPILE_OBJECT}")
3373cab2bb3Spatrick
3383cab2bb3Spatrick      set(output_file_${libname} ${output_name_${libname}}${CMAKE_C_OUTPUT_EXTENSION})
3393cab2bb3Spatrick      foreach(substitution ${substitutions})
3403cab2bb3Spatrick        if(substitution STREQUAL "<CMAKE_C_COMPILER>")
3413cab2bb3Spatrick          string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"
3423cab2bb3Spatrick                 compile_command_${libname} ${compile_command_${libname}})
3433cab2bb3Spatrick        elseif(substitution STREQUAL "<OBJECT>")
3443cab2bb3Spatrick          string(REPLACE "<OBJECT>" "${output_dir_${libname}}/${output_file_${libname}}"
3453cab2bb3Spatrick                 compile_command_${libname} ${compile_command_${libname}})
3463cab2bb3Spatrick        elseif(substitution STREQUAL "<SOURCE>")
3473cab2bb3Spatrick          string(REPLACE "<SOURCE>" "${sources_${libname}}"
3483cab2bb3Spatrick                 compile_command_${libname} ${compile_command_${libname}})
3493cab2bb3Spatrick        elseif(substitution STREQUAL "<FLAGS>")
3503cab2bb3Spatrick          string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_cflags_${libname}}"
3513cab2bb3Spatrick                 compile_command_${libname} ${compile_command_${libname}})
3523cab2bb3Spatrick        else()
3533cab2bb3Spatrick          string(REPLACE "${substitution}" "" compile_command_${libname}
3543cab2bb3Spatrick                 ${compile_command_${libname}})
3553cab2bb3Spatrick        endif()
3563cab2bb3Spatrick      endforeach()
3573cab2bb3Spatrick      separate_arguments(compile_command_${libname})
3583cab2bb3Spatrick      add_custom_command(
3593cab2bb3Spatrick          OUTPUT ${output_dir_${libname}}/${output_file_${libname}}
3603cab2bb3Spatrick          COMMAND ${compile_command_${libname}}
3613cab2bb3Spatrick          DEPENDS ${sources_${libname}}
3623cab2bb3Spatrick          COMMENT "Building C object ${output_file_${libname}}")
3633cab2bb3Spatrick      add_custom_target(${libname} DEPENDS ${output_dir_${libname}}/${output_file_${libname}})
3643cab2bb3Spatrick      install(FILES ${output_dir_${libname}}/${output_file_${libname}}
3653cab2bb3Spatrick        DESTINATION ${install_dir_${libname}}
3663cab2bb3Spatrick        ${COMPONENT_OPTION})
3673cab2bb3Spatrick    else()
3683cab2bb3Spatrick      add_library(${libname} ${type} ${sources_${libname}})
3693cab2bb3Spatrick      set_target_compile_flags(${libname} ${extra_cflags_${libname}})
3703cab2bb3Spatrick      set_target_link_flags(${libname} ${extra_link_flags_${libname}})
3713cab2bb3Spatrick      set_property(TARGET ${libname} APPEND PROPERTY
3723cab2bb3Spatrick                   COMPILE_DEFINITIONS ${LIB_DEFS})
3733cab2bb3Spatrick      set_target_output_directories(${libname} ${output_dir_${libname}})
3743cab2bb3Spatrick      install(TARGETS ${libname}
3753cab2bb3Spatrick        ARCHIVE DESTINATION ${install_dir_${libname}}
3763cab2bb3Spatrick                ${COMPONENT_OPTION}
3773cab2bb3Spatrick        LIBRARY DESTINATION ${install_dir_${libname}}
3783cab2bb3Spatrick                ${COMPONENT_OPTION}
3793cab2bb3Spatrick        RUNTIME DESTINATION ${install_dir_${libname}}
3803cab2bb3Spatrick                ${COMPONENT_OPTION})
3813cab2bb3Spatrick    endif()
382d89ec533Spatrick    if(LIB_DEPS)
383d89ec533Spatrick      add_dependencies(${libname} ${LIB_DEPS})
384d89ec533Spatrick    endif()
3853cab2bb3Spatrick    set_target_properties(${libname} PROPERTIES
3863cab2bb3Spatrick        OUTPUT_NAME ${output_name_${libname}})
3873cab2bb3Spatrick    set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime")
3883cab2bb3Spatrick    if(LIB_LINK_LIBS)
3893cab2bb3Spatrick      target_link_libraries(${libname} PRIVATE ${LIB_LINK_LIBS})
3903cab2bb3Spatrick    endif()
3911f9cb04fSpatrick    if(builtins_${libname})
3921f9cb04fSpatrick      target_link_libraries(${libname} PRIVATE ${builtins_${libname}})
3931f9cb04fSpatrick    endif()
3943cab2bb3Spatrick    if(${type} STREQUAL "SHARED")
395*810390e3Srobert      if(APPLE OR WIN32)
396*810390e3Srobert        set_property(TARGET ${libname} PROPERTY BUILD_WITH_INSTALL_RPATH ON)
3973cab2bb3Spatrick      endif()
3983cab2bb3Spatrick      if(WIN32 AND NOT CYGWIN AND NOT MINGW)
3993cab2bb3Spatrick        set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "")
4003cab2bb3Spatrick        set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib")
4013cab2bb3Spatrick      endif()
402*810390e3Srobert      if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*")
403*810390e3Srobert        # Ad-hoc sign the dylibs when using Xcode versions older than 12.
404*810390e3Srobert        # Xcode 12 shipped with ld64-609.
405*810390e3Srobert        # FIXME: Remove whole conditional block once everything uses Xcode 12+.
406*810390e3Srobert        set(LD_V_OUTPUT)
407*810390e3Srobert        execute_process(
408*810390e3Srobert          COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1"
409*810390e3Srobert          RESULT_VARIABLE HAD_ERROR
410*810390e3Srobert          OUTPUT_VARIABLE LD_V_OUTPUT
411*810390e3Srobert        )
412*810390e3Srobert        if (HAD_ERROR)
413*810390e3Srobert          message(FATAL_ERROR "${CMAKE_LINKER} failed with status ${HAD_ERROR}")
414*810390e3Srobert        endif()
415*810390e3Srobert        set(NEED_EXPLICIT_ADHOC_CODESIGN 1)
416*810390e3Srobert        if ("${LD_V_OUTPUT}" MATCHES ".*ld64-([0-9.]+).*")
417*810390e3Srobert          string(REGEX REPLACE ".*ld64-([0-9.]+).*" "\\1" HOST_LINK_VERSION ${LD_V_OUTPUT})
418*810390e3Srobert          if (HOST_LINK_VERSION VERSION_GREATER_EQUAL 609)
419*810390e3Srobert            set(NEED_EXPLICIT_ADHOC_CODESIGN 0)
420*810390e3Srobert          endif()
421*810390e3Srobert        endif()
422*810390e3Srobert        if (NEED_EXPLICIT_ADHOC_CODESIGN)
4233cab2bb3Spatrick          add_custom_command(TARGET ${libname}
4243cab2bb3Spatrick            POST_BUILD
4253cab2bb3Spatrick            COMMAND codesign --sign - $<TARGET_FILE:${libname}>
426d89ec533Spatrick            WORKING_DIRECTORY ${COMPILER_RT_OUTPUT_LIBRARY_DIR}
4273cab2bb3Spatrick          )
4283cab2bb3Spatrick        endif()
4293cab2bb3Spatrick      endif()
430*810390e3Srobert    endif()
4313cab2bb3Spatrick
4323cab2bb3Spatrick    set(parent_target_arg)
4333cab2bb3Spatrick    if(LIB_PARENT_TARGET)
4343cab2bb3Spatrick      set(parent_target_arg PARENT_TARGET ${LIB_PARENT_TARGET})
4353cab2bb3Spatrick    endif()
4363cab2bb3Spatrick    add_compiler_rt_install_targets(${libname} ${parent_target_arg})
4373cab2bb3Spatrick
4383cab2bb3Spatrick    if(APPLE)
4393cab2bb3Spatrick      set_target_properties(${libname} PROPERTIES
4403cab2bb3Spatrick      OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
4413cab2bb3Spatrick    endif()
4423cab2bb3Spatrick
4433cab2bb3Spatrick    if(type STREQUAL "SHARED")
4443cab2bb3Spatrick      rt_externalize_debuginfo(${libname})
4453cab2bb3Spatrick    endif()
4463cab2bb3Spatrick  endforeach()
4473cab2bb3Spatrick  if(LIB_PARENT_TARGET)
4483cab2bb3Spatrick    add_dependencies(${LIB_PARENT_TARGET} ${libnames})
4493cab2bb3Spatrick  endif()
4503cab2bb3Spatrickendfunction()
4513cab2bb3Spatrick
4523cab2bb3Spatrick# Compile and register compiler-rt tests.
4533cab2bb3Spatrick# generate_compiler_rt_tests(<output object files> <test_suite> <test_name>
4543cab2bb3Spatrick#                           <test architecture>
4553cab2bb3Spatrick#                           KIND <custom prefix>
4563cab2bb3Spatrick#                           SUBDIR <subdirectory for testing binary>
4573cab2bb3Spatrick#                           SOURCES <sources to compile>
4583cab2bb3Spatrick#                           RUNTIME <tests runtime to link in>
4593cab2bb3Spatrick#                           CFLAGS <compile-time flags>
4603cab2bb3Spatrick#                           COMPILE_DEPS <compile-time dependencies>
4613cab2bb3Spatrick#                           DEPS <dependencies>
4623cab2bb3Spatrick#                           LINK_FLAGS <flags to use during linking>
4633cab2bb3Spatrick# )
4643cab2bb3Spatrickfunction(generate_compiler_rt_tests test_objects test_suite testname arch)
4653cab2bb3Spatrick  cmake_parse_arguments(TEST "" "KIND;RUNTIME;SUBDIR"
4663cab2bb3Spatrick    "SOURCES;COMPILE_DEPS;DEPS;CFLAGS;LINK_FLAGS" ${ARGN})
4673cab2bb3Spatrick
4683cab2bb3Spatrick  foreach(source ${TEST_SOURCES})
4693cab2bb3Spatrick    sanitizer_test_compile(
4703cab2bb3Spatrick      "${test_objects}" "${source}" "${arch}"
4713cab2bb3Spatrick      KIND ${TEST_KIND}
4723cab2bb3Spatrick      COMPILE_DEPS ${TEST_COMPILE_DEPS}
4733cab2bb3Spatrick      DEPS ${TEST_DEPS}
4743cab2bb3Spatrick      CFLAGS ${TEST_CFLAGS}
4753cab2bb3Spatrick      )
4763cab2bb3Spatrick  endforeach()
4773cab2bb3Spatrick
4783cab2bb3Spatrick  set(TEST_DEPS ${${test_objects}})
4793cab2bb3Spatrick
4803cab2bb3Spatrick  if(NOT "${TEST_RUNTIME}" STREQUAL "")
4813cab2bb3Spatrick    list(APPEND TEST_DEPS ${TEST_RUNTIME})
4823cab2bb3Spatrick    list(APPEND "${test_objects}" $<TARGET_FILE:${TEST_RUNTIME}>)
4833cab2bb3Spatrick  endif()
4843cab2bb3Spatrick
4853cab2bb3Spatrick  add_compiler_rt_test(${test_suite} "${testname}" "${arch}"
4863cab2bb3Spatrick    SUBDIR ${TEST_SUBDIR}
4873cab2bb3Spatrick    OBJECTS ${${test_objects}}
4883cab2bb3Spatrick    DEPS ${TEST_DEPS}
4893cab2bb3Spatrick    LINK_FLAGS ${TEST_LINK_FLAGS}
4903cab2bb3Spatrick    )
4913cab2bb3Spatrick  set("${test_objects}" "${${test_objects}}" PARENT_SCOPE)
4923cab2bb3Spatrickendfunction()
4933cab2bb3Spatrick
4943cab2bb3Spatrick# Link objects into a single executable with COMPILER_RT_TEST_COMPILER,
4953cab2bb3Spatrick# using specified link flags. Make executable a part of provided
4963cab2bb3Spatrick# test_suite.
4973cab2bb3Spatrick# add_compiler_rt_test(<test_suite> <test_name> <arch>
4983cab2bb3Spatrick#                      SUBDIR <subdirectory for binary>
4993cab2bb3Spatrick#                      OBJECTS <object files>
5003cab2bb3Spatrick#                      DEPS <deps (e.g. runtime libs)>
5013cab2bb3Spatrick#                      LINK_FLAGS <link flags>)
5023cab2bb3Spatrickfunction(add_compiler_rt_test test_suite test_name arch)
5033cab2bb3Spatrick  cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN})
5043cab2bb3Spatrick  set(output_dir ${CMAKE_CURRENT_BINARY_DIR})
5053cab2bb3Spatrick  if(TEST_SUBDIR)
5063cab2bb3Spatrick    set(output_dir "${output_dir}/${TEST_SUBDIR}")
5073cab2bb3Spatrick  endif()
5083cab2bb3Spatrick  set(output_dir "${output_dir}/${CMAKE_CFG_INTDIR}")
5093cab2bb3Spatrick  file(MAKE_DIRECTORY "${output_dir}")
5103cab2bb3Spatrick  set(output_bin "${output_dir}/${test_name}")
5113cab2bb3Spatrick  if(MSVC)
5123cab2bb3Spatrick    set(output_bin "${output_bin}.exe")
5133cab2bb3Spatrick  endif()
5143cab2bb3Spatrick
5153cab2bb3Spatrick  # Use host compiler in a standalone build, and just-built Clang otherwise.
5163cab2bb3Spatrick  if(NOT COMPILER_RT_STANDALONE_BUILD)
5173cab2bb3Spatrick    list(APPEND TEST_DEPS clang)
5183cab2bb3Spatrick  endif()
5193cab2bb3Spatrick
5203cab2bb3Spatrick  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
5213cab2bb3Spatrick  list(APPEND TEST_LINK_FLAGS ${TARGET_LINK_FLAGS})
5223cab2bb3Spatrick
5233cab2bb3Spatrick  # If we're not on MSVC, include the linker flags from CMAKE but override them
5243cab2bb3Spatrick  # with the provided link flags. This ensures that flags which are required to
5253cab2bb3Spatrick  # link programs at all are included, but the changes needed for the test
5263cab2bb3Spatrick  # trump. With MSVC we can't do that because CMake is set up to run link.exe
5273cab2bb3Spatrick  # when linking, not the compiler. Here, we hack it to use the compiler
5283cab2bb3Spatrick  # because we want to use -fsanitize flags.
5291f9cb04fSpatrick
5301f9cb04fSpatrick  # Only add CMAKE_EXE_LINKER_FLAGS when in a standalone bulid.
5311f9cb04fSpatrick  # Or else CMAKE_EXE_LINKER_FLAGS contains flags for build compiler of Clang/llvm.
5321f9cb04fSpatrick  # This might not be the same as what the COMPILER_RT_TEST_COMPILER supports.
5331f9cb04fSpatrick  # eg: the build compiler use lld linker and we build clang with default ld linker
5341f9cb04fSpatrick  # then to be tested clang will complain about lld options like --color-diagnostics.
5351f9cb04fSpatrick  if(NOT MSVC AND COMPILER_RT_STANDALONE_BUILD)
5363cab2bb3Spatrick    set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}")
5373cab2bb3Spatrick    separate_arguments(TEST_LINK_FLAGS)
5383cab2bb3Spatrick  endif()
5393cab2bb3Spatrick  if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_HAS_LLD AND "lld" IN_LIST LLVM_ENABLE_PROJECTS)
5403cab2bb3Spatrick    # CMAKE_EXE_LINKER_FLAGS may contain -fuse=lld
5413cab2bb3Spatrick    # FIXME: -DLLVM_ENABLE_LLD=ON and -DLLVM_ENABLE_PROJECTS without lld case.
5423cab2bb3Spatrick    list(APPEND TEST_DEPS lld)
5433cab2bb3Spatrick  endif()
5443cab2bb3Spatrick  add_custom_command(
5453cab2bb3Spatrick    OUTPUT "${output_bin}"
546*810390e3Srobert    COMMAND ${COMPILER_RT_TEST_CXX_COMPILER} ${TEST_OBJECTS} -o "${output_bin}"
5473cab2bb3Spatrick            ${TEST_LINK_FLAGS}
5483cab2bb3Spatrick    DEPENDS ${TEST_DEPS}
5493cab2bb3Spatrick    )
5503cab2bb3Spatrick  add_custom_target(T${test_name} DEPENDS "${output_bin}")
5513cab2bb3Spatrick  set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT Tests")
5523cab2bb3Spatrick
5533cab2bb3Spatrick  # Make the test suite depend on the binary.
5543cab2bb3Spatrick  add_dependencies(${test_suite} T${test_name})
5553cab2bb3Spatrickendfunction()
5563cab2bb3Spatrick
5573cab2bb3Spatrickmacro(add_compiler_rt_resource_file target_name file_name component)
5583cab2bb3Spatrick  set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}")
5593cab2bb3Spatrick  set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}")
5603cab2bb3Spatrick  add_custom_command(OUTPUT ${dst_file}
5613cab2bb3Spatrick    DEPENDS ${src_file}
5623cab2bb3Spatrick    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}
5633cab2bb3Spatrick    COMMENT "Copying ${file_name}...")
5643cab2bb3Spatrick  add_custom_target(${target_name} DEPENDS ${dst_file})
5653cab2bb3Spatrick  # Install in Clang resource directory.
5663cab2bb3Spatrick  install(FILES ${file_name}
567d89ec533Spatrick    DESTINATION ${COMPILER_RT_INSTALL_DATA_DIR}
5683cab2bb3Spatrick    COMPONENT ${component})
5693cab2bb3Spatrick  add_dependencies(${component} ${target_name})
5703cab2bb3Spatrick
5713cab2bb3Spatrick  set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc")
5723cab2bb3Spatrickendmacro()
5733cab2bb3Spatrick
5743cab2bb3Spatrickmacro(add_compiler_rt_script name)
5753cab2bb3Spatrick  set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name})
5763cab2bb3Spatrick  set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name})
5773cab2bb3Spatrick  add_custom_command(OUTPUT ${dst}
5783cab2bb3Spatrick    DEPENDS ${src}
5793cab2bb3Spatrick    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
5803cab2bb3Spatrick    COMMENT "Copying ${name}...")
5813cab2bb3Spatrick  add_custom_target(${name} DEPENDS ${dst})
5823cab2bb3Spatrick  install(FILES ${dst}
5833cab2bb3Spatrick    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
584d89ec533Spatrick    DESTINATION ${COMPILER_RT_INSTALL_BINARY_DIR})
5853cab2bb3Spatrickendmacro(add_compiler_rt_script src name)
5863cab2bb3Spatrick
5873cab2bb3Spatrick# Builds custom version of libc++ and installs it in <prefix>.
5883cab2bb3Spatrick# Can be used to build sanitized versions of libc++ for running unit tests.
5893cab2bb3Spatrick# add_custom_libcxx(<name> <prefix>
5903cab2bb3Spatrick#                   DEPS <list of build deps>
5913cab2bb3Spatrick#                   CFLAGS <list of compile flags>
5923cab2bb3Spatrick#                   USE_TOOLCHAIN)
5933cab2bb3Spatrickmacro(add_custom_libcxx name prefix)
5943cab2bb3Spatrick  if(NOT COMPILER_RT_LIBCXX_PATH)
5953cab2bb3Spatrick    message(FATAL_ERROR "libcxx not found!")
5963cab2bb3Spatrick  endif()
5973cab2bb3Spatrick  if(NOT COMPILER_RT_LIBCXXABI_PATH)
5983cab2bb3Spatrick    message(FATAL_ERROR "libcxxabi not found!")
5993cab2bb3Spatrick  endif()
6003cab2bb3Spatrick
6013cab2bb3Spatrick  cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN})
6023cab2bb3Spatrick
6033cab2bb3Spatrick  if(LIBCXX_USE_TOOLCHAIN)
6043cab2bb3Spatrick    set(compiler_args -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}
6053cab2bb3Spatrick                      -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER})
606d89ec533Spatrick    if(NOT COMPILER_RT_STANDALONE_BUILD AND NOT LLVM_RUNTIMES_BUILD)
6073cab2bb3Spatrick      set(toolchain_deps $<TARGET_FILE:clang>)
6083cab2bb3Spatrick      set(force_deps DEPENDS $<TARGET_FILE:clang>)
6093cab2bb3Spatrick    endif()
6103cab2bb3Spatrick  else()
6113cab2bb3Spatrick    set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
6123cab2bb3Spatrick                      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
6133cab2bb3Spatrick  endif()
6143cab2bb3Spatrick
6153cab2bb3Spatrick  add_custom_target(${name}-clear
616*810390e3Srobert    COMMAND ${CMAKE_COMMAND} -E remove_directory ${prefix}
617*810390e3Srobert    COMMENT "Clobbering ${name} build directories"
6183cab2bb3Spatrick    USES_TERMINAL
6193cab2bb3Spatrick    )
6203cab2bb3Spatrick  set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT Misc")
6213cab2bb3Spatrick
6223cab2bb3Spatrick  add_custom_command(
6233cab2bb3Spatrick    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
6243cab2bb3Spatrick    DEPENDS ${LIBCXX_DEPS} ${toolchain_deps}
625*810390e3Srobert    COMMAND ${CMAKE_COMMAND} -E touch ${prefix}/CMakeCache.txt
6263cab2bb3Spatrick    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp
627*810390e3Srobert    COMMENT "Clobbering bootstrap build directories"
6283cab2bb3Spatrick    )
6293cab2bb3Spatrick
6303cab2bb3Spatrick  add_custom_target(${name}-clobber
6313cab2bb3Spatrick    DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
6323cab2bb3Spatrick  set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT Misc")
6333cab2bb3Spatrick
6343cab2bb3Spatrick  set(PASSTHROUGH_VARIABLES
6353cab2bb3Spatrick    CMAKE_C_COMPILER_TARGET
6363cab2bb3Spatrick    CMAKE_CXX_COMPILER_TARGET
6373cab2bb3Spatrick    CMAKE_SHARED_LINKER_FLAGS
6383cab2bb3Spatrick    CMAKE_MODULE_LINKER_FLAGS
6393cab2bb3Spatrick    CMAKE_EXE_LINKER_FLAGS
6403cab2bb3Spatrick    CMAKE_INSTALL_PREFIX
6413cab2bb3Spatrick    CMAKE_MAKE_PROGRAM
6423cab2bb3Spatrick    CMAKE_LINKER
6433cab2bb3Spatrick    CMAKE_AR
6443cab2bb3Spatrick    CMAKE_RANLIB
6453cab2bb3Spatrick    CMAKE_NM
6463cab2bb3Spatrick    CMAKE_OBJCOPY
6473cab2bb3Spatrick    CMAKE_OBJDUMP
6483cab2bb3Spatrick    CMAKE_STRIP
649*810390e3Srobert    CMAKE_READELF
6503cab2bb3Spatrick    CMAKE_SYSROOT
651d89ec533Spatrick    LIBCXX_HAS_MUSL_LIBC
652*810390e3Srobert    LIBCXX_HAS_GCC_S_LIB
653*810390e3Srobert    LIBCXX_HAS_PTHREAD_LIB
654*810390e3Srobert    LIBCXX_HAS_RT_LIB
655*810390e3Srobert    LIBCXX_USE_COMPILER_RT
656*810390e3Srobert    LIBCXXABI_HAS_PTHREAD_LIB
657d89ec533Spatrick    PYTHON_EXECUTABLE
658d89ec533Spatrick    Python3_EXECUTABLE
659d89ec533Spatrick    Python2_EXECUTABLE
6603cab2bb3Spatrick    CMAKE_SYSTEM_NAME)
6613cab2bb3Spatrick  foreach(variable ${PASSTHROUGH_VARIABLES})
6623cab2bb3Spatrick    get_property(is_value_set CACHE ${variable} PROPERTY VALUE SET)
6633cab2bb3Spatrick    if(${is_value_set})
6643cab2bb3Spatrick      get_property(value CACHE ${variable} PROPERTY VALUE)
6653cab2bb3Spatrick      list(APPEND CMAKE_PASSTHROUGH_VARIABLES -D${variable}=${value})
6663cab2bb3Spatrick    endif()
6673cab2bb3Spatrick  endforeach()
6683cab2bb3Spatrick
6693cab2bb3Spatrick  string(REPLACE ";" " " LIBCXX_C_FLAGS "${LIBCXX_CFLAGS}")
6703cab2bb3Spatrick  get_property(C_FLAGS CACHE CMAKE_C_FLAGS PROPERTY VALUE)
6713cab2bb3Spatrick  set(LIBCXX_C_FLAGS "${LIBCXX_C_FLAGS} ${C_FLAGS}")
6723cab2bb3Spatrick
6733cab2bb3Spatrick  string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CFLAGS}")
6743cab2bb3Spatrick  get_property(CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE)
6753cab2bb3Spatrick  set(LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS} ${CXX_FLAGS}")
6763cab2bb3Spatrick
6773cab2bb3Spatrick  ExternalProject_Add(${name}
6783cab2bb3Spatrick    DEPENDS ${name}-clobber ${LIBCXX_DEPS}
679*810390e3Srobert    PREFIX ${CMAKE_CURRENT_BINARY_DIR}/${name}
680*810390e3Srobert    SOURCE_DIR ${LLVM_MAIN_SRC_DIR}/../runtimes
681*810390e3Srobert    BINARY_DIR ${prefix}
6823cab2bb3Spatrick    CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES}
6833cab2bb3Spatrick               ${compiler_args}
6843cab2bb3Spatrick               -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS}
6853cab2bb3Spatrick               -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS}
6863cab2bb3Spatrick               -DCMAKE_BUILD_TYPE=Release
6873cab2bb3Spatrick               -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
6883cab2bb3Spatrick               -DLLVM_PATH=${LLVM_MAIN_SRC_DIR}
689*810390e3Srobert               -DLLVM_ENABLE_RUNTIMES=libcxx|libcxxabi
690*810390e3Srobert               -DLIBCXXABI_ENABLE_SHARED=OFF
691*810390e3Srobert               -DLIBCXXABI_HERMETIC_STATIC_LIBRARY=ON
692*810390e3Srobert               -DLIBCXXABI_INCLUDE_TESTS=OFF
693*810390e3Srobert               -DLIBCXX_CXX_ABI=libcxxabi
694*810390e3Srobert               -DLIBCXX_ENABLE_SHARED=OFF
695*810390e3Srobert               -DLIBCXX_HERMETIC_STATIC_LIBRARY=ON
696*810390e3Srobert               -DLIBCXX_INCLUDE_BENCHMARKS=OFF
697*810390e3Srobert               -DLIBCXX_INCLUDE_TESTS=OFF
698*810390e3Srobert               -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON
6993cab2bb3Spatrick               ${LIBCXX_CMAKE_ARGS}
7003cab2bb3Spatrick    INSTALL_COMMAND ""
7013cab2bb3Spatrick    STEP_TARGETS configure build
7023cab2bb3Spatrick    BUILD_ALWAYS 1
7033cab2bb3Spatrick    USES_TERMINAL_CONFIGURE 1
7043cab2bb3Spatrick    USES_TERMINAL_BUILD 1
7053cab2bb3Spatrick    USES_TERMINAL_INSTALL 1
706*810390e3Srobert    LIST_SEPARATOR |
7073cab2bb3Spatrick    EXCLUDE_FROM_ALL TRUE
7083cab2bb3Spatrick    BUILD_BYPRODUCTS "${prefix}/lib/libc++.a" "${prefix}/lib/libc++abi.a"
7093cab2bb3Spatrick    )
7103cab2bb3Spatrick
7113cab2bb3Spatrick  if (CMAKE_GENERATOR MATCHES "Make")
712*810390e3Srobert    set(run_clean "$(MAKE)" "-C" "${prefix}" "clean")
7133cab2bb3Spatrick  else()
714*810390e3Srobert    set(run_clean ${CMAKE_COMMAND} --build ${prefix} --target clean
7153cab2bb3Spatrick                                   --config "$<CONFIG>")
7163cab2bb3Spatrick  endif()
7173cab2bb3Spatrick
7183cab2bb3Spatrick  ExternalProject_Add_Step(${name} clean
7193cab2bb3Spatrick    COMMAND ${run_clean}
7203cab2bb3Spatrick    COMMENT "Cleaning ${name}..."
7213cab2bb3Spatrick    DEPENDEES configure
7223cab2bb3Spatrick    ${force_deps}
723*810390e3Srobert    WORKING_DIRECTORY ${prefix}
7243cab2bb3Spatrick    EXCLUDE_FROM_MAIN 1
7253cab2bb3Spatrick    USES_TERMINAL 1
7263cab2bb3Spatrick    )
7273cab2bb3Spatrick  ExternalProject_Add_StepTargets(${name} clean)
7283cab2bb3Spatrick
7293cab2bb3Spatrick  if(LIBCXX_USE_TOOLCHAIN)
7303cab2bb3Spatrick    add_dependencies(${name}-clean ${name}-clobber)
7313cab2bb3Spatrick    set_target_properties(${name}-clean PROPERTIES
7323cab2bb3Spatrick      SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)
7333cab2bb3Spatrick  endif()
7343cab2bb3Spatrickendmacro()
7353cab2bb3Spatrick
7363cab2bb3Spatrickfunction(rt_externalize_debuginfo name)
7373cab2bb3Spatrick  if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO)
7383cab2bb3Spatrick    return()
7393cab2bb3Spatrick  endif()
7403cab2bb3Spatrick
7413cab2bb3Spatrick  if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)
7423cab2bb3Spatrick    set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)
7433cab2bb3Spatrick  endif()
7443cab2bb3Spatrick
7453cab2bb3Spatrick  if(APPLE)
7463cab2bb3Spatrick    if(CMAKE_CXX_FLAGS MATCHES "-flto"
7473cab2bb3Spatrick      OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")
7483cab2bb3Spatrick
7493cab2bb3Spatrick      set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)
7503cab2bb3Spatrick      set_property(TARGET ${name} APPEND_STRING PROPERTY
7513cab2bb3Spatrick        LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}")
7523cab2bb3Spatrick    endif()
7533cab2bb3Spatrick    add_custom_command(TARGET ${name} POST_BUILD
7543cab2bb3Spatrick      COMMAND xcrun dsymutil $<TARGET_FILE:${name}>
7553cab2bb3Spatrick      ${strip_command})
7563cab2bb3Spatrick  else()
7573cab2bb3Spatrick    message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!")
7583cab2bb3Spatrick  endif()
7593cab2bb3Spatrickendfunction()
7603cab2bb3Spatrick
7613cab2bb3Spatrick
7623cab2bb3Spatrick# Configure lit configuration files, including compiler-rt specific variables.
7633cab2bb3Spatrickfunction(configure_compiler_rt_lit_site_cfg input output)
7643cab2bb3Spatrick  set_llvm_build_mode()
7653cab2bb3Spatrick
7663cab2bb3Spatrick  get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir)
7673cab2bb3Spatrick
7683cab2bb3Spatrick  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER})
7693cab2bb3Spatrick  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir})
7703cab2bb3Spatrick
7713cab2bb3Spatrick  configure_lit_site_cfg(${input} ${output})
7723cab2bb3Spatrickendfunction()
773