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