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