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