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