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