xref: /llvm-project/libcxxabi/src/CMakeLists.txt (revision ef804d8f9b4ef4ff39e873d5910e94887519bdb6)
1# Get sources
2set(LIBCXXABI_SOURCES
3  # C++ABI files
4  cxa_aux_runtime.cpp
5  cxa_default_handlers.cpp
6  cxa_demangle.cpp
7  cxa_exception_storage.cpp
8  cxa_guard.cpp
9  cxa_handlers.cpp
10  cxa_vector.cpp
11  cxa_virtual.cpp
12  # C++ STL files
13  stdlib_exception.cpp
14  stdlib_stdexcept.cpp
15  stdlib_typeinfo.cpp
16  # Internal files
17  abort_message.cpp
18  fallback_malloc.cpp
19  private_typeinfo.cpp
20)
21
22if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS)
23  list(APPEND LIBCXXABI_SOURCES
24    stdlib_new_delete.cpp
25  )
26endif()
27
28if (LIBCXXABI_ENABLE_EXCEPTIONS)
29  list(APPEND LIBCXXABI_SOURCES
30    cxa_exception.cpp
31    cxa_personality.cpp
32  )
33else()
34  list(APPEND LIBCXXABI_SOURCES
35    cxa_noexception.cpp
36  )
37endif()
38
39if (LIBCXXABI_ENABLE_THREADS AND (UNIX OR FUCHSIA) AND NOT (APPLE OR CYGWIN)
40    AND NOT (${CMAKE_SYSTEM_NAME} MATCHES "AIX"))
41  list(APPEND LIBCXXABI_SOURCES
42    cxa_thread_atexit.cpp
43  )
44endif()
45
46set(LIBCXXABI_HEADERS
47  ../include/cxxabi.h
48)
49
50# Add all the headers to the project for IDEs.
51if (MSVC_IDE OR XCODE)
52  # Force them all into the headers dir on MSVC, otherwise they end up at
53  # project scope because they don't have extensions.
54  if (MSVC_IDE)
55    source_group("Header Files" FILES ${LIBCXXABI_HEADERS})
56  endif()
57endif()
58
59# Some files depend on libc++ internals.
60include_directories("${LIBCXXABI_LIBCXX_PATH}/src")
61
62if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
63  add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL)
64endif()
65
66if (LIBCXXABI_ENABLE_FORGIVING_DYNAMIC_CAST)
67  add_definitions(-D_LIBCXXABI_FORGIVING_DYNAMIC_CAST)
68endif()
69
70if (NOT APPLE) # On Apple platforms, we always use -nostdlib++ so we don't need to re-add other libraries
71  if (LIBCXXABI_ENABLE_THREADS)
72    add_library_flags_if(LIBCXXABI_HAS_PTHREAD_LIB pthread)
73  endif()
74
75  add_library_flags_if(LIBCXXABI_HAS_C_LIB c)
76endif()
77
78if (FUCHSIA)
79    # TODO: Use CMAKE_LINK_LIBRARY_USING_FEATURE once our minimum CMake is at least 3.24
80    # https://cmake.org/cmake/help/latest/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.html
81    add_link_flags("-Wl,--push-state,--as-needed,-lzircon,--pop-state")
82endif()
83
84if (NOT LIBCXXABI_USE_COMPILER_RT)
85  add_library_flags_if(LIBCXXABI_HAS_GCC_LIB gcc)
86endif()
87if (NOT LIBCXXABI_USE_LLVM_UNWINDER)
88  add_library_flags_if(LIBCXXABI_HAS_GCC_S_LIB gcc_s)
89endif()
90
91if (MINGW)
92  # MINGW_LIBRARIES is defined in config-ix.cmake
93  list(APPEND LIBCXXABI_LIBRARIES ${MINGW_LIBRARIES})
94endif()
95if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21)
96  list(APPEND LIBCXXABI_LIBRARIES android_support)
97endif()
98
99# Setup flags.
100if (CXX_SUPPORTS_NOSTDLIBXX_FLAG)
101  add_link_flags_if_supported(-nostdlib++)
102else()
103  add_link_flags_if_supported(-nodefaultlibs)
104endif()
105
106if (CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG AND LIBCXXABI_USE_LLVM_UNWINDER)
107  # If we're linking directly against the libunwind that we're building
108  # in the same invocation, don't try to link in the toolchain's
109  # default libunwind (which may be missing still).
110  add_link_flags_if_supported(--unwindlib=none)
111endif()
112
113if ( APPLE )
114  if (LLVM_USE_SANITIZER)
115    if (("${LLVM_USE_SANITIZER}" STREQUAL "Address") OR
116        ("${LLVM_USE_SANITIZER}" STREQUAL "Address;Undefined") OR
117        ("${LLVM_USE_SANITIZER}" STREQUAL "Undefined;Address"))
118      set(LIBFILE "libclang_rt.asan_osx_dynamic.dylib")
119    elseif("${LLVM_USE_SANITIZER}" STREQUAL "Undefined")
120      set(LIBFILE "libclang_rt.ubsan_osx_dynamic.dylib")
121    elseif("${LLVM_USE_SANITIZER}" STREQUAL "Thread")
122      set(LIBFILE "libclang_rt.tsan_osx_dynamic.dylib")
123    else()
124      message(WARNING "LLVM_USE_SANITIZER=${LLVM_USE_SANITIZER} is not supported on OS X")
125    endif()
126    if (LIBFILE)
127      find_compiler_rt_library(builtins LIBCXXABI_BUILTINS_LIBRARY)
128      get_filename_component(LIBDIR "${LIBCXXABI_BUILTINS_LIBRARY}" DIRECTORY)
129      if (NOT IS_DIRECTORY "${LIBDIR}")
130        message(FATAL_ERROR "Cannot find compiler-rt directory on OS X required for LLVM_USE_SANITIZER")
131      endif()
132      set(LIBCXXABI_SANITIZER_LIBRARY "${LIBDIR}/${LIBFILE}")
133      set(LIBCXXABI_SANITIZER_LIBRARY "${LIBCXXABI_SANITIZER_LIBRARY}" PARENT_SCOPE)
134      message(STATUS "Manually linking compiler-rt library: ${LIBCXXABI_SANITIZER_LIBRARY}")
135      add_library_flags("${LIBCXXABI_SANITIZER_LIBRARY}")
136      add_link_flags("-Wl,-rpath,${LIBDIR}")
137    endif()
138  endif()
139
140  # Make sure we link in CrashReporterClient if we find it -- it's used by
141  # abort() on Apple platforms when building the system dylib.
142  find_library(CrashReporterClient NAMES libCrashReporterClient.a
143                                   PATHS "${CMAKE_OSX_SYSROOT}/usr/local/lib")
144  if (CrashReporterClient)
145    message(STATUS "Linking with CrashReporterClient at ${CrashReporterClient}")
146    add_library_flags("${CrashReporterClient}")
147  else()
148    message(STATUS "Could not find CrashReporterClient, not linking against it")
149  endif()
150endif()
151
152split_list(LIBCXXABI_COMPILE_FLAGS)
153split_list(LIBCXXABI_LINK_FLAGS)
154
155# FIXME: libc++abi.so will not link when modules are enabled because it depends
156# on symbols defined in libc++.so which has not yet been built.
157if (LLVM_ENABLE_MODULES)
158  string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
159endif()
160
161include(WarningFlags)
162
163# Build the shared library.
164add_library(cxxabi_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
165cxx_add_warning_flags(cxxabi_shared_objects ${LIBCXXABI_ENABLE_WERROR} ${LIBCXXABI_ENABLE_PEDANTIC})
166if (LIBCXXABI_USE_LLVM_UNWINDER)
167  if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY OR
168      (DEFINED LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_SHARED))
169    target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared_objects) # propagate usage requirements
170    target_sources(cxxabi_shared_objects PUBLIC $<TARGET_OBJECTS:unwind_shared_objects>)
171  else()
172    target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared)
173  endif()
174endif()
175target_link_libraries(cxxabi_shared_objects PRIVATE cxx-headers ${LIBCXXABI_LIBRARIES})
176if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG)
177  target_link_libraries(cxxabi_shared_objects PRIVATE ${LIBCXXABI_BUILTINS_LIBRARY})
178endif()
179target_link_libraries(cxxabi_shared_objects PUBLIC cxxabi-headers)
180set_target_properties(cxxabi_shared_objects
181  PROPERTIES
182    CXX_EXTENSIONS OFF
183    CXX_STANDARD 23
184    CXX_STANDARD_REQUIRED OFF # TODO: Make this REQUIRED once we don't need to accommodate the LLVM documentation builders using an ancient CMake
185    COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
186    DEFINE_SYMBOL ""
187)
188if (CMAKE_POSITION_INDEPENDENT_CODE OR NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
189  set_target_properties(cxxabi_shared_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) # must set manually because it's an object library
190endif()
191target_compile_options(cxxabi_shared_objects PRIVATE "${LIBCXXABI_ADDITIONAL_COMPILE_FLAGS}")
192
193# Build with -fsized-deallocation, which is default in recent versions of Clang.
194# TODO(LLVM 21): This can be dropped once we only support Clang >= 19.
195target_add_compile_flags_if_supported(cxxabi_shared_objects PRIVATE -fsized-deallocation)
196
197add_library(cxxabi_shared SHARED)
198set_target_properties(cxxabi_shared
199  PROPERTIES
200    EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBCXXABI_ENABLE_SHARED}>,FALSE,TRUE>"
201    LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
202    OUTPUT_NAME "${LIBCXXABI_SHARED_OUTPUT_NAME}"
203    SOVERSION "1"
204    VERSION "${LIBCXXABI_LIBRARY_VERSION}"
205)
206
207if (ZOS)
208  add_custom_command(TARGET cxxabi_shared POST_BUILD
209    COMMAND
210      ${LIBCXXABI_LIBCXX_PATH}/utils/zos_rename_dll_side_deck.sh
211      $<TARGET_LINKER_FILE_NAME:cxxabi_shared> $<TARGET_FILE_NAME:cxxabi_shared> "${LIBCXXABI_DLL_NAME}"
212    COMMENT "Rename dll name inside the side deck file"
213    WORKING_DIRECTORY $<TARGET_FILE_DIR:cxxabi_shared>
214  )
215endif ()
216
217target_link_libraries(cxxabi_shared
218  PUBLIC cxxabi_shared_objects
219  PRIVATE ${LIBCXXABI_LIBRARIES})
220
221if (LIBCXXABI_ENABLE_SHARED)
222list(APPEND LIBCXXABI_BUILD_TARGETS "cxxabi_shared")
223endif()
224if (LIBCXXABI_INSTALL_SHARED_LIBRARY)
225list(APPEND LIBCXXABI_INSTALL_TARGETS "cxxabi_shared")
226endif()
227
228# TODO: Move this to libc++'s HandleLibCXXABI.cmake since this is effectively trying to control
229#       what libc++ re-exports.
230add_library(cxxabi-reexports INTERFACE)
231function(export_symbols file)
232  # -exported_symbols_list is only available on Apple platforms
233  if (APPLE)
234    target_link_libraries(cxxabi_shared PRIVATE "-Wl,-exported_symbols_list,${file}")
235  endif()
236endfunction()
237
238function(reexport_symbols file)
239  export_symbols("${file}")
240  # -reexported_symbols_list is only available on Apple platforms
241  if (APPLE)
242    target_link_libraries(cxxabi-reexports INTERFACE "-Wl,-reexported_symbols_list,${file}")
243  endif()
244endfunction()
245
246export_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/symbols-not-reexported.exp")
247reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/cxxabiv1.exp")
248reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/fundamental-types.exp")
249reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/itanium-base.exp")
250reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/std-misc.exp")
251
252if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS)
253  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/new-delete.exp")
254endif()
255
256# Note that std:: exception types are always defined by the library regardless of
257# whether the exception runtime machinery is provided.
258reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/std-exceptions.exp")
259
260if (LIBCXXABI_ENABLE_EXCEPTIONS)
261  reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/itanium-exceptions.exp")
262
263  if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^(armv6|armv7|armv7s)$")
264    reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/personality-sjlj.exp")
265  else()
266    reexport_symbols("${CMAKE_CURRENT_SOURCE_DIR}/../lib/personality-v0.exp")
267  endif()
268endif()
269
270# Build the static library.
271add_library(cxxabi_static_objects OBJECT EXCLUDE_FROM_ALL ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
272cxx_add_warning_flags(cxxabi_static_objects ${LIBCXXABI_ENABLE_WERROR} ${LIBCXXABI_ENABLE_PEDANTIC})
273if (LIBCXXABI_USE_LLVM_UNWINDER AND LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY)
274  target_link_libraries(cxxabi_static_objects PUBLIC unwind_static_objects) # propagate usage requirements
275  target_sources(cxxabi_static_objects PUBLIC $<TARGET_OBJECTS:unwind_static_objects>)
276endif()
277target_link_libraries(cxxabi_static_objects PRIVATE cxx-headers ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
278target_link_libraries(cxxabi_static_objects PUBLIC cxxabi-headers)
279set_target_properties(cxxabi_static_objects
280  PROPERTIES
281    CXX_EXTENSIONS OFF
282    CXX_STANDARD 23
283    CXX_STANDARD_REQUIRED OFF # TODO: Make this REQUIRED once we don't need to accommodate the LLVM documentation builders using an ancient CMake
284    COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
285)
286target_compile_options(cxxabi_static_objects PRIVATE "${LIBCXXABI_ADDITIONAL_COMPILE_FLAGS}")
287
288# Build with -fsized-deallocation, which is default in recent versions of Clang.
289# TODO(LLVM 21): This can be dropped once we only support Clang >= 19.
290target_add_compile_flags_if_supported(cxxabi_static_objects PRIVATE -fsized-deallocation)
291
292if(LIBCXXABI_HERMETIC_STATIC_LIBRARY)
293  target_add_compile_flags_if_supported(cxxabi_static_objects PRIVATE -fvisibility=hidden)
294  # If the hermetic library doesn't define the operator new/delete functions
295  # then its code shouldn't declare them with hidden visibility.  They might
296  # actually be provided by a shared library at link time.
297  if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS)
298    target_add_compile_flags_if_supported(cxxabi_static_objects PRIVATE -fvisibility-global-new-delete=force-hidden)
299    if (NOT CXX_SUPPORTS_FVISIBILITY_GLOBAL_NEW_DELETE_EQ_FORCE_HIDDEN_FLAG)
300      target_add_compile_flags_if_supported(cxxabi_static_objects PRIVATE -fvisibility-global-new-delete-hidden)
301    endif()
302  endif()
303  # _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS can be defined in libcxx's
304  # __config_site too. Define it in the same way here, to avoid redefinition
305  # conflicts.
306  target_compile_definitions(cxxabi_static_objects
307    PRIVATE
308      _LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS
309      _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=)
310endif()
311
312add_library(cxxabi_static STATIC)
313if (LIBCXXABI_USE_LLVM_UNWINDER AND NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY)
314  target_link_libraries(cxxabi_static PUBLIC unwind_static)
315endif()
316set_target_properties(cxxabi_static
317  PROPERTIES
318    EXCLUDE_FROM_ALL "$<IF:$<BOOL:${LIBCXXABI_ENABLE_STATIC}>,FALSE,TRUE>"
319    LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
320    OUTPUT_NAME "${LIBCXXABI_STATIC_OUTPUT_NAME}"
321  )
322target_link_libraries(cxxabi_static
323  PUBLIC cxxabi_static_objects
324  PRIVATE ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
325
326if (LIBCXXABI_ENABLE_STATIC)
327  list(APPEND LIBCXXABI_BUILD_TARGETS "cxxabi_static")
328endif()
329if (LIBCXXABI_INSTALL_STATIC_LIBRARY)
330  list(APPEND LIBCXXABI_INSTALL_TARGETS "cxxabi_static")
331endif()
332
333# Add a meta-target for both libraries.
334add_custom_target(cxxabi DEPENDS ${LIBCXXABI_BUILD_TARGETS})
335
336if (LIBCXXABI_INSTALL_LIBRARY)
337  install(TARGETS ${LIBCXXABI_INSTALL_TARGETS}
338    LIBRARY DESTINATION ${LIBCXXABI_INSTALL_LIBRARY_DIR} COMPONENT cxxabi
339    ARCHIVE DESTINATION ${LIBCXXABI_INSTALL_LIBRARY_DIR} COMPONENT cxxabi
340    RUNTIME DESTINATION ${LIBCXXABI_INSTALL_RUNTIME_DIR} COMPONENT cxxabi
341    )
342endif()
343
344if (NOT CMAKE_CONFIGURATION_TYPES AND LIBCXXABI_INSTALL_LIBRARY)
345  add_custom_target(install-cxxabi
346    DEPENDS cxxabi install-cxxabi-headers
347    COMMAND "${CMAKE_COMMAND}"
348            -DCMAKE_INSTALL_COMPONENT=cxxabi
349            -P "${LIBCXXABI_BINARY_DIR}/cmake_install.cmake")
350  add_custom_target(install-cxxabi-stripped
351    DEPENDS cxxabi
352    COMMAND "${CMAKE_COMMAND}"
353            -DCMAKE_INSTALL_COMPONENT=cxxabi
354            -DCMAKE_INSTALL_DO_STRIP=1
355            -P "${LIBCXXABI_BINARY_DIR}/cmake_install.cmake")
356endif()
357