xref: /openbsd-src/gnu/llvm/libcxx/cmake/Modules/HandleLibCXXABI.cmake (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick#===============================================================================
2*4bdff4beSrobert# Define targets for linking against the selected ABI library
3*4bdff4beSrobert#
4*4bdff4beSrobert# After including this file, the following targets are defined:
5*4bdff4beSrobert# - libcxx-abi-headers: An interface target that allows getting access to the
6*4bdff4beSrobert#                       headers of the selected ABI library.
7*4bdff4beSrobert# - libcxx-abi-shared: A target representing the selected shared ABI library.
8*4bdff4beSrobert# - libcxx-abi-static: A target representing the selected static ABI library.
9*4bdff4beSrobert#
10*4bdff4beSrobert# Furthermore, some ABI libraries also define the following target:
11*4bdff4beSrobert# - libcxx-abi-shared-objects: An object library representing a set of object files
12*4bdff4beSrobert#                              constituting the ABI library, suitable for bundling
13*4bdff4beSrobert#                              into a shared library.
14*4bdff4beSrobert# - libcxx-abi-static-objects: An object library representing a set of object files
15*4bdff4beSrobert#                              constituting the ABI library, suitable for bundling
16*4bdff4beSrobert#                              into a static library.
1746035553Spatrick#===============================================================================
1846035553Spatrick
19*4bdff4beSrobertinclude(GNUInstallDirs)
2046035553Spatrick
21*4bdff4beSrobert# This function copies the provided headers to a private directory and adds that
22*4bdff4beSrobert# path to the given INTERFACE target. That target can then be linked against to
23*4bdff4beSrobert# get access to those headers (and only those).
24*4bdff4beSrobert#
25*4bdff4beSrobert# The problem this solves is that when building against a system-provided ABI library,
26*4bdff4beSrobert# the ABI headers might live side-by-side with an actual C++ Standard Library
27*4bdff4beSrobert# installation. For that reason, we can't just add `-I <path-to-ABI-headers>`,
28*4bdff4beSrobert# since we would end up also adding the system-provided C++ Standard Library to
29*4bdff4beSrobert# the search path. Instead, what we do is copy just the ABI library headers to
30*4bdff4beSrobert# a private directory and add just that path when we build libc++.
31*4bdff4beSrobertfunction(import_private_headers target include_dirs headers)
32*4bdff4beSrobert  foreach(header ${headers})
3346035553Spatrick    set(found FALSE)
34*4bdff4beSrobert    foreach(incpath ${include_dirs})
35*4bdff4beSrobert      if (EXISTS "${incpath}/${header}")
3646035553Spatrick        set(found TRUE)
37*4bdff4beSrobert        message(STATUS "Looking for ${header} in ${incpath} - found")
38*4bdff4beSrobert        get_filename_component(dstdir ${header} PATH)
39*4bdff4beSrobert        get_filename_component(header_file ${header} NAME)
40*4bdff4beSrobert        set(src ${incpath}/${header})
41*4bdff4beSrobert        set(dst "${LIBCXX_BINARY_DIR}/private-abi-headers/${dstdir}/${header_file}")
4246035553Spatrick
4346035553Spatrick        add_custom_command(OUTPUT ${dst}
4446035553Spatrick            DEPENDS ${src}
45*4bdff4beSrobert            COMMAND ${CMAKE_COMMAND} -E make_directory "${LIBCXX_BINARY_DIR}/private-abi-headers/${dstdir}"
4646035553Spatrick            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
47*4bdff4beSrobert            COMMENT "Copying C++ ABI header ${header}")
4846035553Spatrick        list(APPEND abilib_headers "${dst}")
49037e7968Spatrick      else()
50*4bdff4beSrobert        message(STATUS "Looking for ${header} in ${incpath} - not found")
5146035553Spatrick      endif()
5246035553Spatrick    endforeach()
5346035553Spatrick    if (NOT found)
54*4bdff4beSrobert      message(WARNING "Failed to find ${header} in ${include_dirs}")
5546035553Spatrick    endif()
5646035553Spatrick  endforeach()
5746035553Spatrick
58*4bdff4beSrobert  # Work around https://gitlab.kitware.com/cmake/cmake/-/issues/18399
59*4bdff4beSrobert  add_library(${target}-generate-private-headers OBJECT ${abilib_headers})
60*4bdff4beSrobert  set_target_properties(${target}-generate-private-headers PROPERTIES LINKER_LANGUAGE CXX)
6146035553Spatrick
62*4bdff4beSrobert  target_link_libraries(${target} INTERFACE ${target}-generate-private-headers)
63*4bdff4beSrobert  target_include_directories(${target} INTERFACE "${LIBCXX_BINARY_DIR}/private-abi-headers")
64*4bdff4beSrobertendfunction()
6546035553Spatrick
66*4bdff4beSrobert# This function creates an imported static library named <target>.
67*4bdff4beSrobert# It imports a library named <name> searched at the given <path>.
68*4bdff4beSrobertfunction(import_static_library target path name)
69*4bdff4beSrobert  add_library(${target} STATIC IMPORTED GLOBAL)
70*4bdff4beSrobert  find_library(file
71*4bdff4beSrobert    NAMES "${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}"
72*4bdff4beSrobert    PATHS "${path}"
73*4bdff4beSrobert    NO_CACHE)
74*4bdff4beSrobert  set_target_properties(${target} PROPERTIES IMPORTED_LOCATION "${file}")
75*4bdff4beSrobertendfunction()
76*4bdff4beSrobert
77*4bdff4beSrobert# This function creates an imported shared (interface) library named <target>
78*4bdff4beSrobert# for the given library <name>.
79*4bdff4beSrobertfunction(import_shared_library target name)
80*4bdff4beSrobert  add_library(${target} INTERFACE IMPORTED GLOBAL)
81*4bdff4beSrobert  set_target_properties(${target} PROPERTIES IMPORTED_LIBNAME "${name}")
82*4bdff4beSrobertendfunction()
83*4bdff4beSrobert
84*4bdff4beSrobert# Link against a system-provided libstdc++
85*4bdff4beSrobertif ("${LIBCXX_CXX_ABI}" STREQUAL "libstdc++")
86*4bdff4beSrobert  add_library(libcxx-abi-headers INTERFACE)
87*4bdff4beSrobert  import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}"
88*4bdff4beSrobert    "cxxabi.h;bits/c++config.h;bits/os_defines.h;bits/cpu_defines.h;bits/cxxabi_tweaks.h;bits/cxxabi_forced.h")
89*4bdff4beSrobert  target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBSTDCXX" "-D__GLIBCXX__")
90*4bdff4beSrobert
91*4bdff4beSrobert  import_shared_library(libcxx-abi-shared stdc++)
92*4bdff4beSrobert  target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
93*4bdff4beSrobert
94*4bdff4beSrobert  import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" stdc++)
95*4bdff4beSrobert  target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers)
96*4bdff4beSrobert
97*4bdff4beSrobert# Link against a system-provided libsupc++
98*4bdff4beSrobertelseif ("${LIBCXX_CXX_ABI}" STREQUAL "libsupc++")
99*4bdff4beSrobert  add_library(libcxx-abi-headers INTERFACE)
100*4bdff4beSrobert  import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}"
101*4bdff4beSrobert    "cxxabi.h;bits/c++config.h;bits/os_defines.h;bits/cpu_defines.h;bits/cxxabi_tweaks.h;bits/cxxabi_forced.h")
102*4bdff4beSrobert  target_compile_definitions(libcxx-abi-headers INTERFACE "-D__GLIBCXX__")
103*4bdff4beSrobert
104*4bdff4beSrobert  import_shared_library(libcxx-abi-shared supc++)
105*4bdff4beSrobert  target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
106*4bdff4beSrobert
107*4bdff4beSrobert  import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" supc++)
108*4bdff4beSrobert  target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers)
109*4bdff4beSrobert
110*4bdff4beSrobert# Link against the in-tree libc++abi
111*4bdff4beSrobertelseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxabi")
112*4bdff4beSrobert  add_library(libcxx-abi-headers INTERFACE)
113*4bdff4beSrobert  target_link_libraries(libcxx-abi-headers INTERFACE cxxabi-headers)
114*4bdff4beSrobert  target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXX_BUILDING_LIBCXXABI")
115*4bdff4beSrobert
116*4bdff4beSrobert  if (TARGET cxxabi_shared)
117*4bdff4beSrobert    add_library(libcxx-abi-shared ALIAS cxxabi_shared)
11846035553Spatrick  endif()
119*4bdff4beSrobert
120*4bdff4beSrobert  if (TARGET cxxabi_static)
121*4bdff4beSrobert    add_library(libcxx-abi-static ALIAS cxxabi_static)
122*4bdff4beSrobert  endif()
123*4bdff4beSrobert
124*4bdff4beSrobert  if (TARGET cxxabi_shared_objects)
125*4bdff4beSrobert    add_library(libcxx-abi-shared-objects ALIAS cxxabi_shared_objects)
126*4bdff4beSrobert  endif()
127*4bdff4beSrobert
128*4bdff4beSrobert  if (TARGET cxxabi_static_objects)
129*4bdff4beSrobert    add_library(libcxx-abi-static-objects ALIAS cxxabi_static_objects)
130*4bdff4beSrobert  endif()
131*4bdff4beSrobert
132*4bdff4beSrobert# Link against a system-provided libc++abi
133*4bdff4beSrobertelseif ("${LIBCXX_CXX_ABI}" STREQUAL "system-libcxxabi")
134*4bdff4beSrobert  add_library(libcxx-abi-headers INTERFACE)
135*4bdff4beSrobert  import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" "cxxabi.h;__cxxabi_config.h")
136*4bdff4beSrobert  target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXX_BUILDING_LIBCXXABI")
137*4bdff4beSrobert
138*4bdff4beSrobert  import_shared_library(libcxx-abi-shared c++abi)
139*4bdff4beSrobert  target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
140*4bdff4beSrobert
141*4bdff4beSrobert  import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" c++abi)
142*4bdff4beSrobert  target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers)
143*4bdff4beSrobert
144*4bdff4beSrobert# Link against a system-provided libcxxrt
145*4bdff4beSrobertelseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxrt")
146*4bdff4beSrobert  # libcxxrt does not provide aligned new and delete operators
147*4bdff4beSrobert  # TODO: We're keeping this for backwards compatibility, but this doesn't belong here.
148*4bdff4beSrobert  set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON)
149*4bdff4beSrobert
150037e7968Spatrick  if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS)
151*4bdff4beSrobert    message(STATUS "LIBCXX_CXX_ABI_INCLUDE_PATHS not set, using /usr/include/c++/v1")
152037e7968Spatrick    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1")
153037e7968Spatrick  endif()
154*4bdff4beSrobert  add_library(libcxx-abi-headers INTERFACE)
155*4bdff4beSrobert  import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}"
156*4bdff4beSrobert    "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h")
157*4bdff4beSrobert  target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXXRT")
158*4bdff4beSrobert
159*4bdff4beSrobert  import_shared_library(libcxx-abi-shared cxxrt)
160*4bdff4beSrobert  target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
161*4bdff4beSrobert
162*4bdff4beSrobert  import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" cxxrt)
163*4bdff4beSrobert  target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers)
164*4bdff4beSrobert
165*4bdff4beSrobert# Link against a system-provided vcruntime
166*4bdff4beSrobert# FIXME: Figure out how to configure the ABI library on Windows.
167*4bdff4beSrobertelseif ("${LIBCXX_CXX_ABI}" STREQUAL "vcruntime")
168*4bdff4beSrobert  add_library(libcxx-abi-headers INTERFACE)
169*4bdff4beSrobert  add_library(libcxx-abi-shared INTERFACE)
170*4bdff4beSrobert  add_library(libcxx-abi-static INTERFACE)
171*4bdff4beSrobert
172*4bdff4beSrobert# Don't link against any ABI library
173*4bdff4beSrobertelseif ("${LIBCXX_CXX_ABI}" STREQUAL "none")
174*4bdff4beSrobert  add_library(libcxx-abi-headers INTERFACE)
175*4bdff4beSrobert  target_compile_definitions(libcxx-abi-headers INTERFACE "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY")
176*4bdff4beSrobert
177*4bdff4beSrobert  add_library(libcxx-abi-shared INTERFACE)
178*4bdff4beSrobert  target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers)
179*4bdff4beSrobert
180*4bdff4beSrobert  add_library(libcxx-abi-static INTERFACE)
181*4bdff4beSrobert  target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers)
18246035553Spatrickendif()
183