forked from OSchip/llvm-project
181 lines
8.4 KiB
CMake
181 lines
8.4 KiB
CMake
#===============================================================================
|
|
# 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()
|