1include(ExternalProject)
2include(CompilerRTUtils)
3
4function(set_target_output_directories target output_dir)
5  # For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators
6  # append a per-configuration subdirectory to the specified directory.
7  # To avoid the appended folder, the configuration specific variable must be
8  # set 'RUNTIME_OUTPUT_DIRECTORY_${CONF}':
9  # RUNTIME_OUTPUT_DIRECTORY_DEBUG, RUNTIME_OUTPUT_DIRECTORY_RELEASE, ...
10  if(CMAKE_CONFIGURATION_TYPES)
11    foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
12      string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
13      set_target_properties("${target}" PROPERTIES
14          "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
15          "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
16          "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir})
17    endforeach()
18  else()
19    set_target_properties("${target}" PROPERTIES
20        ARCHIVE_OUTPUT_DIRECTORY ${output_dir}
21        LIBRARY_OUTPUT_DIRECTORY ${output_dir}
22        RUNTIME_OUTPUT_DIRECTORY ${output_dir})
23  endif()
24endfunction()
25
26# Tries to add an "object library" target for a given list of OSs and/or
27# architectures with name "<name>.<arch>" for non-Darwin platforms if
28# architecture can be targeted, and "<name>.<os>" for Darwin platforms.
29# add_compiler_rt_object_libraries(<name>
30#                                  OS <os names>
31#                                  ARCHS <architectures>
32#                                  SOURCES <source files>
33#                                  CFLAGS <compile flags>
34#                                  DEFS <compile definitions>)
35function(add_compiler_rt_object_libraries name)
36  cmake_parse_arguments(LIB "" "" "OS;ARCHS;SOURCES;CFLAGS;DEFS" ${ARGN})
37  set(libnames)
38  if(APPLE)
39    foreach(os ${LIB_OS})
40      set(libname "${name}.${os}")
41      set(libnames ${libnames} ${libname})
42      set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})
43      list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
44    endforeach()
45  else()
46    foreach(arch ${LIB_ARCHS})
47      set(libname "${name}.${arch}")
48      set(libnames ${libnames} ${libname})
49      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS})
50      if(NOT CAN_TARGET_${arch})
51        message(FATAL_ERROR "Architecture ${arch} can't be targeted")
52        return()
53      endif()
54    endforeach()
55  endif()
56
57  foreach(libname ${libnames})
58    add_library(${libname} OBJECT ${LIB_SOURCES})
59
60    # Strip out -msse3 if this isn't macOS.
61    set(target_flags ${LIB_CFLAGS})
62    if(APPLE AND NOT "${libname}" MATCHES ".*\.osx.*")
63      list(REMOVE_ITEM target_flags "-msse3")
64    endif()
65
66    set_target_compile_flags(${libname}
67      ${CMAKE_CXX_FLAGS} ${extra_cflags_${libname}} ${target_flags})
68    set_property(TARGET ${libname} APPEND PROPERTY
69      COMPILE_DEFINITIONS ${LIB_DEFS})
70    set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
71    if(APPLE)
72      set_target_properties(${libname} PROPERTIES
73        OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
74    endif()
75  endforeach()
76endfunction()
77
78# Takes a list of object library targets, and a suffix and appends the proper
79# TARGET_OBJECTS string to the output variable.
80# format_object_libs(<output> <suffix> ...)
81macro(format_object_libs output suffix)
82  foreach(lib ${ARGN})
83    list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>)
84  endforeach()
85endmacro()
86
87function(add_compiler_rt_component name)
88  add_custom_target(${name})
89  set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc")
90  if(COMMAND runtime_register_component)
91    runtime_register_component(${name})
92  endif()
93  add_dependencies(compiler-rt ${name})
94endfunction()
95
96function(add_asm_sources output)
97  set(${output} ${ARGN} PARENT_SCOPE)
98  # Xcode will try to compile asm files as C ('clang -x c'), and that will fail.
99  if (${CMAKE_GENERATOR} STREQUAL "Xcode")
100    enable_language(ASM)
101  else()
102    # Pass ASM file directly to the C++ compiler.
103    set_source_files_properties(${ARGN} PROPERTIES LANGUAGE C)
104  endif()
105endfunction()
106
107macro(set_output_name output name arch)
108  if(ANDROID AND ${arch} STREQUAL "i386")
109    set(${output} "${name}-i686${COMPILER_RT_OS_SUFFIX}")
110  else()
111    set(${output} "${name}-${arch}${COMPILER_RT_OS_SUFFIX}")
112  endif()
113endmacro()
114
115# Adds static or shared runtime for a list of architectures and operating
116# systems and puts it in the proper directory in the build and install trees.
117# add_compiler_rt_runtime(<name>
118#                         {STATIC|SHARED}
119#                         ARCHS <architectures>
120#                         OS <os list>
121#                         SOURCES <source files>
122#                         CFLAGS <compile flags>
123#                         LINK_FLAGS <linker flags>
124#                         DEFS <compile definitions>
125#                         LINK_LIBS <linked libraries> (only for shared library)
126#                         OBJECT_LIBS <object libraries to use as sources>
127#                         PARENT_TARGET <convenience parent target>)
128function(add_compiler_rt_runtime name type)
129  if(NOT type MATCHES "^(STATIC|SHARED)$")
130    message(FATAL_ERROR "type argument must be STATIC or SHARED")
131    return()
132  endif()
133  cmake_parse_arguments(LIB
134    ""
135    "PARENT_TARGET"
136    "OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;LINK_LIBS;OBJECT_LIBS"
137    ${ARGN})
138  set(libnames)
139  # Until we support this some other way, build compiler-rt runtime without LTO
140  # to allow non-LTO projects to link with it.
141  if(COMPILER_RT_HAS_FNO_LTO_FLAG)
142    set(NO_LTO_FLAGS "-fno-lto")
143  else()
144    set(NO_LTO_FLAGS "")
145  endif()
146
147  if(APPLE)
148    foreach(os ${LIB_OS})
149      # Strip out -msse3 if this isn't macOS.
150      list(LENGTH LIB_CFLAGS HAS_EXTRA_CFLAGS)
151      if(HAS_EXTRA_CFLAGS AND NOT "${os}" MATCHES "^(osx)$")
152        list(REMOVE_ITEM LIB_CFLAGS "-msse3")
153      endif()
154      if(type STREQUAL "STATIC")
155        set(libname "${name}_${os}")
156      else()
157        set(libname "${name}_${os}_dynamic")
158        set(extra_link_flags_${libname} ${DARWIN_${os}_LINK_FLAGS} ${LIB_LINK_FLAGS})
159      endif()
160      list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
161      if(LIB_ARCHS_${libname})
162        list(APPEND libnames ${libname})
163        set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${NO_LTO_FLAGS} ${LIB_CFLAGS})
164        set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
165        set(sources_${libname} ${LIB_SOURCES})
166        format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS})
167      endif()
168    endforeach()
169  else()
170    foreach(arch ${LIB_ARCHS})
171      if(NOT CAN_TARGET_${arch})
172        message(FATAL_ERROR "Architecture ${arch} can't be targeted")
173        return()
174      endif()
175      if(type STREQUAL "STATIC")
176        set(libname "${name}-${arch}")
177        set_output_name(output_name_${libname} ${name} ${arch})
178      else()
179        set(libname "${name}-dynamic-${arch}")
180        set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
181        set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS})
182        if(WIN32)
183          set_output_name(output_name_${libname} ${name}_dynamic ${arch})
184        else()
185          set_output_name(output_name_${libname} ${name} ${arch})
186        endif()
187      endif()
188      set(sources_${libname} ${LIB_SOURCES})
189      format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS})
190      set(libnames ${libnames} ${libname})
191      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${NO_LTO_FLAGS} ${LIB_CFLAGS})
192    endforeach()
193  endif()
194
195  if(NOT libnames)
196    return()
197  endif()
198
199  if(LIB_PARENT_TARGET)
200    # If the parent targets aren't created we should create them
201    if(NOT TARGET ${LIB_PARENT_TARGET})
202      add_custom_target(${LIB_PARENT_TARGET})
203    endif()
204    if(NOT TARGET install-${LIB_PARENT_TARGET})
205      # The parent install target specifies the parent component to scrape up
206      # anything not installed by the individual install targets, and to handle
207      # installation when running the multi-configuration generators.
208      add_custom_target(install-${LIB_PARENT_TARGET}
209                        DEPENDS ${LIB_PARENT_TARGET}
210                        COMMAND "${CMAKE_COMMAND}"
211                                -DCMAKE_INSTALL_COMPONENT=${LIB_PARENT_TARGET}
212                                -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
213      add_custom_target(install-${LIB_PARENT_TARGET}-stripped
214                        DEPENDS ${LIB_PARENT_TARGET}
215                        COMMAND "${CMAKE_COMMAND}"
216                                -DCMAKE_INSTALL_COMPONENT=${LIB_PARENT_TARGET}
217                                -DCMAKE_INSTALL_DO_STRIP=1
218                                -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
219      set_target_properties(install-${LIB_PARENT_TARGET} PROPERTIES
220                            FOLDER "Compiler-RT Misc")
221      set_target_properties(install-${LIB_PARENT_TARGET}-stripped PROPERTIES
222                            FOLDER "Compiler-RT Misc")
223      add_dependencies(install-compiler-rt install-${LIB_PARENT_TARGET})
224      add_dependencies(install-compiler-rt-stripped install-${LIB_PARENT_TARGET}-stripped)
225    endif()
226  endif()
227
228  foreach(libname ${libnames})
229    # If you are using a multi-configuration generator we don't generate
230    # per-library install rules, so we fall back to the parent target COMPONENT
231    if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET)
232      set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})
233    else()
234      set(COMPONENT_OPTION COMPONENT ${libname})
235    endif()
236
237    add_library(${libname} ${type} ${sources_${libname}})
238    set_target_compile_flags(${libname} ${extra_cflags_${libname}})
239    set_target_link_flags(${libname} ${extra_link_flags_${libname}})
240    set_property(TARGET ${libname} APPEND PROPERTY
241                COMPILE_DEFINITIONS ${LIB_DEFS})
242    set_target_output_directories(${libname} ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
243    set_target_properties(${libname} PROPERTIES
244        OUTPUT_NAME ${output_name_${libname}})
245    set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime")
246    if(LIB_LINK_LIBS)
247      target_link_libraries(${libname} ${LIB_LINK_LIBS})
248    endif()
249    if(${type} STREQUAL "SHARED")
250      if(WIN32 AND NOT CYGWIN AND NOT MINGW)
251        set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "")
252        set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib")
253      endif()
254      if(APPLE)
255        # Ad-hoc sign the dylibs
256        add_custom_command(TARGET ${libname}
257          POST_BUILD
258          COMMAND codesign --sign - $<TARGET_FILE:${libname}>
259          WORKING_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
260        )
261      endif()
262    endif()
263    install(TARGETS ${libname}
264      ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
265              ${COMPONENT_OPTION}
266      LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
267              ${COMPONENT_OPTION}
268      RUNTIME DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
269              ${COMPONENT_OPTION})
270
271    # We only want to generate per-library install targets if you aren't using
272    # an IDE because the extra targets get cluttered in IDEs.
273    if(NOT CMAKE_CONFIGURATION_TYPES)
274      add_custom_target(install-${libname}
275                        DEPENDS ${libname}
276                        COMMAND "${CMAKE_COMMAND}"
277                                -DCMAKE_INSTALL_COMPONENT=${libname}
278                                -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
279      add_custom_target(install-${libname}-stripped
280                        DEPENDS ${libname}
281                        COMMAND "${CMAKE_COMMAND}"
282                                -DCMAKE_INSTALL_COMPONENT=${libname}
283                                -DCMAKE_INSTALL_DO_STRIP=1
284                                -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
285      # If you have a parent target specified, we bind the new install target
286      # to the parent install target.
287      if(LIB_PARENT_TARGET)
288        add_dependencies(install-${LIB_PARENT_TARGET} install-${libname})
289        add_dependencies(install-${LIB_PARENT_TARGET}-stripped install-${libname}-stripped)
290      endif()
291    endif()
292    if(APPLE)
293      set_target_properties(${libname} PROPERTIES
294      OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
295    endif()
296
297    if(type STREQUAL "SHARED")
298      rt_externalize_debuginfo(${libname})
299    endif()
300  endforeach()
301  if(LIB_PARENT_TARGET)
302    add_dependencies(${LIB_PARENT_TARGET} ${libnames})
303  endif()
304endfunction()
305
306# when cross compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help
307# in compilation and linking of unittests.
308string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}")
309set(COMPILER_RT_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_CFLAGS})
310
311# Unittests support.
312set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest)
313set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc)
314set(COMPILER_RT_GTEST_CFLAGS
315  -DGTEST_NO_LLVM_RAW_OSTREAM=1
316  -DGTEST_HAS_RTTI=0
317  -I${COMPILER_RT_GTEST_PATH}/include
318  -I${COMPILER_RT_GTEST_PATH}
319)
320
321append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS)
322append_list_if(COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG -Wno-covered-switch-default COMPILER_RT_UNITTEST_CFLAGS)
323
324if(MSVC)
325  # clang doesn't support exceptions on Windows yet.
326  list(APPEND COMPILER_RT_UNITTEST_CFLAGS -D_HAS_EXCEPTIONS=0)
327
328  # We should teach clang to understand "#pragma intrinsic", see PR19898.
329  list(APPEND COMPILER_RT_UNITTEST_CFLAGS -Wno-undefined-inline)
330
331  # Clang doesn't support SEH on Windows yet.
332  list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0)
333
334  # gtest use a lot of stuff marked as deprecated on Windows.
335  list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations)
336endif()
337
338# Compile and register compiler-rt tests.
339# generate_compiler_rt_tests(<output object files> <test_suite> <test_name>
340#                           <test architecture>
341#                           KIND <custom prefix>
342#                           SUBDIR <subdirectory for testing binary>
343#                           SOURCES <sources to compile>
344#                           RUNTIME <tests runtime to link in>
345#                           CFLAGS <compile-time flags>
346#                           COMPILE_DEPS <compile-time dependencies>
347#                           DEPS <dependencies>
348#                           LINK_FLAGS <flags to use during linking>
349# )
350function(generate_compiler_rt_tests test_objects test_suite testname arch)
351  cmake_parse_arguments(TEST "" "KIND;RUNTIME;SUBDIR"
352    "SOURCES;COMPILE_DEPS;DEPS;CFLAGS;LINK_FLAGS" ${ARGN})
353
354  foreach(source ${TEST_SOURCES})
355    sanitizer_test_compile(
356      "${test_objects}" "${source}" "${arch}"
357      KIND ${TEST_KIND}
358      COMPILE_DEPS ${TEST_COMPILE_DEPS}
359      DEPS ${TEST_DEPS}
360      CFLAGS ${TEST_CFLAGS}
361      )
362  endforeach()
363
364  set(TEST_DEPS ${${test_objects}})
365
366  if(NOT "${TEST_RUNTIME}" STREQUAL "")
367    list(APPEND TEST_DEPS ${TEST_RUNTIME})
368    list(APPEND "${test_objects}" $<TARGET_FILE:${TEST_RUNTIME}>)
369  endif()
370
371  add_compiler_rt_test(${test_suite} "${testname}" "${arch}"
372    SUBDIR ${TEST_SUBDIR}
373    OBJECTS ${${test_objects}}
374    DEPS ${TEST_DEPS}
375    LINK_FLAGS ${TEST_LINK_FLAGS}
376    )
377  set("${test_objects}" "${${test_objects}}" PARENT_SCOPE)
378endfunction()
379
380# Link objects into a single executable with COMPILER_RT_TEST_COMPILER,
381# using specified link flags. Make executable a part of provided
382# test_suite.
383# add_compiler_rt_test(<test_suite> <test_name> <arch>
384#                      SUBDIR <subdirectory for binary>
385#                      OBJECTS <object files>
386#                      DEPS <deps (e.g. runtime libs)>
387#                      LINK_FLAGS <link flags>)
388function(add_compiler_rt_test test_suite test_name arch)
389  cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN})
390  set(output_dir ${CMAKE_CURRENT_BINARY_DIR})
391  if(TEST_SUBDIR)
392    set(output_dir "${output_dir}/${TEST_SUBDIR}")
393  endif()
394  set(output_dir "${output_dir}/${CMAKE_CFG_INTDIR}")
395  file(MAKE_DIRECTORY "${output_dir}")
396  set(output_bin "${output_dir}/${test_name}")
397  if(MSVC)
398    set(output_bin "${output_bin}.exe")
399  endif()
400
401  # Use host compiler in a standalone build, and just-built Clang otherwise.
402  if(NOT COMPILER_RT_STANDALONE_BUILD)
403    list(APPEND TEST_DEPS clang)
404  endif()
405
406  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
407  list(APPEND TEST_LINK_FLAGS ${TARGET_LINK_FLAGS})
408
409  # If we're not on MSVC, include the linker flags from CMAKE but override them
410  # with the provided link flags. This ensures that flags which are required to
411  # link programs at all are included, but the changes needed for the test
412  # trump. With MSVC we can't do that because CMake is set up to run link.exe
413  # when linking, not the compiler. Here, we hack it to use the compiler
414  # because we want to use -fsanitize flags.
415  if(NOT MSVC)
416    set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}")
417    separate_arguments(TEST_LINK_FLAGS)
418  endif()
419  add_custom_command(
420    OUTPUT "${output_bin}"
421    COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS} -o "${output_bin}"
422            ${TEST_LINK_FLAGS}
423    DEPENDS ${TEST_DEPS}
424    )
425  add_custom_target(T${test_name} DEPENDS "${output_bin}")
426  set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT Tests")
427
428  # Make the test suite depend on the binary.
429  add_dependencies(${test_suite} T${test_name})
430endfunction()
431
432macro(add_compiler_rt_resource_file target_name file_name component)
433  set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}")
434  set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}")
435  add_custom_command(OUTPUT ${dst_file}
436    DEPENDS ${src_file}
437    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}
438    COMMENT "Copying ${file_name}...")
439  add_custom_target(${target_name} DEPENDS ${dst_file})
440  # Install in Clang resource directory.
441  install(FILES ${file_name}
442    DESTINATION ${COMPILER_RT_INSTALL_PATH}/share
443    COMPONENT ${component})
444  add_dependencies(${component} ${target_name})
445
446  set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc")
447endmacro()
448
449macro(add_compiler_rt_script name)
450  set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name})
451  set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name})
452  add_custom_command(OUTPUT ${dst}
453    DEPENDS ${src}
454    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
455    COMMENT "Copying ${name}...")
456  add_custom_target(${name} DEPENDS ${dst})
457  install(FILES ${dst}
458    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
459    DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin)
460endmacro(add_compiler_rt_script src name)
461
462# Builds custom version of libc++ and installs it in <prefix>.
463# Can be used to build sanitized versions of libc++ for running unit tests.
464# add_custom_libcxx(<name> <prefix>
465#                   DEPS <list of build deps>
466#                   CFLAGS <list of compile flags>)
467macro(add_custom_libcxx name prefix)
468  if(NOT COMPILER_RT_LIBCXX_PATH)
469    message(FATAL_ERROR "libcxx not found!")
470  endif()
471
472  cmake_parse_arguments(LIBCXX "" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN})
473  foreach(flag ${LIBCXX_CFLAGS})
474    set(flagstr "${flagstr} ${flag}")
475  endforeach()
476  set(LIBCXX_CFLAGS ${flagstr})
477
478  if(NOT COMPILER_RT_STANDALONE_BUILD)
479    list(APPEND LIBCXX_DEPS clang)
480  endif()
481
482  ExternalProject_Add(${name}
483    PREFIX ${prefix}
484    SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH}
485    CMAKE_ARGS -DCMAKE_MAKE_PROGRAM:STRING=${CMAKE_MAKE_PROGRAM}
486               -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}
487               -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}
488               -DCMAKE_C_FLAGS=${LIBCXX_CFLAGS}
489               -DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS}
490               -DCMAKE_BUILD_TYPE=Release
491               -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
492               -DLLVM_PATH=${LLVM_MAIN_SRC_DIR}
493               -DLIBCXX_STANDALONE_BUILD=On
494               ${LIBCXX_CMAKE_ARGS}
495    LOG_BUILD 1
496    LOG_CONFIGURE 1
497    LOG_INSTALL 1
498    )
499  set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
500
501  ExternalProject_Add_Step(${name} force-reconfigure
502    DEPENDERS configure
503    ALWAYS 1
504    )
505
506  ExternalProject_Add_Step(${name} clobber
507    COMMAND ${CMAKE_COMMAND} -E remove_directory <BINARY_DIR>
508    COMMAND ${CMAKE_COMMAND} -E make_directory <BINARY_DIR>
509    COMMENT "Clobberring ${name} build directory..."
510    DEPENDERS configure
511    DEPENDS ${LIBCXX_DEPS}
512    )
513endmacro()
514
515function(rt_externalize_debuginfo name)
516  if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO)
517    return()
518  endif()
519
520  if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)
521    set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)
522  endif()
523
524  if(APPLE)
525    if(CMAKE_CXX_FLAGS MATCHES "-flto"
526      OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")
527
528      set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)
529      set_property(TARGET ${name} APPEND_STRING PROPERTY
530        LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}")
531    endif()
532    add_custom_command(TARGET ${name} POST_BUILD
533      COMMAND xcrun dsymutil $<TARGET_FILE:${name}>
534      ${strip_command})
535  else()
536    message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!")
537  endif()
538endfunction()
539
540
541# Configure lit configuration files, including compiler-rt specific variables.
542function(configure_compiler_rt_lit_site_cfg input output)
543  set_llvm_build_mode()
544
545  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER})
546  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
547
548  configure_lit_site_cfg(${input} ${output})
549endfunction()
550