xref: /aosp_15_r20/external/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robotinclude(CMakeParseArguments)
2*7c3d14c8STreehugger Robot
3*7c3d14c8STreehugger Robot# On OS X SDKs can be installed anywhere on the base system and xcode-select can
4*7c3d14c8STreehugger Robot# set the default Xcode to use. This function finds the SDKs that are present in
5*7c3d14c8STreehugger Robot# the current Xcode.
6*7c3d14c8STreehugger Robotfunction(find_darwin_sdk_dir var sdk_name)
7*7c3d14c8STreehugger Robot  # Let's first try the internal SDK, otherwise use the public SDK.
8*7c3d14c8STreehugger Robot  execute_process(
9*7c3d14c8STreehugger Robot    COMMAND xcodebuild -version -sdk ${sdk_name}.internal Path
10*7c3d14c8STreehugger Robot    OUTPUT_VARIABLE var_internal
11*7c3d14c8STreehugger Robot    OUTPUT_STRIP_TRAILING_WHITESPACE
12*7c3d14c8STreehugger Robot    ERROR_FILE /dev/null
13*7c3d14c8STreehugger Robot  )
14*7c3d14c8STreehugger Robot  if("" STREQUAL "${var_internal}")
15*7c3d14c8STreehugger Robot    execute_process(
16*7c3d14c8STreehugger Robot      COMMAND xcodebuild -version -sdk ${sdk_name} Path
17*7c3d14c8STreehugger Robot      OUTPUT_VARIABLE var_internal
18*7c3d14c8STreehugger Robot      OUTPUT_STRIP_TRAILING_WHITESPACE
19*7c3d14c8STreehugger Robot      ERROR_FILE /dev/null
20*7c3d14c8STreehugger Robot    )
21*7c3d14c8STreehugger Robot  else()
22*7c3d14c8STreehugger Robot    set(${var}_INTERNAL ${var_internal} PARENT_SCOPE)
23*7c3d14c8STreehugger Robot  endif()
24*7c3d14c8STreehugger Robot  set(${var} ${var_internal} PARENT_SCOPE)
25*7c3d14c8STreehugger Robotendfunction()
26*7c3d14c8STreehugger Robot
27*7c3d14c8STreehugger Robot# There isn't a clear mapping of what architectures are supported with a given
28*7c3d14c8STreehugger Robot# target platform, but ld's version output does list the architectures it can
29*7c3d14c8STreehugger Robot# link for.
30*7c3d14c8STreehugger Robotfunction(darwin_get_toolchain_supported_archs output_var)
31*7c3d14c8STreehugger Robot  execute_process(
32*7c3d14c8STreehugger Robot    COMMAND ld -v
33*7c3d14c8STreehugger Robot    ERROR_VARIABLE LINKER_VERSION)
34*7c3d14c8STreehugger Robot
35*7c3d14c8STreehugger Robot  string(REGEX MATCH "configured to support archs: ([^\n]+)"
36*7c3d14c8STreehugger Robot         ARCHES_MATCHED "${LINKER_VERSION}")
37*7c3d14c8STreehugger Robot  if(ARCHES_MATCHED)
38*7c3d14c8STreehugger Robot    set(ARCHES "${CMAKE_MATCH_1}")
39*7c3d14c8STreehugger Robot    message(STATUS "Got ld supported ARCHES: ${ARCHES}")
40*7c3d14c8STreehugger Robot    string(REPLACE " " ";" ARCHES ${ARCHES})
41*7c3d14c8STreehugger Robot  else()
42*7c3d14c8STreehugger Robot    # If auto-detecting fails, fall back to a default set
43*7c3d14c8STreehugger Robot    message(WARNING "Detecting supported architectures from 'ld -v' failed. Returning default set.")
44*7c3d14c8STreehugger Robot    set(ARCHES "i386;x86_64;armv7;armv7s;arm64")
45*7c3d14c8STreehugger Robot  endif()
46*7c3d14c8STreehugger Robot
47*7c3d14c8STreehugger Robot  set(${output_var} ${ARCHES} PARENT_SCOPE)
48*7c3d14c8STreehugger Robotendfunction()
49*7c3d14c8STreehugger Robot
50*7c3d14c8STreehugger Robot# This function takes an OS and a list of architectures and identifies the
51*7c3d14c8STreehugger Robot# subset of the architectures list that the installed toolchain can target.
52*7c3d14c8STreehugger Robotfunction(darwin_test_archs os valid_archs)
53*7c3d14c8STreehugger Robot  if(${valid_archs})
54*7c3d14c8STreehugger Robot    message(STATUS "Using cached valid architectures for ${os}.")
55*7c3d14c8STreehugger Robot    return()
56*7c3d14c8STreehugger Robot  endif()
57*7c3d14c8STreehugger Robot
58*7c3d14c8STreehugger Robot  set(archs ${ARGN})
59*7c3d14c8STreehugger Robot  if(NOT TEST_COMPILE_ONLY)
60*7c3d14c8STreehugger Robot    message(STATUS "Finding valid architectures for ${os}...")
61*7c3d14c8STreehugger Robot    set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c)
62*7c3d14c8STreehugger Robot    file(WRITE ${SIMPLE_C} "#include <stdio.h>\nint main() { printf(__FILE__); return 0; }\n")
63*7c3d14c8STreehugger Robot
64*7c3d14c8STreehugger Robot    set(os_linker_flags)
65*7c3d14c8STreehugger Robot    foreach(flag ${DARWIN_${os}_LINKFLAGS})
66*7c3d14c8STreehugger Robot      set(os_linker_flags "${os_linker_flags} ${flag}")
67*7c3d14c8STreehugger Robot    endforeach()
68*7c3d14c8STreehugger Robot  endif()
69*7c3d14c8STreehugger Robot
70*7c3d14c8STreehugger Robot  # The simple program will build for x86_64h on the simulator because it is
71*7c3d14c8STreehugger Robot  # compatible with x86_64 libraries (mostly), but since x86_64h isn't actually
72*7c3d14c8STreehugger Robot  # a valid or useful architecture for the iOS simulator we should drop it.
73*7c3d14c8STreehugger Robot  if(${os} MATCHES "^(iossim|tvossim|watchossim)$")
74*7c3d14c8STreehugger Robot    list(REMOVE_ITEM archs "x86_64h")
75*7c3d14c8STreehugger Robot  endif()
76*7c3d14c8STreehugger Robot
77*7c3d14c8STreehugger Robot  set(working_archs)
78*7c3d14c8STreehugger Robot  foreach(arch ${archs})
79*7c3d14c8STreehugger Robot
80*7c3d14c8STreehugger Robot    set(arch_linker_flags "-arch ${arch} ${os_linker_flags}")
81*7c3d14c8STreehugger Robot    if(TEST_COMPILE_ONLY)
82*7c3d14c8STreehugger Robot      try_compile_only(CAN_TARGET_${os}_${arch} -v -arch ${arch} ${DARWIN_${os}_CFLAGS})
83*7c3d14c8STreehugger Robot    else()
84*7c3d14c8STreehugger Robot      try_compile(CAN_TARGET_${os}_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_C}
85*7c3d14c8STreehugger Robot                  COMPILE_DEFINITIONS "-v -arch ${arch}" ${DARWIN_${os}_CFLAGS}
86*7c3d14c8STreehugger Robot                  CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${arch_linker_flags}"
87*7c3d14c8STreehugger Robot                  OUTPUT_VARIABLE TEST_OUTPUT)
88*7c3d14c8STreehugger Robot    endif()
89*7c3d14c8STreehugger Robot    if(${CAN_TARGET_${os}_${arch}})
90*7c3d14c8STreehugger Robot      list(APPEND working_archs ${arch})
91*7c3d14c8STreehugger Robot    else()
92*7c3d14c8STreehugger Robot      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
93*7c3d14c8STreehugger Robot        "Testing compiler for supporting ${os}-${arch}:\n"
94*7c3d14c8STreehugger Robot        "${TEST_OUTPUT}\n")
95*7c3d14c8STreehugger Robot    endif()
96*7c3d14c8STreehugger Robot  endforeach()
97*7c3d14c8STreehugger Robot  set(${valid_archs} ${working_archs}
98*7c3d14c8STreehugger Robot    CACHE STRING "List of valid architectures for platform ${os}.")
99*7c3d14c8STreehugger Robotendfunction()
100*7c3d14c8STreehugger Robot
101*7c3d14c8STreehugger Robot# This function checks the host cpusubtype to see if it is post-haswell. Haswell
102*7c3d14c8STreehugger Robot# and later machines can run x86_64h binaries. Haswell is cpusubtype 8.
103*7c3d14c8STreehugger Robotfunction(darwin_filter_host_archs input output)
104*7c3d14c8STreehugger Robot  list_intersect(tmp_var DARWIN_osx_ARCHS ${input})
105*7c3d14c8STreehugger Robot  execute_process(
106*7c3d14c8STreehugger Robot    COMMAND sysctl hw.cpusubtype
107*7c3d14c8STreehugger Robot    OUTPUT_VARIABLE SUBTYPE)
108*7c3d14c8STreehugger Robot
109*7c3d14c8STreehugger Robot  string(REGEX MATCH "hw.cpusubtype: ([0-9]*)"
110*7c3d14c8STreehugger Robot         SUBTYPE_MATCHED "${SUBTYPE}")
111*7c3d14c8STreehugger Robot  set(HASWELL_SUPPORTED Off)
112*7c3d14c8STreehugger Robot  if(SUBTYPE_MATCHED)
113*7c3d14c8STreehugger Robot    if(${CMAKE_MATCH_1} GREATER 7)
114*7c3d14c8STreehugger Robot      set(HASWELL_SUPPORTED On)
115*7c3d14c8STreehugger Robot    endif()
116*7c3d14c8STreehugger Robot  endif()
117*7c3d14c8STreehugger Robot  if(NOT HASWELL_SUPPORTED)
118*7c3d14c8STreehugger Robot    list(REMOVE_ITEM tmp_var x86_64h)
119*7c3d14c8STreehugger Robot  endif()
120*7c3d14c8STreehugger Robot  set(${output} ${tmp_var} PARENT_SCOPE)
121*7c3d14c8STreehugger Robotendfunction()
122*7c3d14c8STreehugger Robot
123*7c3d14c8STreehugger Robot# Read and process the exclude file into a list of symbols
124*7c3d14c8STreehugger Robotfunction(darwin_read_list_from_file output_var file)
125*7c3d14c8STreehugger Robot  if(EXISTS ${file})
126*7c3d14c8STreehugger Robot    file(READ ${file} EXCLUDES)
127*7c3d14c8STreehugger Robot    string(REPLACE "\n" ";" EXCLUDES ${EXCLUDES})
128*7c3d14c8STreehugger Robot    set(${output_var} ${EXCLUDES} PARENT_SCOPE)
129*7c3d14c8STreehugger Robot  endif()
130*7c3d14c8STreehugger Robotendfunction()
131*7c3d14c8STreehugger Robot
132*7c3d14c8STreehugger Robot# this function takes an OS, architecture and minimum version and provides a
133*7c3d14c8STreehugger Robot# list of builtin functions to exclude
134*7c3d14c8STreehugger Robotfunction(darwin_find_excluded_builtins_list output_var)
135*7c3d14c8STreehugger Robot  cmake_parse_arguments(LIB
136*7c3d14c8STreehugger Robot    ""
137*7c3d14c8STreehugger Robot    "OS;ARCH;MIN_VERSION"
138*7c3d14c8STreehugger Robot    ""
139*7c3d14c8STreehugger Robot    ${ARGN})
140*7c3d14c8STreehugger Robot
141*7c3d14c8STreehugger Robot  if(NOT LIB_OS OR NOT LIB_ARCH)
142*7c3d14c8STreehugger Robot    message(FATAL_ERROR "Must specify OS and ARCH to darwin_find_excluded_builtins_list!")
143*7c3d14c8STreehugger Robot  endif()
144*7c3d14c8STreehugger Robot
145*7c3d14c8STreehugger Robot  darwin_read_list_from_file(${LIB_OS}_BUILTINS
146*7c3d14c8STreehugger Robot    ${DARWIN_EXCLUDE_DIR}/${LIB_OS}.txt)
147*7c3d14c8STreehugger Robot  darwin_read_list_from_file(${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS
148*7c3d14c8STreehugger Robot    ${DARWIN_EXCLUDE_DIR}/${LIB_OS}-${LIB_ARCH}.txt)
149*7c3d14c8STreehugger Robot
150*7c3d14c8STreehugger Robot  if(LIB_MIN_VERSION)
151*7c3d14c8STreehugger Robot    file(GLOB builtin_lists ${DARWIN_EXCLUDE_DIR}/${LIB_OS}*-${LIB_ARCH}.txt)
152*7c3d14c8STreehugger Robot    foreach(builtin_list ${builtin_lists})
153*7c3d14c8STreehugger Robot      string(REGEX MATCH "${LIB_OS}([0-9\\.]*)-${LIB_ARCH}.txt" VERSION_MATCHED "${builtin_list}")
154*7c3d14c8STreehugger Robot      if (VERSION_MATCHED AND NOT CMAKE_MATCH_1 VERSION_LESS LIB_MIN_VERSION)
155*7c3d14c8STreehugger Robot        if(NOT smallest_version)
156*7c3d14c8STreehugger Robot          set(smallest_version ${CMAKE_MATCH_1})
157*7c3d14c8STreehugger Robot        elseif(CMAKE_MATCH_1 VERSION_LESS smallest_version)
158*7c3d14c8STreehugger Robot          set(smallest_version ${CMAKE_MATCH_1})
159*7c3d14c8STreehugger Robot        endif()
160*7c3d14c8STreehugger Robot      endif()
161*7c3d14c8STreehugger Robot    endforeach()
162*7c3d14c8STreehugger Robot
163*7c3d14c8STreehugger Robot    if(smallest_version)
164*7c3d14c8STreehugger Robot      darwin_read_list_from_file(${LIB_ARCH}_${LIB_OS}_BUILTINS
165*7c3d14c8STreehugger Robot        ${DARWIN_EXCLUDE_DIR}/${LIB_OS}${smallest_version}-${LIB_ARCH}.txt)
166*7c3d14c8STreehugger Robot    endif()
167*7c3d14c8STreehugger Robot  endif()
168*7c3d14c8STreehugger Robot
169*7c3d14c8STreehugger Robot  set(${output_var}
170*7c3d14c8STreehugger Robot      ${${LIB_ARCH}_${LIB_OS}_BUILTINS}
171*7c3d14c8STreehugger Robot      ${${LIB_OS}_${LIB_ARCH}_BASE_BUILTINS}
172*7c3d14c8STreehugger Robot      ${${LIB_OS}_BUILTINS} PARENT_SCOPE)
173*7c3d14c8STreehugger Robotendfunction()
174*7c3d14c8STreehugger Robot
175*7c3d14c8STreehugger Robot# adds a single builtin library for a single OS & ARCH
176*7c3d14c8STreehugger Robotmacro(darwin_add_builtin_library name suffix)
177*7c3d14c8STreehugger Robot  cmake_parse_arguments(LIB
178*7c3d14c8STreehugger Robot    ""
179*7c3d14c8STreehugger Robot    "PARENT_TARGET;OS;ARCH"
180*7c3d14c8STreehugger Robot    "SOURCES;CFLAGS;DEFS"
181*7c3d14c8STreehugger Robot    ${ARGN})
182*7c3d14c8STreehugger Robot  set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}")
183*7c3d14c8STreehugger Robot  add_library(${libname} STATIC ${LIB_SOURCES})
184*7c3d14c8STreehugger Robot  if(DARWIN_${LIB_OS}_SYSROOT)
185*7c3d14c8STreehugger Robot    set(sysroot_flag -isysroot ${DARWIN_${LIB_OS}_SYSROOT})
186*7c3d14c8STreehugger Robot  endif()
187*7c3d14c8STreehugger Robot  set_target_compile_flags(${libname}
188*7c3d14c8STreehugger Robot    ${sysroot_flag}
189*7c3d14c8STreehugger Robot    ${DARWIN_${LIB_OS}_BUILTIN_MIN_VER_FLAG}
190*7c3d14c8STreehugger Robot    ${LIB_CFLAGS})
191*7c3d14c8STreehugger Robot  set_property(TARGET ${libname} APPEND PROPERTY
192*7c3d14c8STreehugger Robot      COMPILE_DEFINITIONS ${LIB_DEFS})
193*7c3d14c8STreehugger Robot  set_target_properties(${libname} PROPERTIES
194*7c3d14c8STreehugger Robot      OUTPUT_NAME ${libname}${COMPILER_RT_OS_SUFFIX})
195*7c3d14c8STreehugger Robot  set_target_properties(${libname} PROPERTIES
196*7c3d14c8STreehugger Robot    OSX_ARCHITECTURES ${LIB_ARCH})
197*7c3d14c8STreehugger Robot
198*7c3d14c8STreehugger Robot  if(LIB_PARENT_TARGET)
199*7c3d14c8STreehugger Robot    add_dependencies(${LIB_PARENT_TARGET} ${libname})
200*7c3d14c8STreehugger Robot  endif()
201*7c3d14c8STreehugger Robot
202*7c3d14c8STreehugger Robot  list(APPEND ${LIB_OS}_${suffix}_libs ${libname})
203*7c3d14c8STreehugger Robot  list(APPEND ${LIB_OS}_${suffix}_lipo_flags -arch ${arch} $<TARGET_FILE:${libname}>)
204*7c3d14c8STreehugger Robotendmacro()
205*7c3d14c8STreehugger Robot
206*7c3d14c8STreehugger Robotfunction(darwin_lipo_libs name)
207*7c3d14c8STreehugger Robot  cmake_parse_arguments(LIB
208*7c3d14c8STreehugger Robot    ""
209*7c3d14c8STreehugger Robot    "PARENT_TARGET;OUTPUT_DIR;INSTALL_DIR"
210*7c3d14c8STreehugger Robot    "LIPO_FLAGS;DEPENDS"
211*7c3d14c8STreehugger Robot    ${ARGN})
212*7c3d14c8STreehugger Robot  if(LIB_DEPENDS AND LIB_LIPO_FLAGS)
213*7c3d14c8STreehugger Robot    add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a
214*7c3d14c8STreehugger Robot      COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
215*7c3d14c8STreehugger Robot      COMMAND lipo -output
216*7c3d14c8STreehugger Robot              ${LIB_OUTPUT_DIR}/lib${name}.a
217*7c3d14c8STreehugger Robot              -create ${LIB_LIPO_FLAGS}
218*7c3d14c8STreehugger Robot      DEPENDS ${LIB_DEPENDS}
219*7c3d14c8STreehugger Robot      )
220*7c3d14c8STreehugger Robot    add_custom_target(${name}
221*7c3d14c8STreehugger Robot      DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)
222*7c3d14c8STreehugger Robot    add_dependencies(${LIB_PARENT_TARGET} ${name})
223*7c3d14c8STreehugger Robot    install(FILES ${LIB_OUTPUT_DIR}/lib${name}.a
224*7c3d14c8STreehugger Robot      DESTINATION ${LIB_INSTALL_DIR})
225*7c3d14c8STreehugger Robot  else()
226*7c3d14c8STreehugger Robot    message(WARNING "Not generating lipo target for ${name} because no input libraries exist.")
227*7c3d14c8STreehugger Robot  endif()
228*7c3d14c8STreehugger Robotendfunction()
229*7c3d14c8STreehugger Robot
230*7c3d14c8STreehugger Robot# Filter out generic versions of routines that are re-implemented in
231*7c3d14c8STreehugger Robot# architecture specific manner.  This prevents multiple definitions of the
232*7c3d14c8STreehugger Robot# same symbols, making the symbol selection non-deterministic.
233*7c3d14c8STreehugger Robotfunction(darwin_filter_builtin_sources output_var exclude_or_include excluded_list)
234*7c3d14c8STreehugger Robot  if(exclude_or_include STREQUAL "EXCLUDE")
235*7c3d14c8STreehugger Robot    set(filter_action GREATER)
236*7c3d14c8STreehugger Robot    set(filter_value -1)
237*7c3d14c8STreehugger Robot  elseif(exclude_or_include STREQUAL "INCLUDE")
238*7c3d14c8STreehugger Robot    set(filter_action LESS)
239*7c3d14c8STreehugger Robot    set(filter_value 0)
240*7c3d14c8STreehugger Robot  else()
241*7c3d14c8STreehugger Robot    message(FATAL_ERROR "darwin_filter_builtin_sources called without EXCLUDE|INCLUDE")
242*7c3d14c8STreehugger Robot  endif()
243*7c3d14c8STreehugger Robot
244*7c3d14c8STreehugger Robot  set(intermediate ${ARGN})
245*7c3d14c8STreehugger Robot  foreach (_file ${intermediate})
246*7c3d14c8STreehugger Robot    get_filename_component(_name_we ${_file} NAME_WE)
247*7c3d14c8STreehugger Robot    list(FIND ${excluded_list} ${_name_we} _found)
248*7c3d14c8STreehugger Robot    if(_found ${filter_action} ${filter_value})
249*7c3d14c8STreehugger Robot      list(REMOVE_ITEM intermediate ${_file})
250*7c3d14c8STreehugger Robot    elseif(${_file} MATCHES ".*/.*\\.S" OR ${_file} MATCHES ".*/.*\\.c")
251*7c3d14c8STreehugger Robot      get_filename_component(_name ${_file} NAME)
252*7c3d14c8STreehugger Robot      string(REPLACE ".S" ".c" _cname "${_name}")
253*7c3d14c8STreehugger Robot      list(REMOVE_ITEM intermediate ${_cname})
254*7c3d14c8STreehugger Robot    endif ()
255*7c3d14c8STreehugger Robot  endforeach ()
256*7c3d14c8STreehugger Robot  set(${output_var} ${intermediate} PARENT_SCOPE)
257*7c3d14c8STreehugger Robotendfunction()
258*7c3d14c8STreehugger Robot
259*7c3d14c8STreehugger Robotfunction(darwin_add_eprintf_library)
260*7c3d14c8STreehugger Robot  cmake_parse_arguments(LIB
261*7c3d14c8STreehugger Robot    ""
262*7c3d14c8STreehugger Robot    ""
263*7c3d14c8STreehugger Robot    "CFLAGS"
264*7c3d14c8STreehugger Robot    ${ARGN})
265*7c3d14c8STreehugger Robot
266*7c3d14c8STreehugger Robot  add_library(clang_rt.eprintf STATIC eprintf.c)
267*7c3d14c8STreehugger Robot  set_target_compile_flags(clang_rt.eprintf
268*7c3d14c8STreehugger Robot    -isysroot ${DARWIN_osx_SYSROOT}
269*7c3d14c8STreehugger Robot    ${DARWIN_osx_BUILTIN_MIN_VER_FLAG}
270*7c3d14c8STreehugger Robot    -arch i386
271*7c3d14c8STreehugger Robot    ${LIB_CFLAGS})
272*7c3d14c8STreehugger Robot  set_target_properties(clang_rt.eprintf PROPERTIES
273*7c3d14c8STreehugger Robot      OUTPUT_NAME clang_rt.eprintf${COMPILER_RT_OS_SUFFIX})
274*7c3d14c8STreehugger Robot  set_target_properties(clang_rt.eprintf PROPERTIES
275*7c3d14c8STreehugger Robot    OSX_ARCHITECTURES i386)
276*7c3d14c8STreehugger Robot  add_dependencies(builtins clang_rt.eprintf)
277*7c3d14c8STreehugger Robot  set_target_properties(clang_rt.eprintf PROPERTIES
278*7c3d14c8STreehugger Robot        ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
279*7c3d14c8STreehugger Robot  install(TARGETS clang_rt.eprintf
280*7c3d14c8STreehugger Robot      ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
281*7c3d14c8STreehugger Robotendfunction()
282*7c3d14c8STreehugger Robot
283*7c3d14c8STreehugger Robot# Generates builtin libraries for all operating systems specified in ARGN. Each
284*7c3d14c8STreehugger Robot# OS library is constructed by lipo-ing together single-architecture libraries.
285*7c3d14c8STreehugger Robotmacro(darwin_add_builtin_libraries)
286*7c3d14c8STreehugger Robot  set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes)
287*7c3d14c8STreehugger Robot
288*7c3d14c8STreehugger Robot  set(CFLAGS "-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer")
289*7c3d14c8STreehugger Robot  set(CMAKE_C_FLAGS "")
290*7c3d14c8STreehugger Robot  set(CMAKE_CXX_FLAGS "")
291*7c3d14c8STreehugger Robot  set(CMAKE_ASM_FLAGS "")
292*7c3d14c8STreehugger Robot
293*7c3d14c8STreehugger Robot  set(PROFILE_SOURCES ../profile/InstrProfiling
294*7c3d14c8STreehugger Robot                      ../profile/InstrProfilingBuffer
295*7c3d14c8STreehugger Robot                      ../profile/InstrProfilingPlatformDarwin
296*7c3d14c8STreehugger Robot                      ../profile/InstrProfilingWriter)
297*7c3d14c8STreehugger Robot  foreach (os ${ARGN})
298*7c3d14c8STreehugger Robot    list_intersect(DARWIN_BUILTIN_ARCHS DARWIN_${os}_ARCHS BUILTIN_SUPPORTED_ARCH)
299*7c3d14c8STreehugger Robot    foreach (arch ${DARWIN_BUILTIN_ARCHS})
300*7c3d14c8STreehugger Robot      darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
301*7c3d14c8STreehugger Robot                              OS ${os}
302*7c3d14c8STreehugger Robot                              ARCH ${arch}
303*7c3d14c8STreehugger Robot                              MIN_VERSION ${DARWIN_${os}_BUILTIN_MIN_VER})
304*7c3d14c8STreehugger Robot
305*7c3d14c8STreehugger Robot      darwin_filter_builtin_sources(filtered_sources
306*7c3d14c8STreehugger Robot        EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS
307*7c3d14c8STreehugger Robot        ${${arch}_SOURCES})
308*7c3d14c8STreehugger Robot
309*7c3d14c8STreehugger Robot      darwin_add_builtin_library(clang_rt builtins
310*7c3d14c8STreehugger Robot                              OS ${os}
311*7c3d14c8STreehugger Robot                              ARCH ${arch}
312*7c3d14c8STreehugger Robot                              SOURCES ${filtered_sources}
313*7c3d14c8STreehugger Robot                              CFLAGS ${CFLAGS} -arch ${arch}
314*7c3d14c8STreehugger Robot                              PARENT_TARGET builtins)
315*7c3d14c8STreehugger Robot    endforeach()
316*7c3d14c8STreehugger Robot
317*7c3d14c8STreehugger Robot    # Don't build cc_kext libraries for simulator platforms
318*7c3d14c8STreehugger Robot    if(NOT DARWIN_${os}_SKIP_CC_KEXT)
319*7c3d14c8STreehugger Robot      foreach (arch ${DARWIN_BUILTIN_ARCHS})
320*7c3d14c8STreehugger Robot        # By not specifying MIN_VERSION this only reads the OS and OS-arch lists.
321*7c3d14c8STreehugger Robot        # We don't want to filter out the builtins that are present in libSystem
322*7c3d14c8STreehugger Robot        # because kexts can't link libSystem.
323*7c3d14c8STreehugger Robot        darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
324*7c3d14c8STreehugger Robot                              OS ${os}
325*7c3d14c8STreehugger Robot                              ARCH ${arch})
326*7c3d14c8STreehugger Robot
327*7c3d14c8STreehugger Robot        darwin_filter_builtin_sources(filtered_sources
328*7c3d14c8STreehugger Robot          EXCLUDE ${arch}_${os}_EXCLUDED_BUILTINS
329*7c3d14c8STreehugger Robot          ${${arch}_SOURCES})
330*7c3d14c8STreehugger Robot
331*7c3d14c8STreehugger Robot        # In addition to the builtins cc_kext includes some profile sources
332*7c3d14c8STreehugger Robot        darwin_add_builtin_library(clang_rt cc_kext
333*7c3d14c8STreehugger Robot                                OS ${os}
334*7c3d14c8STreehugger Robot                                ARCH ${arch}
335*7c3d14c8STreehugger Robot                                SOURCES ${filtered_sources} ${PROFILE_SOURCES}
336*7c3d14c8STreehugger Robot                                CFLAGS ${CFLAGS} -arch ${arch} -mkernel
337*7c3d14c8STreehugger Robot                                DEFS KERNEL_USE
338*7c3d14c8STreehugger Robot                                PARENT_TARGET builtins)
339*7c3d14c8STreehugger Robot      endforeach()
340*7c3d14c8STreehugger Robot      set(archive_name clang_rt.cc_kext_${os})
341*7c3d14c8STreehugger Robot      if(${os} STREQUAL "osx")
342*7c3d14c8STreehugger Robot        set(archive_name clang_rt.cc_kext)
343*7c3d14c8STreehugger Robot      endif()
344*7c3d14c8STreehugger Robot      darwin_lipo_libs(${archive_name}
345*7c3d14c8STreehugger Robot                      PARENT_TARGET builtins
346*7c3d14c8STreehugger Robot                      LIPO_FLAGS ${${os}_cc_kext_lipo_flags}
347*7c3d14c8STreehugger Robot                      DEPENDS ${${os}_cc_kext_libs}
348*7c3d14c8STreehugger Robot                      OUTPUT_DIR ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
349*7c3d14c8STreehugger Robot                      INSTALL_DIR ${COMPILER_RT_LIBRARY_INSTALL_DIR})
350*7c3d14c8STreehugger Robot    endif()
351*7c3d14c8STreehugger Robot  endforeach()
352*7c3d14c8STreehugger Robot
353*7c3d14c8STreehugger Robot  darwin_add_eprintf_library(CFLAGS ${CFLAGS})
354*7c3d14c8STreehugger Robot
355*7c3d14c8STreehugger Robot  # We put the x86 sim slices into the archives for their base OS
356*7c3d14c8STreehugger Robot  foreach (os ${ARGN})
357*7c3d14c8STreehugger Robot    if(NOT ${os} MATCHES ".*sim$")
358*7c3d14c8STreehugger Robot      darwin_lipo_libs(clang_rt.${os}
359*7c3d14c8STreehugger Robot                        PARENT_TARGET builtins
360*7c3d14c8STreehugger Robot                        LIPO_FLAGS ${${os}_builtins_lipo_flags} ${${os}sim_builtins_lipo_flags}
361*7c3d14c8STreehugger Robot                        DEPENDS ${${os}_builtins_libs} ${${os}sim_builtins_libs}
362*7c3d14c8STreehugger Robot                        OUTPUT_DIR ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
363*7c3d14c8STreehugger Robot                        INSTALL_DIR ${COMPILER_RT_LIBRARY_INSTALL_DIR})
364*7c3d14c8STreehugger Robot    endif()
365*7c3d14c8STreehugger Robot  endforeach()
366*7c3d14c8STreehugger Robot  darwin_add_embedded_builtin_libraries()
367*7c3d14c8STreehugger Robotendmacro()
368*7c3d14c8STreehugger Robot
369*7c3d14c8STreehugger Robotmacro(darwin_add_embedded_builtin_libraries)
370*7c3d14c8STreehugger Robot  # this is a hacky opt-out. If you can't target both intel and arm
371*7c3d14c8STreehugger Robot  # architectures we bail here.
372*7c3d14c8STreehugger Robot  set(DARWIN_SOFT_FLOAT_ARCHS armv6m armv7m armv7em armv7)
373*7c3d14c8STreehugger Robot  set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7)
374*7c3d14c8STreehugger Robot  if(COMPILER_RT_SUPPORTED_ARCH MATCHES ".*armv.*")
375*7c3d14c8STreehugger Robot    list(FIND COMPILER_RT_SUPPORTED_ARCH i386 i386_idx)
376*7c3d14c8STreehugger Robot    if(i386_idx GREATER -1)
377*7c3d14c8STreehugger Robot      list(APPEND DARWIN_HARD_FLOAT_ARCHS i386)
378*7c3d14c8STreehugger Robot    endif()
379*7c3d14c8STreehugger Robot
380*7c3d14c8STreehugger Robot    list(FIND COMPILER_RT_SUPPORTED_ARCH x86_64 x86_64_idx)
381*7c3d14c8STreehugger Robot    if(x86_64_idx GREATER -1)
382*7c3d14c8STreehugger Robot      list(APPEND DARWIN_HARD_FLOAT_ARCHS x86_64)
383*7c3d14c8STreehugger Robot    endif()
384*7c3d14c8STreehugger Robot
385*7c3d14c8STreehugger Robot    set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded)
386*7c3d14c8STreehugger Robot
387*7c3d14c8STreehugger Robot    set(CFLAGS "-Oz -Wall -fomit-frame-pointer -ffreestanding")
388*7c3d14c8STreehugger Robot    set(CMAKE_C_FLAGS "")
389*7c3d14c8STreehugger Robot    set(CMAKE_CXX_FLAGS "")
390*7c3d14c8STreehugger Robot    set(CMAKE_ASM_FLAGS "")
391*7c3d14c8STreehugger Robot
392*7c3d14c8STreehugger Robot    set(SOFT_FLOAT_FLAG -mfloat-abi=soft)
393*7c3d14c8STreehugger Robot    set(HARD_FLOAT_FLAG -mfloat-abi=hard)
394*7c3d14c8STreehugger Robot
395*7c3d14c8STreehugger Robot    set(ENABLE_PIC Off)
396*7c3d14c8STreehugger Robot    set(PIC_FLAG -fPIC)
397*7c3d14c8STreehugger Robot    set(STATIC_FLAG -static)
398*7c3d14c8STreehugger Robot
399*7c3d14c8STreehugger Robot    set(DARWIN_macho_embedded_ARCHS armv6m armv7m armv7em armv7 i386 x86_64)
400*7c3d14c8STreehugger Robot
401*7c3d14c8STreehugger Robot    set(DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR
402*7c3d14c8STreehugger Robot      ${COMPILER_RT_OUTPUT_DIR}/lib/macho_embedded)
403*7c3d14c8STreehugger Robot    set(DARWIN_macho_embedded_LIBRARY_INSTALL_DIR
404*7c3d14c8STreehugger Robot      ${COMPILER_RT_INSTALL_PATH}/lib/macho_embedded)
405*7c3d14c8STreehugger Robot
406*7c3d14c8STreehugger Robot    set(CFLAGS_armv7 "-target thumbv7-apple-darwin-eabi")
407*7c3d14c8STreehugger Robot    set(CFLAGS_i386 "-march=pentium")
408*7c3d14c8STreehugger Robot
409*7c3d14c8STreehugger Robot    darwin_read_list_from_file(common_FUNCTIONS ${MACHO_SYM_DIR}/common.txt)
410*7c3d14c8STreehugger Robot    darwin_read_list_from_file(thumb2_FUNCTIONS ${MACHO_SYM_DIR}/thumb2.txt)
411*7c3d14c8STreehugger Robot    darwin_read_list_from_file(thumb2_64_FUNCTIONS ${MACHO_SYM_DIR}/thumb2-64.txt)
412*7c3d14c8STreehugger Robot    darwin_read_list_from_file(arm_FUNCTIONS ${MACHO_SYM_DIR}/arm.txt)
413*7c3d14c8STreehugger Robot    darwin_read_list_from_file(i386_FUNCTIONS ${MACHO_SYM_DIR}/i386.txt)
414*7c3d14c8STreehugger Robot
415*7c3d14c8STreehugger Robot
416*7c3d14c8STreehugger Robot    set(armv6m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS})
417*7c3d14c8STreehugger Robot    set(armv7m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
418*7c3d14c8STreehugger Robot    set(armv7em_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
419*7c3d14c8STreehugger Robot    set(armv7_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS} ${thumb2_64_FUNCTIONS})
420*7c3d14c8STreehugger Robot    set(i386_FUNCTIONS ${common_FUNCTIONS} ${i386_FUNCTIONS})
421*7c3d14c8STreehugger Robot    set(x86_64_FUNCTIONS ${common_FUNCTIONS})
422*7c3d14c8STreehugger Robot
423*7c3d14c8STreehugger Robot    foreach(arch ${DARWIN_macho_embedded_ARCHS})
424*7c3d14c8STreehugger Robot      darwin_filter_builtin_sources(${arch}_filtered_sources
425*7c3d14c8STreehugger Robot        INCLUDE ${arch}_FUNCTIONS
426*7c3d14c8STreehugger Robot        ${${arch}_SOURCES})
427*7c3d14c8STreehugger Robot      if(NOT ${arch}_filtered_sources)
428*7c3d14c8STreehugger Robot        message("${arch}_SOURCES: ${${arch}_SOURCES}")
429*7c3d14c8STreehugger Robot        message("${arch}_FUNCTIONS: ${${arch}_FUNCTIONS}")
430*7c3d14c8STreehugger Robot        message(FATAL_ERROR "Empty filtered sources!")
431*7c3d14c8STreehugger Robot      endif()
432*7c3d14c8STreehugger Robot    endforeach()
433*7c3d14c8STreehugger Robot
434*7c3d14c8STreehugger Robot    foreach(float_type SOFT HARD)
435*7c3d14c8STreehugger Robot      foreach(type PIC STATIC)
436*7c3d14c8STreehugger Robot        string(TOLOWER "${float_type}_${type}" lib_suffix)
437*7c3d14c8STreehugger Robot        foreach(arch ${DARWIN_${float_type}_FLOAT_ARCHS})
438*7c3d14c8STreehugger Robot          set(DARWIN_macho_embedded_SYSROOT ${DARWIN_osx_SYSROOT})
439*7c3d14c8STreehugger Robot          set(float_flag)
440*7c3d14c8STreehugger Robot          if(${arch} MATCHES "^arm")
441*7c3d14c8STreehugger Robot            # x86 targets are hard float by default, but the complain about the
442*7c3d14c8STreehugger Robot            # float ABI flag, so don't pass it unless we're targeting arm.
443*7c3d14c8STreehugger Robot            set(float_flag ${${float_type}_FLOAT_FLAG})
444*7c3d14c8STreehugger Robot          endif()
445*7c3d14c8STreehugger Robot          darwin_add_builtin_library(clang_rt ${lib_suffix}
446*7c3d14c8STreehugger Robot                                OS macho_embedded
447*7c3d14c8STreehugger Robot                                ARCH ${arch}
448*7c3d14c8STreehugger Robot                                SOURCES ${${arch}_filtered_sources}
449*7c3d14c8STreehugger Robot                                CFLAGS ${CFLAGS} -arch ${arch} ${${type}_FLAG} ${float_flag} ${CFLAGS_${arch}}
450*7c3d14c8STreehugger Robot                                PARENT_TARGET builtins)
451*7c3d14c8STreehugger Robot        endforeach()
452*7c3d14c8STreehugger Robot        foreach(lib ${macho_embedded_${lib_suffix}_libs})
453*7c3d14c8STreehugger Robot          set_target_properties(${lib} PROPERTIES LINKER_LANGUAGE C)
454*7c3d14c8STreehugger Robot        endforeach()
455*7c3d14c8STreehugger Robot        darwin_lipo_libs(clang_rt.${lib_suffix}
456*7c3d14c8STreehugger Robot                      PARENT_TARGET builtins
457*7c3d14c8STreehugger Robot                      LIPO_FLAGS ${macho_embedded_${lib_suffix}_lipo_flags}
458*7c3d14c8STreehugger Robot                      DEPENDS ${macho_embedded_${lib_suffix}_libs}
459*7c3d14c8STreehugger Robot                      OUTPUT_DIR ${DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR}
460*7c3d14c8STreehugger Robot                      INSTALL_DIR ${DARWIN_macho_embedded_LIBRARY_INSTALL_DIR})
461*7c3d14c8STreehugger Robot      endforeach()
462*7c3d14c8STreehugger Robot    endforeach()
463*7c3d14c8STreehugger Robot  endif()
464*7c3d14c8STreehugger Robotendmacro()
465