KOKKOS_INCLUDE_DIRECTORIES(
  ${CMAKE_CURRENT_BINARY_DIR}
  ${CMAKE_CURRENT_SOURCE_DIR}
  ${KOKKOS_TOP_BUILD_DIR}
)
IF (Kokkos_ENABLE_IMPL_DESUL_ATOMICS AND NOT desul_FOUND)
  KOKKOS_INCLUDE_DIRECTORIES(
    ${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/include
  )
ENDIF()


INSTALL (DIRECTORY
  "${CMAKE_CURRENT_SOURCE_DIR}/"
  DESTINATION ${KOKKOS_HEADER_DIR}
  FILES_MATCHING
  PATTERN "*.hpp"
  PATTERN "*.h"
)

SET(KOKKOS_CORE_SRCS)
APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp)
SET(KOKKOS_CORE_HEADERS)
APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.hpp)

IF (KOKKOS_ENABLE_CUDA)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/Cuda/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Cuda/*.hpp)
ENDIF()

IF (KOKKOS_ENABLE_OPENMP)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/OpenMP/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/OpenMP/*.hpp)
ENDIF()

IF (KOKKOS_ENABLE_OPENMPTARGET)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/OpenMPTarget/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/OpenMPTarget/*.hpp)
ENDIF()

IF (KOKKOS_ENABLE_OPENACC)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/OpenACC/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/OpenACC/*.hpp)
ENDIF()

IF (KOKKOS_ENABLE_THREADS)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/Threads/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Threads/*.hpp)
ENDIF()

IF (KOKKOS_ENABLE_HIP)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/HIP/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/HIP/*.hpp)
ENDIF()

IF (KOKKOS_ENABLE_HPX)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/HPX/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/HPX/*.hpp)
ENDIF()

IF (NOT KOKKOS_ENABLE_MEMKIND)
  LIST(REMOVE_ITEM KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/impl/Kokkos_HBWSpace.cpp)
ENDIF()

IF (KOKKOS_ENABLE_SERIAL)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/Serial/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Serial/*.hpp)
ENDIF()

IF (KOKKOS_ENABLE_SYCL)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/SYCL/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/SYCL/*.hpp)
ENDIF()

IF (Kokkos_ENABLE_IMPL_DESUL_ATOMICS AND NOT desul_FOUND)
  APPEND_GLOB(KOKKOS_CORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/src/*.cpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/include/desul/*.hpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/include/desul/*/*.hpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/include/desul/*/*/*.hpp)
  APPEND_GLOB(KOKKOS_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/include/*/*/*.inc*)

  INSTALL (DIRECTORY
    "${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/include/desul"
    DESTINATION ${KOKKOS_HEADER_DIR}
    FILES_MATCHING
    PATTERN "*.inc"
    PATTERN "*.inc_*"
    PATTERN "*.hpp"
  )
  MESSAGE(STATUS "Using internal desul_atomics copy")
ELSE()
  MESSAGE(STATUS "Using external desul_atomics install found at:")
  MESSAGE(STATUS "  " ${desul_DIR})
ENDIF()


KOKKOS_ADD_LIBRARY(
  kokkoscore
  SOURCES ${KOKKOS_CORE_SRCS}
  HEADERS ${KOKKOS_CORE_HEADERS}
  ADD_BUILD_OPTIONS # core should be given all the necessary compiler/linker flags
)

KOKKOS_LIB_INCLUDE_DIRECTORIES(kokkoscore
  ${KOKKOS_TOP_BUILD_DIR}
  ${CMAKE_CURRENT_BINARY_DIR}
  ${CMAKE_CURRENT_SOURCE_DIR}
)
IF (Kokkos_ENABLE_IMPL_DESUL_ATOMICS AND NOT desul_FOUND)
  KOKKOS_LIB_INCLUDE_DIRECTORIES(kokkoscore
    ${CMAKE_CURRENT_SOURCE_DIR}/../../tpls/desul/include
  )
ENDIF()

KOKKOS_LINK_TPL(kokkoscore PUBLIC HWLOC)
KOKKOS_LINK_TPL(kokkoscore PUBLIC MEMKIND)
IF (NOT KOKKOS_ENABLE_COMPILE_AS_CMAKE_LANGUAGE)
  KOKKOS_LINK_TPL(kokkoscore PUBLIC CUDA)
ENDIF()
KOKKOS_LINK_TPL(kokkoscore PUBLIC HPX)
KOKKOS_LINK_TPL(kokkoscore PUBLIC LIBDL)
KOKKOS_LINK_TPL(kokkoscore PUBLIC LIBRT)
# On *nix-like systems (Linux, macOS) we need pthread for C++ std::thread
IF (NOT WIN32)
  KOKKOS_LINK_TPL(kokkoscore PUBLIC THREADS)
ENDIF()
KOKKOS_LINK_TPL(kokkoscore PUBLIC ROCM)

# FIXME: We need a proper solution to figure out whether to enable
#        libatomic
# XL requires libatomic even for 64 bit CAS, most others only for 128
# I (CT) had removed 128bit CAS from desul to not need libatomic.
IF (Kokkos_ENABLE_IMPL_DESUL_ATOMICS AND
    (KOKKOS_ENABLE_OPENMPTARGET OR (CMAKE_CXX_COMPILER_ID STREQUAL XLClang)))
  target_link_libraries(kokkoscore PUBLIC atomic)
ENDIF()

IF (Kokkos_ENABLE_IMPL_DESUL_ATOMICS AND desul_FOUND)
  target_link_libraries(kokkoscore PUBLIC desul_atomics)
ENDIF()

KOKKOS_LINK_TPL(kokkoscore PUBLIC LIBQUADMATH)
