Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / cmake / Modules / CompilerRTDarwinUtils.cmake
blob6a62d3bf7adcedd5517e40af3a493bce88551b60
1 include(CMakeParseArguments)
2 include(CompilerRTUtils)
3 include(BuiltinTests)
5 set(CMAKE_LIPO "lipo" CACHE PATH "path to the lipo tool")
7 # On OS X SDKs can be installed anywhere on the base system and xcode-select can
8 # set the default Xcode to use. This function finds the SDKs that are present in
9 # the current Xcode.
10 function(find_darwin_sdk_dir var sdk_name)
11   set(DARWIN_${sdk_name}_CACHED_SYSROOT "" CACHE STRING "Darwin SDK path for SDK ${sdk_name}.")
12   set(DARWIN_PREFER_PUBLIC_SDK OFF CACHE BOOL "Prefer Darwin public SDK, even when an internal SDK is present.")
14   if(DARWIN_${sdk_name}_CACHED_SYSROOT)
15     set(${var} ${DARWIN_${sdk_name}_CACHED_SYSROOT} PARENT_SCOPE)
16     return()
17   endif()
18   if(NOT DARWIN_PREFER_PUBLIC_SDK)
19     # Let's first try the internal SDK, otherwise use the public SDK.
20     execute_process(
21       COMMAND xcrun --sdk ${sdk_name}.internal --show-sdk-path
22       RESULT_VARIABLE result_process
23       OUTPUT_VARIABLE var_internal
24       OUTPUT_STRIP_TRAILING_WHITESPACE
25       ERROR_FILE /dev/null
26     )
27   endif()
28   if((NOT result_process EQUAL 0) OR "" STREQUAL "${var_internal}")
29     execute_process(
30       COMMAND xcrun --sdk ${sdk_name} --show-sdk-path
31       RESULT_VARIABLE result_process
32       OUTPUT_VARIABLE var_internal
33       OUTPUT_STRIP_TRAILING_WHITESPACE
34       ERROR_FILE /dev/null
35     )
36   else()
37     set(${var}_INTERNAL ${var_internal} PARENT_SCOPE)
38   endif()
39   if(result_process EQUAL 0)
40     set(${var} ${var_internal} PARENT_SCOPE)
41   endif()
42   message(STATUS "Checking DARWIN_${sdk_name}_SYSROOT - '${var_internal}'")
43   set(DARWIN_${sdk_name}_CACHED_SYSROOT ${var_internal} CACHE STRING "Darwin SDK path for SDK ${sdk_name}." FORCE)
44 endfunction()
46 function(find_darwin_sdk_version var sdk_name)
47   if (DARWIN_${sdk_name}_OVERRIDE_SDK_VERSION)
48     message(WARNING "Overriding ${sdk_name} SDK version to ${DARWIN_${sdk_name}_OVERRIDE_SDK_VERSION}")
49     set(${var} "${DARWIN_${sdk_name}_OVERRIDE_SDK_VERSION}" PARENT_SCOPE)
50     return()
51   endif()
52   set(result_process 1)
53   if(NOT DARWIN_PREFER_PUBLIC_SDK)
54     # Let's first try the internal SDK, otherwise use the public SDK.
55     execute_process(
56       COMMAND xcrun --sdk ${sdk_name}.internal --show-sdk-version
57       RESULT_VARIABLE result_process
58       OUTPUT_VARIABLE var_internal
59       OUTPUT_STRIP_TRAILING_WHITESPACE
60       ERROR_FILE /dev/null
61     )
62   endif()
63   if((NOT ${result_process} EQUAL 0) OR "" STREQUAL "${var_internal}")
64     execute_process(
65       COMMAND xcrun --sdk ${sdk_name} --show-sdk-version
66       RESULT_VARIABLE result_process
67       OUTPUT_VARIABLE var_internal
68       OUTPUT_STRIP_TRAILING_WHITESPACE
69       ERROR_FILE /dev/null
70     )
71   endif()
72   if(NOT result_process EQUAL 0)
73     message(FATAL_ERROR
74       "Failed to determine SDK version for \"${sdk_name}\" SDK")
75   endif()
76   # Check reported version looks sane.
77   if (NOT "${var_internal}" MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+)?$")
78     message(FATAL_ERROR
79       "Reported SDK version \"${var_internal}\" does not look like a version")
80   endif()
81   set(${var} ${var_internal} PARENT_SCOPE)
82 endfunction()
84 # There isn't a clear mapping of what architectures are supported with a given
85 # target platform, but ld's version output does list the architectures it can
86 # link for.
87 function(darwin_get_toolchain_supported_archs output_var)
88   execute_process(
89     COMMAND "${CMAKE_LINKER}" -v
90     ERROR_VARIABLE LINKER_VERSION)
92   string(REGEX MATCH "configured to support archs: ([^\n]+)"
93          ARCHES_MATCHED "${LINKER_VERSION}")
94   if(ARCHES_MATCHED)
95     set(ARCHES "${CMAKE_MATCH_1}")
96     message(STATUS "Got ld supported ARCHES: ${ARCHES}")
97     string(REPLACE " " ";" ARCHES ${ARCHES})
98   else()
99     # If auto-detecting fails, fall back to a default set
100     message(WARNING "Detecting supported architectures from 'ld -v' failed. Returning default set.")
101     set(ARCHES "i386;x86_64;armv7;armv7s;arm64")
102   endif()
103   
104   set(${output_var} ${ARCHES} PARENT_SCOPE)
105 endfunction()
107 # This function takes an OS and a list of architectures and identifies the
108 # subset of the architectures list that the installed toolchain can target.
109 function(darwin_test_archs os valid_archs)
110   if(${valid_archs})
111     message(STATUS "Using cached valid architectures for ${os}.")
112     return()
113   endif()
115   set(archs ${ARGN})
116   if(NOT TEST_COMPILE_ONLY)
117     message(STATUS "Finding valid architectures for ${os}...")
118     set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c)
119     file(WRITE ${SIMPLE_C} "#include <stdio.h>\nint main(void) { printf(__FILE__); return 0; }\n")
121     set(os_linker_flags)
122     foreach(flag ${DARWIN_${os}_LINK_FLAGS})
123       set(os_linker_flags "${os_linker_flags} ${flag}")
124     endforeach()
126     # Disable building for i386 for macOS SDK >= 10.15. The SDK doesn't support
127     # linking for i386 and the corresponding OS doesn't allow running macOS i386
128     # binaries.
129     if ("${os}" STREQUAL "osx")
130       find_darwin_sdk_version(macosx_sdk_version "macosx")
131       if ("${macosx_sdk_version}" VERSION_GREATER 10.15 OR "${macosx_sdk_version}" VERSION_EQUAL 10.15)
132         message(STATUS "Disabling i386 slice for ${valid_archs}")
133         list(REMOVE_ITEM archs "i386")
134       endif()
135     endif()
136   endif()
138   # The simple program will build for x86_64h on the simulator because it is 
139   # compatible with x86_64 libraries (mostly), but since x86_64h isn't actually
140   # a valid or useful architecture for the iOS simulator we should drop it.
141   if(${os} MATCHES "^(iossim|tvossim|watchossim)$")
142     list(REMOVE_ITEM archs "x86_64h")
143   endif()
145   if(${os} MATCHES "iossim")
146     message(STATUS "Disabling i386 slice for iossim")
147     list(REMOVE_ITEM archs "i386")
148   endif()
150   if(${os} MATCHES "^ios$")
151     message(STATUS "Disabling sanitizers armv7* slice for ios")
152     list(FILTER archs EXCLUDE REGEX "armv7.*")
153   endif()
155   set(working_archs)
156   foreach(arch ${archs})
157    
158     set(arch_linker_flags "-arch ${arch} ${os_linker_flags}")
159     if(TEST_COMPILE_ONLY)
160       # `-w` is used to surpress compiler warnings which `try_compile_only()` treats as an error.
161       try_compile_only(CAN_TARGET_${os}_${arch} FLAGS -v -arch ${arch} ${DARWIN_${os}_CFLAGS} -w)
162     else()
163       set(SAVED_CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
164       set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${arch_linker_flags}")
165       try_compile(CAN_TARGET_${os}_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_C}
166                   COMPILE_DEFINITIONS "-v -arch ${arch}" ${DARWIN_${os}_CFLAGS}
167                   OUTPUT_VARIABLE TEST_OUTPUT)
168       set(CMAKE_EXE_LINKER_FLAGS ${SAVED_CMAKE_EXE_LINKER_FLAGS})
169     endif()
170     if(${CAN_TARGET_${os}_${arch}})
171       list(APPEND working_archs ${arch})
172     else()
173       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
174         "Testing compiler for supporting ${os}-${arch}:\n"
175         "${TEST_OUTPUT}\n")
176     endif()
177   endforeach()
178   set(${valid_archs} ${working_archs}
179     CACHE STRING "List of valid architectures for platform ${os}." FORCE)
180 endfunction()
182 # This function checks the host cputype/cpusubtype to filter supported
183 # architecture for the host OS. This is used to determine which tests are
184 # available for the host.
185 function(darwin_filter_host_archs input output)
186   list_intersect(tmp_var DARWIN_osx_ARCHS ${input})
187   execute_process(
188     COMMAND sysctl hw.cputype
189     OUTPUT_VARIABLE CPUTYPE)
190   string(REGEX MATCH "hw.cputype: ([0-9]*)"
191          CPUTYPE_MATCHED "${CPUTYPE}")
192   set(ARM_HOST Off)
193   if(CPUTYPE_MATCHED)
194     # ARM cputype is (0x01000000 | 12) and X86(_64) is always 7.
195     if(${CMAKE_MATCH_1} GREATER 11)
196       set(ARM_HOST On)
197     endif()
198   endif()
200   if(ARM_HOST)
201     list(REMOVE_ITEM tmp_var i386)
202     list(REMOVE_ITEM tmp_var x86_64)
203     list(REMOVE_ITEM tmp_var x86_64h)
204   else()
205     list(REMOVE_ITEM tmp_var arm64)
206     list(REMOVE_ITEM tmp_var arm64e)
207     execute_process(
208       COMMAND sysctl hw.cpusubtype
209       OUTPUT_VARIABLE SUBTYPE)
210     string(REGEX MATCH "hw.cpusubtype: ([0-9]*)"
211            SUBTYPE_MATCHED "${SUBTYPE}")
213     set(HASWELL_SUPPORTED Off)
214     if(SUBTYPE_MATCHED)
215       if(${CMAKE_MATCH_1} GREATER 7)
216         set(HASWELL_SUPPORTED On)
217       endif()
218     endif()
219     if(NOT HASWELL_SUPPORTED)
220       list(REMOVE_ITEM tmp_var x86_64h)
221     endif()
222   endif()
224   set(${output} ${tmp_var} PARENT_SCOPE)
225 endfunction()
227 # Read and process the exclude file into a list of symbols
228 function(darwin_read_list_from_file output_var file)
229   if(EXISTS ${file})
230     file(READ ${file} EXCLUDES)
231     string(REPLACE "\n" ";" EXCLUDES ${EXCLUDES})
232     set(${output_var} ${EXCLUDES} PARENT_SCOPE)
233   endif()
234 endfunction()
236 # this function takes an OS, architecture and minimum version and provides a
237 # list of builtin functions to exclude
238 function(darwin_find_excluded_builtins_list output_var)
239   cmake_parse_arguments(LIB
240     ""
241     "OS;ARCH;MIN_VERSION"
242     ""
243     ${ARGN})
245   if(NOT LIB_OS OR NOT LIB_ARCH)
246     message(FATAL_ERROR "Must specify OS and ARCH to darwin_find_excluded_builtins_list!")
247   endif()
249   darwin_read_list_from_file(${LIB_OS}_BUILTINS
250     ${DARWIN_EXCLUDE_DIR}/${LIB_OS}.txt)
251   darwin_read_list_from_file(${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS
252     ${DARWIN_EXCLUDE_DIR}/${LIB_OS}-${LIB_ARCH}.txt)
254   if(LIB_MIN_VERSION)
255     file(GLOB builtin_lists ${DARWIN_EXCLUDE_DIR}/${LIB_OS}*-${LIB_ARCH}.txt)
256     foreach(builtin_list ${builtin_lists})
257       string(REGEX MATCH "${LIB_OS}([0-9\\.]*)-${LIB_ARCH}.txt" VERSION_MATCHED "${builtin_list}")
258       if (VERSION_MATCHED AND NOT CMAKE_MATCH_1 VERSION_LESS LIB_MIN_VERSION)
259         if(NOT smallest_version)
260           set(smallest_version ${CMAKE_MATCH_1})
261         elseif(CMAKE_MATCH_1 VERSION_LESS smallest_version)
262           set(smallest_version ${CMAKE_MATCH_1})
263         endif()
264       endif()
265     endforeach()
267     if(smallest_version)
268       darwin_read_list_from_file(${LIB_ARCH}_${LIB_OS}_BUILTINS
269         ${DARWIN_EXCLUDE_DIR}/${LIB_OS}${smallest_version}-${LIB_ARCH}.txt)
270     endif()
271   endif()
272   
273   set(${output_var}
274       ${${LIB_ARCH}_${LIB_OS}_BUILTINS}
275       ${${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS}
276       ${${LIB_OS}_BUILTINS} PARENT_SCOPE)
277 endfunction()
279 # adds a single builtin library for a single OS & ARCH
280 macro(darwin_add_builtin_library name suffix)
281   cmake_parse_arguments(LIB
282     ""
283     "PARENT_TARGET;OS;ARCH"
284     "SOURCES;CFLAGS;DEFS;INCLUDE_DIRS"
285     ${ARGN})
286   set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}")
287   add_library(${libname} STATIC ${LIB_SOURCES})
288   if(DARWIN_${LIB_OS}_SYSROOT)
289     set(sysroot_flag -isysroot ${DARWIN_${LIB_OS}_SYSROOT})
290   endif()
292   # Make a copy of the compilation flags.
293   set(builtin_cflags ${LIB_CFLAGS})
295   # Strip out any inappropriate flags for the target.
296   if("${LIB_ARCH}" MATCHES "^(armv7|armv7k|armv7s)$")
297     set(builtin_cflags "")
298     foreach(cflag "${LIB_CFLAGS}")
299       string(REPLACE "-fomit-frame-pointer" "" cflag "${cflag}")
300       list(APPEND builtin_cflags ${cflag})
301     endforeach(cflag)
302   endif()
304   if ("${LIB_OS}" MATCHES ".*sim$")
305     # Pass an explicit -simulator environment to the -target option to ensure
306     # that we don't rely on the architecture to infer whether we're building
307     # for the simulator.
308     string(REGEX REPLACE "sim" "" base_os "${LIB_OS}")
309     list(APPEND builtin_cflags
310          -target "${LIB_ARCH}-apple-${base_os}${DARWIN_${LIBOS}_BUILTIN_MIN_VER}-simulator")
311   endif()
313   if ("${COMPILER_RT_ENABLE_MACCATALYST}" AND
314       "${LIB_OS}" MATCHES "^osx$")
315     # Build the macOS builtins with Mac Catalyst support.
316     list(APPEND builtin_cflags
317       "SHELL:-target ${LIB_ARCH}-apple-macos${DARWIN_osx_BUILTIN_MIN_VER} -darwin-target-variant ${LIB_ARCH}-apple-ios13.1-macabi")
318   endif()
320   set_target_compile_flags(${libname}
321     ${sysroot_flag}
322     ${DARWIN_${LIB_OS}_BUILTIN_MIN_VER_FLAG}
323     ${builtin_cflags})
324   target_include_directories(${libname}
325     PRIVATE ${LIB_INCLUDE_DIRS})
326   set_property(TARGET ${libname} APPEND PROPERTY
327       COMPILE_DEFINITIONS ${LIB_DEFS})
328   set_target_properties(${libname} PROPERTIES
329       OUTPUT_NAME ${libname}${COMPILER_RT_OS_SUFFIX})
330   set_target_properties(${libname} PROPERTIES
331     OSX_ARCHITECTURES ${LIB_ARCH})
333   if(LIB_PARENT_TARGET)
334     add_dependencies(${LIB_PARENT_TARGET} ${libname})
335   endif()
337   list(APPEND ${LIB_OS}_${suffix}_libs ${libname})
338   list(APPEND ${LIB_OS}_${suffix}_lipo_flags -arch ${arch} $<TARGET_FILE:${libname}>)
339   set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
340 endmacro()
342 function(darwin_lipo_libs name)
343   cmake_parse_arguments(LIB
344     ""
345     "PARENT_TARGET;OUTPUT_DIR;INSTALL_DIR"
346     "LIPO_FLAGS;DEPENDS"
347     ${ARGN})
348   if(LIB_DEPENDS AND LIB_LIPO_FLAGS)
349     add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a
350       COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
351       COMMAND ${CMAKE_LIPO} -output
352               ${LIB_OUTPUT_DIR}/lib${name}.a
353               -create ${LIB_LIPO_FLAGS}
354       DEPENDS ${LIB_DEPENDS}
355       )
356     add_custom_target(${name}
357       DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)
358     set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc")
359     add_dependencies(${LIB_PARENT_TARGET} ${name})
361     if(CMAKE_CONFIGURATION_TYPES)
362       set(install_component ${LIB_PARENT_TARGET})
363     else()
364       set(install_component ${name})
365     endif()
366     install(FILES ${LIB_OUTPUT_DIR}/lib${name}.a
367       DESTINATION ${LIB_INSTALL_DIR}
368       COMPONENT ${install_component})
369     add_compiler_rt_install_targets(${name} PARENT_TARGET ${LIB_PARENT_TARGET})
370   else()
371     message(WARNING "Not generating lipo target for ${name} because no input libraries exist.")
372   endif()
373 endfunction()
375 # Filter the list of builtin sources for Darwin, then delegate to the generic
376 # filtering.
378 # `exclude_or_include` must be one of:
379 #  - EXCLUDE: remove every item whose name (w/o extension) matches a name in
380 #    `excluded_list`.
381 #  - INCLUDE: keep only items whose name (w/o extension) matches something
382 #    in `excluded_list`.
383 function(darwin_filter_builtin_sources output_var name exclude_or_include excluded_list)
384   if(exclude_or_include STREQUAL "EXCLUDE")
385     set(filter_action GREATER)
386     set(filter_value -1)
387   elseif(exclude_or_include STREQUAL "INCLUDE")
388     set(filter_action LESS)
389     set(filter_value 0)
390   else()
391     message(FATAL_ERROR "darwin_filter_builtin_sources called without EXCLUDE|INCLUDE")
392   endif()
394   set(intermediate ${ARGN})
395   foreach(_file ${intermediate})
396     get_filename_component(_name_we ${_file} NAME_WE)
397     list(FIND ${excluded_list} ${_name_we} _found)
398     if(_found ${filter_action} ${filter_value})
399       list(REMOVE_ITEM intermediate ${_file})
400     endif()
401   endforeach()
403   filter_builtin_sources(intermediate ${name})
404   set(${output_var} ${intermediate} PARENT_SCOPE)
405 endfunction()
407 # Generates builtin libraries for all operating systems specified in ARGN. Each
408 # OS library is constructed by lipo-ing together single-architecture libraries.
409 macro(darwin_add_builtin_libraries)
410   set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes)
412   set(CFLAGS -fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer)
413   set(CMAKE_C_FLAGS "")
414   set(CMAKE_CXX_FLAGS "")
415   set(CMAKE_ASM_FLAGS "")
417   append_list_if(COMPILER_RT_HAS_ASM_LSE -DHAS_ASM_LSE CFLAGS)
419   set(PROFILE_SOURCES ../profile/InstrProfiling.c
420                       ../profile/InstrProfilingBuffer.c
421                       ../profile/InstrProfilingPlatformDarwin.c
422                       ../profile/InstrProfilingWriter.c
423                       ../profile/InstrProfilingInternal.c
424                       ../profile/InstrProfilingVersionVar.c)
425   foreach (os ${ARGN})
426     set(macosx_sdk_version 99999)
427     if ("${os}" STREQUAL "osx")
428       find_darwin_sdk_version(macosx_sdk_version "macosx")
429     endif()
430     add_security_warnings(CFLAGS ${macosx_sdk_version})
432     list_intersect(DARWIN_BUILTIN_ARCHS DARWIN_${os}_BUILTIN_ARCHS BUILTIN_SUPPORTED_ARCH)
434     if((arm64 IN_LIST DARWIN_BUILTIN_ARCHS OR arm64e IN_LIST DARWIN_BUILTIN_ARCHS) AND NOT TARGET lse_builtin_symlinks)
435       add_custom_target(
436         lse_builtin_symlinks
437         BYPRODUCTS ${lse_builtins}
438         ${arm64_lse_commands}
439       )
441       set(deps_arm64 lse_builtin_symlinks)
442       set(deps_arm64e lse_builtin_symlinks)
443     endif()
445     foreach (arch ${DARWIN_BUILTIN_ARCHS})
446       darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
447                               OS ${os}
448                               ARCH ${arch}
449                               MIN_VERSION ${DARWIN_${os}_BUILTIN_MIN_VER})
451       darwin_filter_builtin_sources(filtered_sources
452         ${os}_${arch}
453         EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS
454         ${${arch}_SOURCES})
456       darwin_add_builtin_library(clang_rt builtins
457                               OS ${os}
458                               ARCH ${arch}
459                               DEPS ${deps_${arch}}
460                               SOURCES ${filtered_sources}
461                               CFLAGS ${CFLAGS} -arch ${arch}
462                               PARENT_TARGET builtins)
463     endforeach()
465     # Don't build cc_kext libraries for simulator platforms
466     if(NOT DARWIN_${os}_SKIP_CC_KEXT)
467       foreach (arch ${DARWIN_BUILTIN_ARCHS})
468         # By not specifying MIN_VERSION this only reads the OS and OS-arch lists.
469         # We don't want to filter out the builtins that are present in libSystem
470         # because kexts can't link libSystem.
471         darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
472                               OS ${os}
473                               ARCH ${arch})
475         darwin_filter_builtin_sources(filtered_sources
476           cc_kext_${os}_${arch}
477           EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS
478           ${${arch}_SOURCES})
480         # In addition to the builtins cc_kext includes some profile sources
481         darwin_add_builtin_library(clang_rt cc_kext
482                                 OS ${os}
483                                 ARCH ${arch}
484                                 DEPS ${deps_${arch}}
485                                 SOURCES ${filtered_sources} ${PROFILE_SOURCES}
486                                 CFLAGS ${CFLAGS} -arch ${arch} -mkernel
487                                 DEFS KERNEL_USE
488                                 INCLUDE_DIRS ../../include
489                                 PARENT_TARGET builtins)
490       endforeach()
491       set(archive_name clang_rt.cc_kext_${os})
492       if(${os} STREQUAL "osx")
493         set(archive_name clang_rt.cc_kext)
494       endif()
495       darwin_lipo_libs(${archive_name}
496                       PARENT_TARGET builtins
497                       LIPO_FLAGS ${${os}_cc_kext_lipo_flags}
498                       DEPENDS ${${os}_cc_kext_libs}
499                       OUTPUT_DIR ${COMPILER_RT_OUTPUT_LIBRARY_DIR}
500                       INSTALL_DIR ${COMPILER_RT_INSTALL_LIBRARY_DIR})
501     endif()
502   endforeach()
504   foreach (os ${ARGN})
505     darwin_lipo_libs(clang_rt.${os}
506                      PARENT_TARGET builtins
507                      LIPO_FLAGS ${${os}_builtins_lipo_flags}
508                      DEPENDS ${${os}_builtins_libs}
509                      OUTPUT_DIR ${COMPILER_RT_OUTPUT_LIBRARY_DIR}
510                      INSTALL_DIR ${COMPILER_RT_INSTALL_LIBRARY_DIR})
511   endforeach()
512   darwin_add_embedded_builtin_libraries()
513 endmacro()
515 macro(darwin_add_embedded_builtin_libraries)
516   # this is a hacky opt-out. If you can't target both intel and arm
517   # architectures we bail here.
518   set(DARWIN_SOFT_FLOAT_ARCHS armv6m armv7m armv7em armv7)
519   set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7)
520   if(COMPILER_RT_SUPPORTED_ARCH MATCHES ".*armv.*")
521     list(FIND COMPILER_RT_SUPPORTED_ARCH i386 i386_idx)
522     if(i386_idx GREATER -1)
523       list(APPEND DARWIN_HARD_FLOAT_ARCHS i386)
524     endif()
526     list(FIND COMPILER_RT_SUPPORTED_ARCH x86_64 x86_64_idx)
527     if(x86_64_idx GREATER -1)
528       list(APPEND DARWIN_HARD_FLOAT_ARCHS x86_64)
529     endif()
531     set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded)
533     set(CFLAGS -Oz -Wall -fomit-frame-pointer -ffreestanding)
534     set(CMAKE_C_FLAGS "")
535     set(CMAKE_CXX_FLAGS "")
536     set(CMAKE_ASM_FLAGS "")
538     set(SOFT_FLOAT_FLAG -mfloat-abi=soft)
539     set(HARD_FLOAT_FLAG -mfloat-abi=hard)
541     set(ENABLE_PIC Off)
542     set(PIC_FLAG -fPIC)
543     set(STATIC_FLAG -static)
545     set(DARWIN_macho_embedded_ARCHS armv6m armv7m armv7em armv7 i386 x86_64)
547     set(DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR
548       ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/macho_embedded)
549     set(DARWIN_macho_embedded_LIBRARY_INSTALL_DIR
550       ${COMPILER_RT_INSTALL_LIBRARY_DIR}/macho_embedded)
551       
552     set(CFLAGS_armv7 -target thumbv7-apple-darwin-eabi)
553     set(CFLAGS_i386 -march=pentium)
555     darwin_read_list_from_file(common_FUNCTIONS ${MACHO_SYM_DIR}/common.txt)
556     darwin_read_list_from_file(thumb2_FUNCTIONS ${MACHO_SYM_DIR}/thumb2.txt)
557     darwin_read_list_from_file(thumb2_64_FUNCTIONS ${MACHO_SYM_DIR}/thumb2-64.txt)
558     darwin_read_list_from_file(arm_FUNCTIONS ${MACHO_SYM_DIR}/arm.txt)
559     darwin_read_list_from_file(i386_FUNCTIONS ${MACHO_SYM_DIR}/i386.txt)
562     set(armv6m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS})
563     set(armv7m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
564     set(armv7em_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
565     set(armv7_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS} ${thumb2_64_FUNCTIONS})
566     set(i386_FUNCTIONS ${common_FUNCTIONS} ${i386_FUNCTIONS})
567     set(x86_64_FUNCTIONS ${common_FUNCTIONS})
569     foreach(arch ${DARWIN_macho_embedded_ARCHS})
570       darwin_filter_builtin_sources(${arch}_filtered_sources
571         macho_embedded_${arch}
572         INCLUDE ${arch}_FUNCTIONS
573         ${${arch}_SOURCES})
574       if(NOT ${arch}_filtered_sources)
575         message(WARNING "${arch}_SOURCES: ${${arch}_SOURCES}")
576         message(WARNING "${arch}_FUNCTIONS: ${${arch}_FUNCTIONS}")
577         message(FATAL_ERROR "Empty filtered sources!")
578       endif()
579     endforeach()
581     foreach(float_type SOFT HARD)
582       foreach(type PIC STATIC)
583         string(TOLOWER "${float_type}_${type}" lib_suffix)
584         foreach(arch ${DARWIN_${float_type}_FLOAT_ARCHS})
585           set(DARWIN_macho_embedded_SYSROOT ${DARWIN_osx_SYSROOT})
586           set(float_flag)
587           if(${arch} MATCHES "^arm")
588             # x86 targets are hard float by default, but the complain about the
589             # float ABI flag, so don't pass it unless we're targeting arm.
590             set(float_flag ${${float_type}_FLOAT_FLAG})
591           endif()
592           darwin_add_builtin_library(clang_rt ${lib_suffix}
593                                 OS macho_embedded
594                                 ARCH ${arch}
595                                 SOURCES ${${arch}_filtered_sources}
596                                 CFLAGS ${CFLAGS} -arch ${arch} ${${type}_FLAG} ${float_flag} ${CFLAGS_${arch}}
597                                 PARENT_TARGET builtins)
598         endforeach()
599         foreach(lib ${macho_embedded_${lib_suffix}_libs})
600           set_target_properties(${lib} PROPERTIES LINKER_LANGUAGE C)
601         endforeach()
602         darwin_lipo_libs(clang_rt.${lib_suffix}
603                       PARENT_TARGET builtins
604                       LIPO_FLAGS ${macho_embedded_${lib_suffix}_lipo_flags}
605                       DEPENDS ${macho_embedded_${lib_suffix}_libs}
606                       OUTPUT_DIR ${DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR}
607                       INSTALL_DIR ${DARWIN_macho_embedded_LIBRARY_INSTALL_DIR})
608       endforeach()
609     endforeach()
610   endif()
611 endmacro()