1set(LIBCXX_LIB_CMAKEFILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}"  PARENT_SCOPE)
2
3# Get sources
4set(LIBCXX_SOURCES
5  algorithm.cpp
6  any.cpp
7  atomic.cpp
8  barrier.cpp
9  bind.cpp
10  charconv.cpp
11  chrono.cpp
12  condition_variable.cpp
13  condition_variable_destructor.cpp
14  exception.cpp
15  functional.cpp
16  future.cpp
17  hash.cpp
18  include/apple_availability.h
19  include/atomic_support.h
20  include/config_elast.h
21  include/refstring.h
22  include/ryu/common.h
23  include/ryu/d2fixed.h
24  include/ryu/d2fixed_full_table.h
25  include/ryu/d2s.h
26  include/ryu/d2s_full_table.h
27  include/ryu/d2s_intrinsics.h
28  include/ryu/digit_table.h
29  include/ryu/f2s.h
30  include/ryu/ryu.h
31  include/to_chars_floating_point.h
32  legacy_pointer_safety.cpp
33  memory.cpp
34  mutex.cpp
35  mutex_destructor.cpp
36  new.cpp
37  optional.cpp
38  random_shuffle.cpp
39  ryu/d2fixed.cpp
40  ryu/d2s.cpp
41  ryu/f2s.cpp
42  shared_mutex.cpp
43  stdexcept.cpp
44  string.cpp
45  support/runtime/exception_fallback.ipp
46  support/runtime/exception_glibcxx.ipp
47  support/runtime/exception_libcxxabi.ipp
48  support/runtime/exception_libcxxrt.ipp
49  support/runtime/exception_msvc.ipp
50  support/runtime/exception_pointer_cxxabi.ipp
51  support/runtime/exception_pointer_glibcxx.ipp
52  support/runtime/exception_pointer_msvc.ipp
53  support/runtime/exception_pointer_unimplemented.ipp
54  support/runtime/new_handler_fallback.ipp
55  support/runtime/stdexcept_default.ipp
56  support/runtime/stdexcept_vcruntime.ipp
57  system_error.cpp
58  thread.cpp
59  typeinfo.cpp
60  utility.cpp
61  valarray.cpp
62  variant.cpp
63  vector.cpp
64  verbose_abort.cpp
65  )
66
67if (LIBCXX_ENABLE_DEBUG_MODE OR LIBCXX_ENABLE_BACKWARDS_COMPATIBILITY_DEBUG_MODE_SYMBOLS)
68  list(APPEND LIBCXX_SOURCES
69    debug.cpp
70    legacy_debug_handler.cpp
71    )
72endif()
73
74if (LIBCXX_ENABLE_RANDOM_DEVICE)
75  list(APPEND LIBCXX_SOURCES
76    random.cpp
77    )
78endif()
79
80if (LIBCXX_ENABLE_LOCALIZATION)
81  list(APPEND LIBCXX_SOURCES
82    include/sso_allocator.h
83    ios.cpp
84    ios.instantiations.cpp
85    iostream.cpp
86    locale.cpp
87    regex.cpp
88    strstream.cpp
89    )
90endif()
91
92if(WIN32)
93  list(APPEND LIBCXX_SOURCES
94    support/win32/locale_win32.cpp
95    support/win32/support.cpp
96    )
97
98  if (NOT LIBCXX_HAS_PTHREAD_API)
99    list(APPEND LIBCXX_SOURCES
100      support/win32/thread_win32.cpp
101      )
102  endif()
103elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
104  list(APPEND LIBCXX_SOURCES
105    support/solaris/mbsnrtowcs.inc
106    support/solaris/wcsnrtombs.inc
107    support/solaris/xlocale.cpp
108    )
109elseif(ZOS)
110  list(APPEND LIBCXX_SOURCES
111    support/ibm/mbsnrtowcs.cpp
112    support/ibm/wcsnrtombs.cpp
113    support/ibm/xlocale_zos.cpp
114    )
115endif()
116
117if (LIBCXX_ENABLE_FILESYSTEM)
118  list(APPEND LIBCXX_SOURCES
119    filesystem/filesystem_common.h
120    filesystem/operations.cpp
121    filesystem/directory_iterator.cpp
122    filesystem/posix_compat.h
123    )
124  # Filesystem uses __int128_t, which requires a definition of __muloi4 when
125  # compiled with UBSAN. This definition is not provided by libgcc_s, but is
126  # provided by compiler-rt. So we need to disable it to avoid having multiple
127  # definitions. See filesystem/int128_builtins.cpp.
128  if (NOT LIBCXX_USE_COMPILER_RT)
129    list(APPEND LIBCXX_SOURCES
130      filesystem/int128_builtins.cpp
131      )
132  endif()
133endif()
134
135# Add all the headers to the project for IDEs.
136if (LIBCXX_CONFIGURE_IDE)
137  file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/*)
138  if(WIN32)
139    file( GLOB LIBCXX_WIN32_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/__support/win32/*.h)
140    list(APPEND LIBCXX_HEADERS ${LIBCXX_WIN32_HEADERS})
141  endif()
142  # Force them all into the headers dir on MSVC, otherwise they end up at
143  # project scope because they don't have extensions.
144  if (MSVC_IDE)
145    source_group("Header Files" FILES ${LIBCXX_HEADERS})
146  endif()
147endif()
148
149if(NOT LIBCXX_INSTALL_LIBRARY)
150  set(exclude_from_all EXCLUDE_FROM_ALL)
151endif()
152
153if (LIBCXX_GENERATE_COVERAGE AND NOT LIBCXX_COVERAGE_LIBRARY)
154  find_compiler_rt_library(profile LIBCXX_COVERAGE_LIBRARY)
155endif()
156add_library_flags_if(LIBCXX_COVERAGE_LIBRARY "${LIBCXX_COVERAGE_LIBRARY}")
157
158if (APPLE AND LLVM_USE_SANITIZER)
159  if (("${LLVM_USE_SANITIZER}" STREQUAL "Address") OR
160      ("${LLVM_USE_SANITIZER}" STREQUAL "Address;Undefined") OR
161      ("${LLVM_USE_SANITIZER}" STREQUAL "Undefined;Address"))
162    set(LIBFILE "libclang_rt.asan_osx_dynamic.dylib")
163  elseif("${LLVM_USE_SANITIZER}" STREQUAL "Undefined")
164    set(LIBFILE "libclang_rt.ubsan_osx_dynamic.dylib")
165  elseif("${LLVM_USE_SANITIZER}" STREQUAL "Thread")
166    set(LIBFILE "libclang_rt.tsan_osx_dynamic.dylib")
167  else()
168    message(WARNING "LLVM_USE_SANITIZER=${LLVM_USE_SANITIZER} is not supported on OS X")
169  endif()
170  if (LIBFILE)
171    find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
172    get_filename_component(LIBDIR "${LIBCXX_BUILTINS_LIBRARY}" DIRECTORY)
173    if (NOT IS_DIRECTORY "${LIBDIR}")
174      message(FATAL_ERROR "Cannot find compiler-rt directory on OS X required for LLVM_USE_SANITIZER")
175    endif()
176    set(LIBCXX_SANITIZER_LIBRARY "${LIBDIR}/${LIBFILE}")
177    set(LIBCXX_SANITIZER_LIBRARY "${LIBCXX_SANITIZER_LIBRARY}" PARENT_SCOPE)
178    message(STATUS "Manually linking compiler-rt library: ${LIBCXX_SANITIZER_LIBRARY}")
179    add_library_flags("${LIBCXX_SANITIZER_LIBRARY}")
180    add_link_flags("-Wl,-rpath,${LIBDIR}")
181  endif()
182endif()
183
184if (LIBCXX_ENABLE_PARALLEL_ALGORITHMS AND NOT TARGET pstl::ParallelSTL)
185  message(FATAL_ERROR "Could not find ParallelSTL")
186endif()
187
188function(cxx_set_common_defines name)
189  if (LIBCXX_ENABLE_PARALLEL_ALGORITHMS)
190    target_link_libraries(${name} PUBLIC pstl::ParallelSTL)
191  endif()
192endfunction()
193
194split_list(LIBCXX_COMPILE_FLAGS)
195split_list(LIBCXX_LINK_FLAGS)
196
197# Build the shared library.
198if (LIBCXX_ENABLE_SHARED)
199  add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
200  target_include_directories(cxx_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
201  target_link_libraries(cxx_shared PUBLIC cxx-headers
202                                   PRIVATE ${LIBCXX_LIBRARIES})
203  set_target_properties(cxx_shared
204    PROPERTIES
205      COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
206      LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
207      OUTPUT_NAME   "c++"
208      VERSION       "${LIBCXX_LIBRARY_VERSION}"
209      SOVERSION     "${LIBCXX_ABI_VERSION}"
210      DEFINE_SYMBOL ""
211  )
212  cxx_add_common_build_flags(cxx_shared)
213  cxx_set_common_defines(cxx_shared)
214
215  # Link against libc++abi
216  if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
217    target_link_libraries(cxx_shared PRIVATE libcxx-abi-shared-objects)
218  else()
219    target_link_libraries(cxx_shared PUBLIC libcxx-abi-shared)
220  endif()
221
222  # Maybe re-export symbols from libc++abi
223  # In particular, we don't re-export the symbols if libc++abi is merged statically
224  # into libc++ because in that case there's no dylib to re-export from.
225  if (APPLE AND LIBCXX_CXX_ABI STREQUAL "libcxxabi"
226            AND NOT DEFINED LIBCXX_OSX_REEXPORT_LIBCXXABI_SYMBOLS
227            AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
228    set(LIBCXX_OSX_REEXPORT_LIBCXXABI_SYMBOLS ON)
229  endif()
230
231  if (LIBCXX_OSX_REEXPORT_LIBCXXABI_SYMBOLS)
232    target_link_libraries(cxx_shared PRIVATE
233      "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/libc++unexp.exp"
234      "-Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/libc++abi.exp"
235      "-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/notweak.exp"
236      "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/weak.exp")
237
238    target_link_libraries(cxx_shared PRIVATE $<TARGET_NAME_IF_EXISTS:cxxabi-reexports>)
239  endif()
240
241  # Generate a linker script in place of a libc++.so symlink.
242  if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
243    set(link_libraries)
244
245    set(imported_libname "$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>")
246    set(output_name "$<TARGET_PROPERTY:libcxx-abi-shared,OUTPUT_NAME>")
247    string(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<IF:$<BOOL:${imported_libname}>,${imported_libname},${output_name}>")
248
249    # TODO: Move to the same approach as above for the unwind library
250    if (LIBCXXABI_USE_LLVM_UNWINDER)
251      if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY)
252        # libunwind is already included in libc++abi
253      elseif (TARGET unwind_shared OR HAVE_LIBUNWIND)
254        string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:unwind_shared,OUTPUT_NAME>")
255      else()
256        string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}unwind")
257      endif()
258    endif()
259
260    set(linker_script "INPUT($<TARGET_SONAME_FILE_NAME:cxx_shared> ${link_libraries})")
261    add_custom_command(TARGET cxx_shared POST_BUILD
262      COMMAND "${CMAKE_COMMAND}" -E remove "$<TARGET_LINKER_FILE:cxx_shared>"
263      COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "$<TARGET_LINKER_FILE:cxx_shared>"
264      COMMENT "Generating linker script: '${linker_script}' as file $<TARGET_LINKER_FILE:cxx_shared>"
265      VERBATIM
266    )
267  endif()
268
269  list(APPEND LIBCXX_BUILD_TARGETS "cxx_shared")
270  if(WIN32 AND NOT MINGW AND NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
271    # Since we most likely do not have a mt.exe replacement, disable the
272    # manifest bundling.  This allows a normal cmake invocation to pass which
273    # will attempt to use the manifest tool to generate the bundled manifest
274    set_target_properties(cxx_shared PROPERTIES
275                          APPEND_STRING PROPERTY LINK_FLAGS " /MANIFEST:NO")
276  endif()
277endif()
278
279set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
280
281# Build the static library.
282if (LIBCXX_ENABLE_STATIC)
283  add_library(cxx_static STATIC ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
284  target_include_directories(cxx_static PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
285  target_link_libraries(cxx_static PUBLIC cxx-headers
286                                   PRIVATE ${LIBCXX_LIBRARIES}
287                                   PRIVATE libcxx-abi-static)
288  set_target_properties(cxx_static
289    PROPERTIES
290      COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
291      LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
292      OUTPUT_NAME   "c++"
293  )
294  cxx_add_common_build_flags(cxx_static)
295  cxx_set_common_defines(cxx_static)
296
297  if (LIBCXX_HERMETIC_STATIC_LIBRARY)
298    # If the hermetic library doesn't define the operator new/delete functions
299    # then its code shouldn't declare them with hidden visibility.  They might
300    # actually be provided by a shared library at link time.
301    if (LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
302      append_flags_if_supported(CXX_STATIC_LIBRARY_FLAGS -fvisibility-global-new-delete-hidden)
303    endif()
304    target_compile_options(cxx_static PRIVATE ${CXX_STATIC_LIBRARY_FLAGS})
305    # _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS can be defined in __config_site
306    # too. Define it in the same way here, to avoid redefinition conflicts.
307    target_compile_definitions(cxx_static PRIVATE _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=)
308  endif()
309
310  list(APPEND LIBCXX_BUILD_TARGETS "cxx_static")
311  # Attempt to merge the libc++.a archive and the ABI library archive into one.
312  if (LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY)
313    target_link_libraries(cxx_static PRIVATE libcxx-abi-static-objects)
314  endif()
315endif()
316
317# Add a meta-target for both libraries.
318add_custom_target(cxx DEPENDS ${LIBCXX_BUILD_TARGETS})
319
320set(LIBCXX_EXPERIMENTAL_SOURCES
321  experimental/memory_resource.cpp
322  format.cpp
323  )
324
325add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES})
326target_link_libraries(cxx_experimental PUBLIC cxx-headers)
327if (LIBCXX_ENABLE_SHARED)
328  target_link_libraries(cxx_experimental PRIVATE cxx_shared)
329else()
330  target_link_libraries(cxx_experimental PRIVATE cxx_static)
331endif()
332
333if (LIBCXX_HERMETIC_STATIC_LIBRARY)
334  # _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS can be defined in __config_site
335  # too. Define it in the same way here, to avoid redefinition conflicts.
336  target_compile_definitions(cxx_experimental PRIVATE _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=)
337endif()
338
339set_target_properties(cxx_experimental
340  PROPERTIES
341    COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
342    OUTPUT_NAME   "c++experimental"
343)
344cxx_add_common_build_flags(cxx_experimental)
345target_compile_options(cxx_experimental PUBLIC -D_LIBCPP_ENABLE_EXPERIMENTAL)
346
347
348if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
349  set(LIBCXX_EXTERNAL_THREADING_SUPPORT_SOURCES
350      "${CMAKE_CURRENT_SOURCE_DIR}/../test/support/external_threads.cpp")
351
352  if (LIBCXX_ENABLE_SHARED)
353    add_library(cxx_external_threads SHARED ${LIBCXX_EXTERNAL_THREADING_SUPPORT_SOURCES})
354  else()
355    add_library(cxx_external_threads STATIC ${LIBCXX_EXTERNAL_THREADING_SUPPORT_SOURCES})
356  endif()
357
358  set_target_properties(cxx_external_threads
359    PROPERTIES
360      LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
361      COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
362      OUTPUT_NAME   "c++external_threads"
363  )
364
365  target_link_libraries(cxx_external_threads PRIVATE cxx-headers)
366endif()
367
368if (LIBCXX_INSTALL_SHARED_LIBRARY)
369  install(TARGETS cxx_shared
370    ARCHIVE DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
371    LIBRARY DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
372    RUNTIME DESTINATION ${LIBCXX_INSTALL_RUNTIME_DIR} COMPONENT cxx)
373endif()
374
375if (LIBCXX_INSTALL_STATIC_LIBRARY)
376  install(TARGETS cxx_static
377    ARCHIVE DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
378    LIBRARY DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
379    RUNTIME DESTINATION ${LIBCXX_INSTALL_RUNTIME_DIR} COMPONENT cxx)
380endif()
381
382if (LIBCXX_INSTALL_LIBRARY)
383  install(TARGETS cxx_experimental
384    LIBRARY DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
385    ARCHIVE DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
386    RUNTIME DESTINATION ${LIBCXX_INSTALL_RUNTIME_DIR} COMPONENT cxx)
387endif()
388
389# NOTE: This install command must go after the cxx install command otherwise
390# it will not be executed after the library symlinks are installed.
391if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
392  install(FILES "$<TARGET_LINKER_FILE:cxx_shared>"
393    DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR}
394    COMPONENT libcxx)
395endif()
396
397if (NOT CMAKE_CONFIGURATION_TYPES)
398    if(LIBCXX_INSTALL_LIBRARY)
399      set(lib_install_target "cxx;cxx_experimental")
400    endif()
401    if(LIBCXX_INSTALL_HEADERS)
402      set(header_install_target install-cxx-headers)
403    endif()
404    if (LIBCXX_ENABLE_PARALLEL_ALGORITHMS)
405      set(pstl_install_target install-pstl)
406    endif()
407    add_custom_target(install-cxx
408                      DEPENDS ${lib_install_target}
409                              cxx_experimental
410                              ${header_install_target}
411                              ${pstl_install_target}
412                      COMMAND "${CMAKE_COMMAND}"
413                      -DCMAKE_INSTALL_COMPONENT=cxx
414                      -P "${LIBCXX_BINARY_DIR}/cmake_install.cmake")
415    add_custom_target(install-cxx-stripped
416                      DEPENDS ${lib_install_target}
417                              cxx_experimental
418                              ${header_install_target}
419                              ${pstl_install_target}
420                      COMMAND "${CMAKE_COMMAND}"
421                      -DCMAKE_INSTALL_COMPONENT=cxx
422                      -DCMAKE_INSTALL_DO_STRIP=1
423                      -P "${LIBCXX_BINARY_DIR}/cmake_install.cmake")
424endif()
425