xref: /openbsd-src/gnu/llvm/libcxx/CMakeLists.txt (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
1# See https://libcxx.llvm.org/docs/BuildingLibcxx.html for instructions on how
2# to build libcxx with CMake.
3
4#===============================================================================
5# Setup Project
6#===============================================================================
7cmake_minimum_required(VERSION 3.13.4)
8
9set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
10
11# Add path for custom modules
12list(INSERT CMAKE_MODULE_PATH 0
13  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
14  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
15  "${LLVM_COMMON_CMAKE_UTILS}"
16  "${LLVM_COMMON_CMAKE_UTILS}/Modules"
17  )
18
19set(CMAKE_FOLDER "libc++")
20
21set(LIBCXX_SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR})
22set(LIBCXX_BINARY_DIR  ${CMAKE_CURRENT_BINARY_DIR})
23set(LIBCXX_BINARY_INCLUDE_DIR "${LIBCXX_BINARY_DIR}/include/c++build")
24
25include(GNUInstallDirs)
26
27# Require out of source build.
28include(MacroEnsureOutOfSourceBuild)
29MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
30 "${PROJECT_NAME} requires an out of source build. Please create a separate
31 build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
32 )
33if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
34  message(STATUS "Configuring for clang-cl")
35  set(LIBCXX_TARGETING_CLANG_CL ON)
36endif()
37
38if (MSVC)
39  set(LIBCXX_TARGETING_MSVC ON)
40  message(STATUS "Configuring for MSVC")
41else()
42  set(LIBCXX_TARGETING_MSVC OFF)
43endif()
44
45#===============================================================================
46# Setup CMake Options
47#===============================================================================
48include(CMakeDependentOption)
49include(HandleCompilerRT)
50
51# Basic options ---------------------------------------------------------------
52option(LIBCXX_ENABLE_ASSERTIONS
53  "Enable assertions inside the compiled library, and at the same time make it the
54   default when compiling user code. Note that assertions can be enabled or disabled
55   by users in their own code regardless of this option." OFF)
56option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
57option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON)
58set(ENABLE_FILESYSTEM_DEFAULT ON)
59if (WIN32 AND NOT MINGW)
60  # Filesystem is buildable for windows, but it requires __int128 helper
61  # functions, that currently are provided by libgcc or compiler_rt builtins.
62  # These are available in MinGW environments, but not currently in MSVC
63  # environments.
64  set(ENABLE_FILESYSTEM_DEFAULT OFF)
65endif()
66option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of the main libc++ library"
67    ${ENABLE_FILESYSTEM_DEFAULT})
68option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
69option(LIBCXX_ENABLE_PARALLEL_ALGORITHMS "Enable the parallel algorithms library. This requires the PSTL to be available." OFF)
70option(LIBCXX_ENABLE_DEBUG_MODE
71  "Whether to build libc++ with the debug mode enabled.
72   By default, this is turned off. Turning it on results in a different ABI (additional
73   symbols but also potentially different layouts of types), and one should not mix code
74   built against a dylib that has debug mode and code built against a regular dylib." OFF)
75option(LIBCXX_ENABLE_RANDOM_DEVICE
76  "Whether to include support for std::random_device in the library. Disabling
77   this can be useful when building the library for platforms that don't have
78   a source of randomness, such as some embedded platforms. When this is not
79   supported, most of <random> will still be available, but std::random_device
80   will not." ON)
81option(LIBCXX_ENABLE_LOCALIZATION
82  "Whether to include support for localization in the library. Disabling
83   localization can be useful when porting to platforms that don't support
84   the C locale API (e.g. embedded). When localization is not supported,
85   several parts of the library will be disabled: <iostream>, <regex>, <locale>
86   will be completely unusable, and other parts may be only partly available." ON)
87option(LIBCXX_ENABLE_FSTREAM
88   "Whether to include support for <fstream>." ON) # TODO: Consider rolling that into LIBCXX_ENABLE_FILESYSTEM
89option(LIBCXX_ENABLE_UNICODE
90  "Whether to include support for Unicode in the library. Disabling Unicode can
91   be useful when porting to platforms that don't support UTF-8 encoding (e.g.
92   embedded)." ON)
93option(LIBCXX_ENABLE_WIDE_CHARACTERS
94  "Whether to include support for wide characters in the library. Disabling
95   wide character support can be useful when porting to platforms that don't
96   support the C functionality for wide characters. When wide characters are
97   not supported, several parts of the library will be disabled, notably the
98   wide character specializations of std::basic_string." ON)
99option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS
100  "Whether to turn on vendor availability annotations on declarations that depend
101   on definitions in a shared library. By default, we assume that we're not building
102   libc++ for any specific vendor, and we disable those annotations. Vendors wishing
103   to provide compile-time errors when using features unavailable on some version of
104   the shared library they shipped should turn this on and see `include/__availability`
105   for more details." OFF)
106option(LIBCXX_ENABLE_CLANG_TIDY "Whether to compile and run clang-tidy checks" OFF)
107
108if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
109  set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in")
110elseif(MINGW)
111  set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-mingw.cfg.in")
112elseif(WIN32) # clang-cl
113  if (LIBCXX_ENABLE_SHARED)
114    set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-clangcl.cfg.in")
115  else()
116    set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static-clangcl.cfg.in")
117  endif()
118else()
119  if (LIBCXX_ENABLE_SHARED)
120    set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared.cfg.in")
121  else()
122    set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static.cfg.in")
123  endif()
124endif()
125set(LIBCXX_TEST_CONFIG "${LIBCXX_DEFAULT_TEST_CONFIG}" CACHE STRING
126    "The path to the Lit testing configuration to use when running the tests.
127     If a relative path is provided, it is assumed to be relative to '<monorepo>/libcxx/test/configs'.")
128if (NOT IS_ABSOLUTE "${LIBCXX_TEST_CONFIG}")
129  set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/${LIBCXX_TEST_CONFIG}")
130endif()
131message(STATUS "Using libc++ testing configuration: ${LIBCXX_TEST_CONFIG}")
132set(LIBCXX_TEST_PARAMS "" CACHE STRING
133    "A list of parameters to run the Lit test suite with.")
134
135# Benchmark options -----------------------------------------------------------
136option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON)
137
138set(LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT --benchmark_min_time=0.01)
139set(LIBCXX_BENCHMARK_TEST_ARGS "${LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT}" CACHE STRING
140    "Arguments to pass when running the benchmarks using check-cxx-benchmarks")
141
142set(LIBCXX_BENCHMARK_NATIVE_STDLIB "" CACHE STRING
143        "Build the benchmarks against the specified native STL.
144         The value must be one of libc++/libstdc++")
145set(LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN "" CACHE STRING
146    "Use alternate GCC toolchain when building the native benchmarks")
147
148if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
149  if (NOT (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++"
150        OR LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++"))
151    message(FATAL_ERROR "Invalid value for LIBCXX_BENCHMARK_NATIVE_STDLIB: "
152            "'${LIBCXX_BENCHMARK_NATIVE_STDLIB}'")
153  endif()
154endif()
155
156option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS})
157set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING
158    "Define suffix of library directory name (32/64)")
159option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON)
160option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON)
161cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY
162  "Install the static libc++ library." ON
163  "LIBCXX_ENABLE_STATIC;LIBCXX_INSTALL_LIBRARY" OFF)
164cmake_dependent_option(LIBCXX_INSTALL_SHARED_LIBRARY
165  "Install the shared libc++ library." ON
166  "LIBCXX_ENABLE_SHARED;LIBCXX_INSTALL_LIBRARY" OFF)
167
168option(LIBCXX_ABI_UNSTABLE "Use the unstable ABI of libc++. This is equivalent to specifying LIBCXX_ABI_VERSION=n, where n is the not-yet-stable version." OFF)
169if (LIBCXX_ABI_UNSTABLE)
170  set(abi_version "2")
171else()
172  set(abi_version "1")
173endif()
174set(LIBCXX_ABI_VERSION "${abi_version}" CACHE STRING
175  "ABI version of libc++. Can be either 1 or 2, where 2 is currently the unstable ABI.
176   Defaults to 1 unless LIBCXX_ABI_UNSTABLE is specified, in which case this is 2.")
177set(LIBCXX_LIBRARY_VERSION "${LIBCXX_ABI_VERSION}.0" CACHE STRING
178  "Version of libc++. This will be reflected in the name of the shared library produced.
179   For example, -DLIBCXX_LIBRARY_VERSION=x.y will result in the library being named
180   libc++.x.y.dylib, along with the usual symlinks pointing to that. On Apple platforms,
181   this also controls the linker's 'current_version' property.")
182set(LIBCXX_ABI_NAMESPACE "__${LIBCXX_ABI_VERSION}" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.")
183if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*")
184  message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE must be a reserved identifier, got '${LIBCXX_ABI_NAMESPACE}'.")
185endif()
186option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.")
187option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.")
188
189set(LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION "default" CACHE STRING
190  "Override the implementation to use for comparing typeinfos. By default, this
191   is detected automatically by the library, but this option allows overriding
192   which implementation is used unconditionally.
193
194   See the documentation in <libcxx/include/typeinfo> for details on what each
195   value means.")
196set(TYPEINFO_COMPARISON_VALUES "default;1;2;3")
197if (NOT ("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" IN_LIST TYPEINFO_COMPARISON_VALUES))
198  message(FATAL_ERROR "Value '${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}' is not a valid value for
199                       LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION")
200endif()
201
202set(LIBCXX_ABI_DEFINES "" CACHE STRING "A semicolon separated list of ABI macros to define in the site config header.")
203option(LIBCXX_EXTRA_SITE_DEFINES "Extra defines to add into __config_site")
204option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
205
206option(LIBCXX_ENABLE_BACKWARDS_COMPATIBILITY_DEBUG_MODE_SYMBOLS
207  "Whether to include the old Debug mode symbols in the compiled library. This
208   is provided for backwards compatibility since the compiled library used to
209   always contain those symbols, regardless of whether the library was built
210   with the debug mode enabled. This is OFF by default, please contact the libc++
211   developers if you need to turn this on, as this will be removed in LLVM 16." OFF)
212
213# ABI Library options ---------------------------------------------------------
214if (LIBCXX_TARGETING_MSVC)
215  set(LIBCXX_DEFAULT_ABI_LIBRARY "vcruntime")
216elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
217  set(LIBCXX_DEFAULT_ABI_LIBRARY "libcxxrt")
218else()
219  set(LIBCXX_DEFAULT_ABI_LIBRARY "libcxxabi")
220endif()
221
222set(LIBCXX_SUPPORTED_ABI_LIBRARIES none libcxxabi system-libcxxabi libcxxrt libstdc++ libsupc++ vcruntime)
223set(LIBCXX_CXX_ABI "${LIBCXX_DEFAULT_ABI_LIBRARY}" CACHE STRING "Specify C++ ABI library to use. Supported values are ${LIBCXX_SUPPORTED_ABI_LIBRARIES}.")
224if (NOT "${LIBCXX_CXX_ABI}" IN_LIST LIBCXX_SUPPORTED_ABI_LIBRARIES)
225  message(FATAL_ERROR "Unsupported C++ ABI library: '${LIBCXX_CXX_ABI}'. Supported values are ${LIBCXX_SUPPORTED_ABI_LIBRARIES}.")
226endif()
227
228option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY
229  "Use a static copy of the ABI library when linking libc++.
230   This option cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT." OFF)
231
232option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY
233  "Statically link the ABI library to static library"
234  ${LIBCXX_ENABLE_STATIC_ABI_LIBRARY})
235
236option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
237  "Statically link the ABI library to shared library"
238  ${LIBCXX_ENABLE_STATIC_ABI_LIBRARY})
239
240# Generate and install a linker script inplace of libc++.so. The linker script
241# will link libc++ to the correct ABI library. This option is on by default
242# on UNIX platforms other than Apple unless
243# 'LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY' is on. This option is also
244# disabled when the ABI library is not specified or is specified to be "none".
245set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF)
246if (LLVM_HAVE_LINK_VERSION_SCRIPT AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
247      AND NOT LIBCXX_CXX_ABI STREQUAL "none"
248      AND Python3_EXECUTABLE
249      AND LIBCXX_ENABLE_SHARED)
250    set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON)
251endif()
252
253option(LIBCXX_ENABLE_ABI_LINKER_SCRIPT
254      "Use and install a linker script for the given ABI library"
255      ${ENABLE_LINKER_SCRIPT_DEFAULT_VALUE})
256
257option(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS
258  "Build libc++ with definitions for operator new/delete. These are normally
259   defined in libc++abi, but this option can be used to define them in libc++
260   instead. If you define them in libc++, make sure they are NOT defined in
261   libc++abi. Doing otherwise is an ODR violation." OFF)
262# Build libc++abi with libunwind. We need this option to determine whether to
263# link with libunwind or libgcc_s while running the test cases.
264option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF)
265
266# Target options --------------------------------------------------------------
267option(LIBCXX_BUILD_32_BITS "Build 32 bit multilib libc++. This option is not supported anymore when building the runtimes. Please specify a full triple instead." ${LLVM_BUILD_32_BITS})
268if (LIBCXX_BUILD_32_BITS)
269  message(FATAL_ERROR "LIBCXX_BUILD_32_BITS is not supported anymore when building the runtimes, please specify a full triple instead.")
270endif()
271
272# Feature options -------------------------------------------------------------
273option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON)
274option(LIBCXX_ENABLE_RTTI "Use run time type information." ON)
275option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON)
276option(LIBCXX_ENABLE_MONOTONIC_CLOCK
277  "Build libc++ with support for a monotonic clock.
278   This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
279option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF)
280option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
281option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF)
282option(LIBCXX_HAS_EXTERNAL_THREAD_API
283  "Build libc++ with an externalized threading API.
284   This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF)
285option(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY
286    "Build libc++ with an externalized threading library.
287     This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON" OFF)
288
289# Misc options ----------------------------------------------------------------
290# FIXME: Turn -pedantic back ON. It is currently off because it warns
291# about #include_next which is used everywhere.
292option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." OFF)
293option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
294option(LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS "Disable #warnings about conflicting macros." OFF)
295
296option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF)
297set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING
298    "The Profile-rt library used to build with code coverage")
299
300set(LIBCXX_CONFIGURE_IDE_DEFAULT OFF)
301if (XCODE OR MSVC_IDE)
302  set(LIBCXX_CONFIGURE_IDE_DEFAULT ON)
303endif()
304option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE"
305      ${LIBCXX_CONFIGURE_IDE_DEFAULT})
306
307set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT OFF)
308if (WIN32)
309  set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT ON)
310endif()
311option(LIBCXX_HERMETIC_STATIC_LIBRARY
312  "Do not export any symbols from the static library." ${LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT})
313
314#===============================================================================
315# Check option configurations
316#===============================================================================
317
318# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when
319# LIBCXX_ENABLE_THREADS is on.
320if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)
321  message(FATAL_ERROR "LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF"
322                      " when LIBCXX_ENABLE_THREADS is also set to OFF.")
323endif()
324
325if(NOT LIBCXX_ENABLE_THREADS)
326  if(LIBCXX_HAS_PTHREAD_API)
327    message(FATAL_ERROR "LIBCXX_HAS_PTHREAD_API can only be set to ON"
328                        " when LIBCXX_ENABLE_THREADS is also set to ON.")
329  endif()
330  if(LIBCXX_HAS_EXTERNAL_THREAD_API)
331    message(FATAL_ERROR "LIBCXX_HAS_EXTERNAL_THREAD_API can only be set to ON"
332                        " when LIBCXX_ENABLE_THREADS is also set to ON.")
333  endif()
334  if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
335    message(FATAL_ERROR "LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY can only be set "
336                        "to ON when LIBCXX_ENABLE_THREADS is also set to ON.")
337  endif()
338  if (LIBCXX_HAS_WIN32_THREAD_API)
339    message(FATAL_ERROR "LIBCXX_HAS_WIN32_THREAD_API can only be set to ON"
340                        " when LIBCXX_ENABLE_THREADS is also set to ON.")
341  endif()
342
343endif()
344
345if (LIBCXX_HAS_EXTERNAL_THREAD_API)
346  if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
347    message(FATAL_ERROR "The options LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY and "
348                        "LIBCXX_HAS_EXTERNAL_THREAD_API cannot both be ON at "
349                        "the same time")
350  endif()
351  if (LIBCXX_HAS_PTHREAD_API)
352    message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API"
353                        "and LIBCXX_HAS_PTHREAD_API cannot be both"
354                        "set to ON at the same time.")
355  endif()
356  if (LIBCXX_HAS_WIN32_THREAD_API)
357    message(FATAL_ERROR "The options LIBCXX_HAS_EXTERNAL_THREAD_API"
358                        "and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
359                        "set to ON at the same time.")
360  endif()
361endif()
362
363if (LIBCXX_HAS_PTHREAD_API)
364  if (LIBCXX_HAS_WIN32_THREAD_API)
365    message(FATAL_ERROR "The options LIBCXX_HAS_PTHREAD_API"
366                        "and LIBCXX_HAS_WIN32_THREAD_API cannot be both"
367                        "set to ON at the same time.")
368  endif()
369endif()
370
371# Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE
372# is ON.
373if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE)
374  message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE")
375endif()
376
377if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
378    if (APPLE)
379      message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT cannot be used on APPLE targets")
380    endif()
381    if (NOT LIBCXX_ENABLE_SHARED)
382      message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT is only available for shared library builds.")
383    endif()
384endif()
385
386if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
387    message(FATAL_ERROR "Conflicting options given.
388        LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY cannot be specified with
389        LIBCXX_ENABLE_ABI_LINKER_SCRIPT")
390endif()
391
392if (LIBCXX_ABI_FORCE_ITANIUM AND LIBCXX_ABI_FORCE_MICROSOFT)
393  message(FATAL_ERROR "Only one of LIBCXX_ABI_FORCE_ITANIUM and LIBCXX_ABI_FORCE_MICROSOFT can be specified.")
394endif ()
395
396#===============================================================================
397# Configure System
398#===============================================================================
399
400# TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR
401# instead of hard-coding include/c++/v1.
402
403set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE PATH
404    "Path where target-agnostic libc++ headers should be installed.")
405set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH
406    "Path where built libc++ runtime libraries should be installed.")
407
408set(LIBCXX_SHARED_OUTPUT_NAME "c++" CACHE STRING "Output name for the shared libc++ runtime library.")
409set(LIBCXX_STATIC_OUTPUT_NAME "c++" CACHE STRING "Output name for the static libc++ runtime library.")
410
411if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
412  set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
413  set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
414  set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1")
415  set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH
416      "Path where built libc++ libraries should be installed.")
417  set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH
418      "Path where target-specific libc++ headers should be installed.")
419  if(LIBCXX_LIBDIR_SUBDIR)
420    string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
421    string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
422  endif()
423else()
424  if(LLVM_LIBRARY_OUTPUT_INTDIR)
425    set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
426    set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
427  else()
428    set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
429    set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1")
430  endif()
431  set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}")
432  set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH
433      "Path where built libc++ libraries should be installed.")
434  set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE PATH
435      "Path where target-specific libc++ headers should be installed.")
436endif()
437
438file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}")
439
440set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
441set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
442set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
443
444# Declare libc++ configuration variables.
445# They are intended for use as follows:
446# LIBCXX_CXX_FLAGS: General flags for both the compiler and linker.
447# LIBCXX_COMPILE_FLAGS: Compile only flags.
448# LIBCXX_LINK_FLAGS: Linker only flags.
449# LIBCXX_LIBRARIES: libraries libc++ is linked to.
450set(LIBCXX_COMPILE_FLAGS "")
451set(LIBCXX_LINK_FLAGS "")
452set(LIBCXX_LIBRARIES "")
453set(LIBCXX_ADDITIONAL_COMPILE_FLAGS "" CACHE STRING
454    "Additional Compile only flags which can be provided in cache")
455set(LIBCXX_ADDITIONAL_LIBRARIES "" CACHE STRING
456    "Additional libraries libc++ is linked to which can be provided in cache")
457
458# Include macros for adding and removing libc++ flags.
459include(HandleLibcxxFlags)
460
461# Target flags ================================================================
462# These flags get added to CMAKE_CXX_FLAGS and CMAKE_C_FLAGS so that
463# 'config-ix' use them during feature checks. It also adds them to both
464# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'
465
466if (${CMAKE_SYSTEM_NAME} MATCHES "AIX")
467  add_target_flags_if_supported("-mdefault-visibility-export-mapping=explicit")
468  set(CMAKE_AIX_EXPORT_ALL_SYMBOLS OFF)
469endif()
470
471# Configure compiler.
472include(config-ix)
473
474# Configure coverage options.
475if (LIBCXX_GENERATE_COVERAGE)
476  include(CodeCoverage)
477  set(CMAKE_BUILD_TYPE "COVERAGE" CACHE STRING "" FORCE)
478endif()
479
480string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
481if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
482  set(LIBCXX_DEBUG_BUILD ON)
483else()
484  set(LIBCXX_DEBUG_BUILD OFF)
485endif()
486
487#===============================================================================
488# Setup Compiler Flags
489#===============================================================================
490
491include(HandleLibCXXABI) # Setup the ABI library flags
492
493# FIXME: Remove all debug flags and flags that change which Windows
494# default libraries are linked. Currently we only support linking the
495# non-debug DLLs
496remove_flags("/D_DEBUG" "/MTd" "/MDd" "/MT" "/Md")
497
498# FIXME(EricWF): See the FIXME on LIBCXX_ENABLE_PEDANTIC.
499# Remove the -pedantic flag and -Wno-pedantic and -pedantic-errors
500# so they don't get transformed into -Wno and -errors respectively.
501remove_flags(-Wno-pedantic -pedantic-errors -pedantic)
502
503# Required flags ==============================================================
504function(cxx_add_basic_build_flags target)
505
506  # Require C++20 for all targets. C++17 is needed to use aligned allocation
507  # in the dylib. C++20 is needed to use char8_t.
508  set_target_properties(${target} PROPERTIES
509    CXX_STANDARD 20
510    CXX_STANDARD_REQUIRED YES
511    CXX_EXTENSIONS NO)
512
513  # When building the dylib, don't warn for unavailable aligned allocation
514  # functions based on the deployment target -- they are always available
515  # because they are provided by the dylib itself with the exception of z/OS.
516  if (ZOS)
517    target_add_compile_flags_if_supported(${target} PRIVATE -fno-aligned-allocation)
518  else()
519    target_add_compile_flags_if_supported(${target} PRIVATE -faligned-allocation)
520  endif()
521
522  # On all systems the system c++ standard library headers need to be excluded.
523  # MSVC only has -X, which disables all default includes; including the crt.
524  # Thus, we do nothing and hope we don't accidentally include any of the C++
525  # headers
526  target_add_compile_flags_if_supported(${target} PUBLIC -nostdinc++)
527
528  # Hide all inline function definitions which have not explicitly been marked
529  # visible. This prevents new definitions for inline functions from appearing in
530  # the dylib when get ODR used by another function.
531  target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility-inlines-hidden)
532
533  # Our visibility annotations are not quite right for non-Clang compilers,
534  # so we end up not exporting all the symbols we should. In the future, we
535  # can improve the situation by providing an explicit list of exported
536  # symbols on all compilers.
537  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
538    target_add_compile_flags_if_supported(${target} PRIVATE -fvisibility=hidden)
539  endif()
540
541  if (LIBCXX_CONFIGURE_IDE)
542    # This simply allows IDE to process <experimental/coroutine>
543    target_add_compile_flags_if_supported(${target} PRIVATE -fcoroutines-ts)
544  endif()
545
546  # Let the library headers know they are currently being used to build the
547  # library.
548  target_compile_definitions(${target} PRIVATE -D_LIBCPP_BUILDING_LIBRARY)
549
550  if (NOT LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
551    target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
552  endif()
553
554  if (C_SUPPORTS_COMMENT_LIB_PRAGMA)
555    if (LIBCXX_HAS_PTHREAD_LIB)
556      target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_PTHREAD_LIB)
557    endif()
558    if (LIBCXX_HAS_RT_LIB)
559      target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_RT_LIB)
560    endif()
561  endif()
562  target_compile_options(${target} PUBLIC "${LIBCXX_ADDITIONAL_COMPILE_FLAGS}")
563endfunction()
564
565# Warning flags ===============================================================
566function(cxx_add_warning_flags target)
567  target_compile_definitions(${target} PUBLIC -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
568  if (MSVC)
569    # -W4 is the cl.exe/clang-cl equivalent of -Wall. (In cl.exe and clang-cl,
570    # -Wall is equivalent to -Weverything in GCC style compiler drivers.)
571    target_add_compile_flags_if_supported(${target} PRIVATE -W4)
572  else()
573    target_add_compile_flags_if_supported(${target} PRIVATE -Wall)
574  endif()
575  target_add_compile_flags_if_supported(${target} PRIVATE -Wextra -W -Wwrite-strings
576                                                          -Wno-unused-parameter -Wno-long-long
577                                                          -Werror=return-type -Wextra-semi -Wundef
578                                                          -Wformat-nonliteral)
579  if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
580    target_add_compile_flags_if_supported(${target} PRIVATE
581      -Wno-user-defined-literals
582      -Wno-covered-switch-default
583      -Wno-suggest-override
584    )
585    if (LIBCXX_TARGETING_CLANG_CL)
586      target_add_compile_flags_if_supported(${target} PRIVATE
587        -Wno-c++98-compat
588        -Wno-c++98-compat-pedantic
589        -Wno-c++11-compat
590        -Wno-undef
591        -Wno-reserved-id-macro
592        -Wno-gnu-include-next
593        -Wno-gcc-compat # For ignoring "'diagnose_if' is a clang extension" warnings
594        -Wno-zero-as-null-pointer-constant # FIXME: Remove this and fix all occurrences.
595        -Wno-deprecated-dynamic-exception-spec # For auto_ptr
596        -Wno-sign-conversion
597        -Wno-old-style-cast
598        -Wno-deprecated # FIXME: Remove this and fix all occurrences.
599        -Wno-shift-sign-overflow # FIXME: Why do we need this with clang-cl but not clang?
600        -Wno-double-promotion # FIXME: remove me
601      )
602    endif()
603  elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
604    target_add_compile_flags_if_supported(${target} PRIVATE
605      -Wno-attributes
606      -Wno-literal-suffix
607      -Wno-c++14-compat
608      -Wno-noexcept-type
609      -Wno-suggest-override)
610  endif()
611  if (LIBCXX_ENABLE_WERROR)
612    target_add_compile_flags_if_supported(${target} PRIVATE -Werror)
613    target_add_compile_flags_if_supported(${target} PRIVATE -WX)
614  else()
615    # TODO(EricWF) Remove this. We shouldn't be suppressing errors when -Werror is
616    # added elsewhere.
617    target_add_compile_flags_if_supported(${target} PRIVATE -Wno-error)
618  endif()
619  if (LIBCXX_ENABLE_PEDANTIC)
620    target_add_compile_flags_if_supported(${target} PRIVATE -pedantic)
621  endif()
622endfunction()
623
624# Exception flags =============================================================
625function(cxx_add_exception_flags target)
626  if (LIBCXX_ENABLE_EXCEPTIONS)
627    # Catches C++ exceptions only and tells the compiler to assume that extern C
628    # functions never throw a C++ exception.
629    target_add_compile_flags_if_supported(${target} PUBLIC -EHsc)
630  else()
631    target_add_compile_flags_if_supported(${target} PUBLIC -EHs- -EHa-)
632    target_add_compile_flags_if_supported(${target} PUBLIC -fno-exceptions)
633  endif()
634endfunction()
635
636# RTTI flags ==================================================================
637function(cxx_add_rtti_flags target)
638  if (NOT LIBCXX_ENABLE_RTTI)
639    target_add_compile_flags_if_supported(${target} PUBLIC -GR-)
640    target_add_compile_flags_if_supported(${target} PUBLIC -fno-rtti)
641  endif()
642endfunction()
643
644# Threading flags =============================================================
645if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXX_ENABLE_SHARED)
646  # Need to allow unresolved symbols if this is to work with shared library builds
647  if (APPLE)
648    add_link_flags("-undefined dynamic_lookup")
649  else()
650    # Relax this restriction from HandleLLVMOptions
651    string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
652  endif()
653endif()
654
655# Assertion flags =============================================================
656define_if(LIBCXX_DEBUG_BUILD -D_DEBUG)
657if (LIBCXX_ENABLE_ASSERTIONS AND NOT LIBCXX_DEBUG_BUILD)
658  # MSVC doesn't like _DEBUG on release builds. See PR 4379.
659  define_if_not(LIBCXX_TARGETING_MSVC -D_DEBUG)
660endif()
661
662# Modules flags ===============================================================
663# FIXME The libc++ sources are fundamentally non-modular. They need special
664# versions of the headers in order to provide C++03 and legacy ABI definitions.
665# NOTE: The public headers can be used with modules in all other contexts.
666function(cxx_add_module_flags target)
667  if (LLVM_ENABLE_MODULES)
668    # Ignore that the rest of the modules flags are now unused.
669    target_add_compile_flags_if_supported(${target} PUBLIC -Wno-unused-command-line-argument)
670    target_compile_options(${target} PUBLIC -fno-modules)
671  endif()
672endfunction()
673
674# Sanitizer flags =============================================================
675
676function(get_sanitizer_flags OUT_VAR  USE_SANITIZER)
677  set(SANITIZER_FLAGS)
678  set(USE_SANITIZER "${USE_SANITIZER}")
679  # NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC.
680  # But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do.
681  if (USE_SANITIZER AND NOT MSVC)
682    append_flags_if_supported(SANITIZER_FLAGS "-fno-omit-frame-pointer")
683    append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
684
685    if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND
686            NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
687      append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
688    endif()
689    if (USE_SANITIZER STREQUAL "Address")
690      append_flags(SANITIZER_FLAGS "-fsanitize=address")
691    elseif (USE_SANITIZER STREQUAL "HWAddress")
692      append_flags(SANITIZER_FLAGS "-fsanitize=hwaddress")
693    elseif (USE_SANITIZER MATCHES "Memory(WithOrigins)?")
694      append_flags(SANITIZER_FLAGS -fsanitize=memory)
695      if (USE_SANITIZER STREQUAL "MemoryWithOrigins")
696        append_flags(SANITIZER_FLAGS "-fsanitize-memory-track-origins")
697      endif()
698    elseif (USE_SANITIZER STREQUAL "Undefined")
699      append_flags(SANITIZER_FLAGS "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
700    elseif (USE_SANITIZER STREQUAL "Address;Undefined" OR
701            USE_SANITIZER STREQUAL "Undefined;Address")
702      append_flags(SANITIZER_FLAGS "-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
703    elseif (USE_SANITIZER STREQUAL "Thread")
704      append_flags(SANITIZER_FLAGS -fsanitize=thread)
705    elseif (USE_SANITIZER STREQUAL "DataFlow")
706      append_flags(SANITIZER_FLAGS -fsanitize=dataflow)
707    else()
708      message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${USE_SANITIZER}")
709    endif()
710  elseif(USE_SANITIZER AND MSVC)
711    message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
712  endif()
713  set(${OUT_VAR} "${SANITIZER_FLAGS}" PARENT_SCOPE)
714endfunction()
715
716get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}")
717
718# Link system libraries =======================================================
719function(cxx_link_system_libraries target)
720
721# In order to remove just libc++ from the link step
722# we need to use -nostdlib++ whenever it is supported.
723# Unfortunately this cannot be used universally because for example g++ supports
724# only -nodefaultlibs in which case all libraries will be removed and
725# all libraries but c++ have to be added in manually.
726  if (CXX_SUPPORTS_NOSTDLIBXX_FLAG)
727    target_add_link_flags_if_supported(${target} PRIVATE "-nostdlib++")
728  else()
729    target_add_link_flags_if_supported(${target} PRIVATE "-nodefaultlibs")
730    target_add_compile_flags_if_supported(${target} PRIVATE "/Zl")
731    target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib")
732  endif()
733
734  if (CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG AND LIBCXXABI_USE_LLVM_UNWINDER)
735    # If we're linking directly against the libunwind that we're building
736    # in the same invocation, don't try to link in the toolchain's
737    # default libunwind (which may be missing still).
738    target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none")
739  endif()
740
741  if (LIBCXX_HAS_SYSTEM_LIB)
742    target_link_libraries(${target} PRIVATE System)
743  endif()
744
745  if (LIBCXX_HAS_PTHREAD_LIB)
746    target_link_libraries(${target} PRIVATE pthread)
747  endif()
748
749  if (LIBCXX_HAS_C_LIB)
750    target_link_libraries(${target} PRIVATE c)
751  endif()
752
753  if (LIBCXX_HAS_M_LIB)
754    target_link_libraries(${target} PRIVATE m)
755  endif()
756
757  if (LIBCXX_HAS_RT_LIB)
758    target_link_libraries(${target} PRIVATE rt)
759  endif()
760
761  if (LIBCXX_USE_COMPILER_RT)
762    find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
763    if (LIBCXX_BUILTINS_LIBRARY)
764      target_link_libraries(${target} PRIVATE "${LIBCXX_BUILTINS_LIBRARY}")
765    endif()
766  elseif (LIBCXX_HAS_GCC_LIB)
767    target_link_libraries(${target} PRIVATE gcc)
768  elseif (LIBCXX_HAS_GCC_S_LIB)
769    target_link_libraries(${target} PRIVATE gcc_s)
770  endif()
771
772  if (LIBCXX_HAS_ATOMIC_LIB)
773    target_link_libraries(${target} PRIVATE atomic)
774  endif()
775
776  if (MINGW)
777    target_link_libraries(${target} PRIVATE "${MINGW_LIBRARIES}")
778  endif()
779
780  if (LIBCXX_TARGETING_MSVC)
781    if (LIBCXX_DEBUG_BUILD)
782      set(LIB_SUFFIX "d")
783    else()
784      set(LIB_SUFFIX "")
785    endif()
786
787    target_link_libraries(${target} PRIVATE ucrt${LIB_SUFFIX}) # Universal C runtime
788    target_link_libraries(${target} PRIVATE vcruntime${LIB_SUFFIX}) # C++ runtime
789    target_link_libraries(${target} PRIVATE msvcrt${LIB_SUFFIX}) # C runtime startup files
790    target_link_libraries(${target} PRIVATE msvcprt${LIB_SUFFIX}) # C++ standard library. Required for exception_ptr internals.
791    # Required for standards-complaint wide character formatting functions
792    # (e.g. `printfw`/`scanfw`)
793    target_link_libraries(${target} PRIVATE iso_stdio_wide_specifiers)
794  endif()
795
796  if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21)
797    target_link_libraries(${target} PUBLIC android_support)
798  endif()
799  target_link_libraries(${target} PUBLIC "${LIBCXX_ADDITIONAL_LIBRARIES}")
800endfunction()
801
802# Windows-related flags =======================================================
803function(cxx_add_windows_flags target)
804  if(WIN32 AND NOT MINGW)
805    target_compile_definitions(${target} PRIVATE
806                                 # Ignore the -MSC_VER mismatch, as we may build
807                                 # with a different compatibility version.
808                                 _ALLOW_MSC_VER_MISMATCH
809                                 # Don't check the msvcprt iterator debug levels
810                                 # as we will define the iterator types; libc++
811                                 # uses a different macro to identify the debug
812                                 # level.
813                                 _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH
814                                 # We are building the c++ runtime, don't pull in
815                                 # msvcprt.
816                                 _CRTBLD
817                                 # Don't warn on the use of "deprecated"
818                                 # "insecure" functions which are standards
819                                 # specified.
820                                 _CRT_SECURE_NO_WARNINGS
821                                 # Use the ISO conforming behaviour for conversion
822                                 # in printf, scanf.
823                                 _CRT_STDIO_ISO_WIDE_SPECIFIERS)
824    # Clang-cl shared builds don't support the experimental library.
825    # To avoid linker errors the format_error destructor is inlined for the
826    # dylib. Users can never use format in this mode.
827    # TODO FMT Remove when format becomes mainline.
828    if (LIBCXX_ENABLE_SHARED)
829      target_compile_definitions(${target} PRIVATE
830                                 _LIBCPP_INLINE_FORMAT_ERROR_DTOR)
831    endif()
832  endif()
833endfunction()
834
835# Configuration file flags =====================================================
836config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION)
837config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE)
838config_define_if(LIBCXX_ABI_FORCE_ITANIUM _LIBCPP_ABI_FORCE_ITANIUM)
839config_define_if(LIBCXX_ABI_FORCE_MICROSOFT _LIBCPP_ABI_FORCE_MICROSOFT)
840config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS)
841config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK)
842if (NOT LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION STREQUAL "default")
843  config_define("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION)
844endif()
845config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD)
846config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL)
847config_define_if(LIBCXX_HAS_WIN32_THREAD_API _LIBCPP_HAS_THREAD_API_WIN32)
848config_define_if(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL)
849config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC)
850config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
851config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITHMS)
852config_define_if_not(LIBCXX_ENABLE_FILESYSTEM _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
853config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
854config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION)
855config_define_if_not(LIBCXX_ENABLE_FSTREAM _LIBCPP_HAS_NO_FSTREAM)
856config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE)
857config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS)
858config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
859config_define_if(LIBCXX_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE)
860if (LIBCXX_ENABLE_ASSERTIONS)
861  config_define(1 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT)
862else()
863  config_define(0 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT)
864endif()
865
866if (LIBCXX_ABI_DEFINES)
867  set(abi_defines)
868  foreach (abi_define ${LIBCXX_ABI_DEFINES})
869    if (NOT abi_define MATCHES "^_LIBCPP_ABI_")
870      message(SEND_ERROR "Invalid ABI macro ${abi_define} in LIBCXX_ABI_DEFINES")
871    endif()
872    list(APPEND abi_defines "#define ${abi_define}")
873  endforeach()
874  string(REPLACE ";" "\n" abi_defines "${abi_defines}")
875  config_define(${abi_defines} _LIBCPP_ABI_DEFINES)
876endif()
877
878if (LIBCXX_EXTRA_SITE_DEFINES)
879  set(extra_site_defines)
880  foreach (extra_site_define ${LIBCXX_EXTRA_SITE_DEFINES})
881    # Allow defines such as DEFINE=VAL, transformed into "#define DEFINE VAL".
882    string(REPLACE "=" " " extra_site_define "${extra_site_define}")
883    list(APPEND extra_site_defines "#define ${extra_site_define}")
884  endforeach()
885  string(REPLACE ";" "\n" extra_site_defines "${extra_site_defines}")
886  config_define(${extra_site_defines} _LIBCPP_EXTRA_SITE_DEFINES)
887endif()
888
889# By default libc++ on Windows expects to use a shared library, which requires
890# the headers to use DLL import/export semantics. However when building a
891# static library only we modify the headers to disable DLL import/export.
892if (DEFINED WIN32 AND LIBCXX_ENABLE_STATIC AND NOT LIBCXX_ENABLE_SHARED)
893  message(STATUS "Generating custom __config for non-DLL Windows build")
894  config_define(ON _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
895endif()
896
897if (WIN32 AND LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
898  # If linking libcxxabi statically into libcxx, skip the dllimport attributes
899  # on symbols we refer to from libcxxabi.
900  add_definitions(-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS)
901endif()
902
903# Setup all common build flags =================================================
904function(cxx_add_common_build_flags target)
905  cxx_add_basic_build_flags(${target})
906  cxx_add_warning_flags(${target})
907  cxx_add_windows_flags(${target})
908  cxx_add_exception_flags(${target})
909  cxx_add_rtti_flags(${target})
910  cxx_add_module_flags(${target})
911  cxx_link_system_libraries(${target})
912endfunction()
913
914#===============================================================================
915# Setup Source Code And Tests
916#===============================================================================
917add_subdirectory(include)
918add_subdirectory(src)
919add_subdirectory(utils)
920
921set(LIBCXX_TEST_DEPS "cxx_experimental")
922
923if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
924  list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
925endif()
926
927if (LIBCXX_ENABLE_CLANG_TIDY)
928  list(APPEND LIBCXX_TEST_DEPS cxx-tidy)
929endif()
930
931if (LIBCXX_INCLUDE_BENCHMARKS)
932  add_subdirectory(benchmarks)
933endif()
934
935if (LIBCXX_INCLUDE_TESTS)
936  add_subdirectory(test)
937  add_subdirectory(lib/abi)
938endif()
939
940if (LIBCXX_INCLUDE_DOCS)
941  add_subdirectory(docs)
942endif()
943