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