
#===============================================================================
# Add an ABI library if appropriate
#===============================================================================

#
# _setup_abi: Set up the build to use an ABI library
#
# Parameters:
#   abidefines: A list of defines needed to compile libc++ with the ABI library
#   abishared : The shared ABI library to link against.
#   abistatic : The static ABI library to link against.
#   abifiles  : A list of files (which may be relative paths) to copy into the
#               libc++ build tree for the build.  These files will be copied
#               twice: once into include/, so the libc++ build itself can find
#               them, and once into include/c++/v1, so that a clang built into
#               the same build area will find them.  These files will also be
#               installed alongside the libc++ headers.
#   abidirs   : A list of relative paths to create under an include directory
#               in the libc++ build directory.
#

macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs)
  list(APPEND LIBCXX_COMPILE_FLAGS ${abidefines})
  set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_CXX_ABI_INCLUDE_PATHS}"
    CACHE PATH
    "Paths to C++ ABI header directories separated by ';'." FORCE
    )
  set(LIBCXX_CXX_ABI_LIBRARY_PATH "${LIBCXX_CXX_ABI_LIBRARY_PATH}"
    CACHE PATH
    "Paths to C++ ABI library directory"
    )
  set(LIBCXX_CXX_SHARED_ABI_LIBRARY ${abishared})
  set(LIBCXX_CXX_STATIC_ABI_LIBRARY ${abistatic})
  set(LIBCXX_ABILIB_FILES ${abifiles})

  foreach(fpath ${LIBCXX_ABILIB_FILES})
    set(found FALSE)
    foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS})
      message(STATUS "Looking for ${fpath} in ${incpath}")
      if (EXISTS "${incpath}/${fpath}")
        set(found TRUE)
        message(STATUS "Looking for ${fpath} in ${incpath} - found")
        get_filename_component(dstdir ${fpath} PATH)
        get_filename_component(ifile ${fpath} NAME)
        set(src ${incpath}/${fpath})

        set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${ifile})
        add_custom_command(OUTPUT ${dst}
            DEPENDS ${src}
            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
            COMMENT "Copying C++ ABI header ${fpath}...")
        list(APPEND abilib_headers "${dst}")

        # TODO: libc++ shouldn't be responsible for copying the libc++abi
        # headers into the right location.
        set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${dstdir}/${fpath}")
        add_custom_command(OUTPUT ${dst}
            DEPENDS ${src}
            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
            COMMENT "Copying C++ ABI header ${fpath}...")
        list(APPEND abilib_headers "${dst}")

        if (LIBCXX_INSTALL_HEADERS)
          install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}"
            DESTINATION include/c++/v1/${dstdir}
            COMPONENT cxx-headers
            PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
            )
        endif()
      else()
        message(STATUS "Looking for ${fpath} in ${incpath} - not found")
      endif()
    endforeach()
    if (NOT found)
      message(WARNING "Failed to find ${fpath} in ${LIBCXX_CXX_ABI_INCLUDE_PATHS}")
    endif()
  endforeach()

  include_directories("${LIBCXX_BINARY_INCLUDE_DIR}")
  add_custom_target(cxx_abi_headers ALL DEPENDS ${abilib_headers})
  set(LIBCXX_CXX_ABI_HEADER_TARGET "cxx_abi_headers")
endmacro()


# Configure based on the selected ABI library.
if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
    "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libsupc++")
  set(_LIBSUPCXX_INCLUDE_FILES
    cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h
    bits/cxxabi_tweaks.h bits/cxxabi_forced.h
    )
  if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++")
    set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX")
    set(_LIBSUPCXX_LIBNAME stdc++)
  else()
    set(_LIBSUPCXX_DEFINES "")
    set(_LIBSUPCXX_LIBNAME supc++)
  endif()
  setup_abi_lib(
    "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}"
    "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
    )
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
  if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS)
    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_SOURCE_DIR}/../libcxxabi/include")
  endif()

  if(LIBCXX_STANDALONE_BUILD AND NOT (LIBCXX_CXX_ABI_INTREE OR HAVE_LIBCXXABI))
    set(shared c++abi)
    set(static c++abi)
  else()
    set(shared cxxabi_shared)
    set(static cxxabi_static)
  endif()

  setup_abi_lib(
    "-DLIBCXX_BUILDING_LIBCXXABI"
    "${shared}" "${static}" "cxxabi.h;__cxxabi_config.h" "")
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
  if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS)
    set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1")
  endif()
  # libcxxrt does not provide aligned new and delete operators
  set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON)
  setup_abi_lib(
    "-DLIBCXXRT"
    "cxxrt" "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
    )
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "vcruntime")
 # Nothing to do
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none")
  list(APPEND LIBCXX_COMPILE_FLAGS "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY")
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "default")
  # Nothing to do
else()
  message(FATAL_ERROR
    "Unsupported c++ abi: '${LIBCXX_CXX_ABI_LIBNAME}'. \
     Currently libstdc++, libsupc++, libcxxabi, libcxxrt, default and none are
     supported for c++ abi."
    )
endif ()
