# Generic library
foreach(LOCKING IN LISTS LOCKING_VARIANTS)
  set(TARGET_NAME generic${LOCKING_SUFFIX_${LOCKING}})
  add_library(${TARGET_NAME}
    sion_generic.c
    sion_generic_apidesc.c
    sion_generic_buddy.c
    sion_generic_collective.c
    sion_generic_collective_merge.c
    sion_generic_internal.c
    sion_generic_mapped.c
  )
  target_include_directories(${TARGET_NAME}
    PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  )
  target_link_libraries(${TARGET_NAME}
    PUBLIC
    SIONlib::common${LOCKING_SUFFIX_${LOCKING}}
  )
  set(SION_LIBNAME_GENERIC lsion_${TARGET_NAME})
  set_target_properties(${TARGET_NAME} PROPERTIES
    OUTPUT_NAME ${SION_LIBNAME_GENERIC}
  )
  add_library(SIONlib::${TARGET_NAME} ALIAS ${TARGET_NAME})
  list(APPEND GENERIC_TARGETS ${TARGET_NAME})
endforeach()

set_property(TARGET generic
  PROPERTY PUBLIC_HEADER
  "${CMAKE_CURRENT_SOURCE_DIR}/sion_generic.h"
)

# MPI library
if(SIONlib_MPI OR SIONlib_OMPI)
  find_package(MPI 2.0 REQUIRED)
endif()
if(SIONlib_OMP OR SIONlib_OMPI)
  find_package(OpenMP 3.0 REQUIRED)
endif()

if(SIONlib_MPI)
  foreach(LOCKING IN LISTS LOCKING_VARIANTS)
    set(TARGET_NAME mpi${LOCKING_SUFFIX_${LOCKING}})
    add_library(${TARGET_NAME}
      sion_mpi_cb_gen.c
      sion_mpi_coll_cb_gen.c
      sion_mpi_file_check.c
      sion_mpi_gen.c
      sion_mpi_internal_gen.c
      sion_mpi_util.c
    )
    target_include_directories(${TARGET_NAME}
      PUBLIC
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
      $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
    )
    target_link_libraries(${TARGET_NAME}
      PUBLIC
      MPI::MPI_C
      SIONlib::common${LOCKING_SUFFIX_${LOCKING}}
      SIONlib::generic${LOCKING_SUFFIX_${LOCKING}}
    )
    target_compile_definitions(${TARGET_NAME}
      PUBLIC
      SION_MPI
    )
    set(SION_LIBNAME_MPI lsion_${TARGET_NAME})
    set_target_properties(${TARGET_NAME} PROPERTIES
      OUTPUT_NAME ${SION_LIBNAME_MPI}
    )
    add_library(SIONlib::${TARGET_NAME} ALIAS ${TARGET_NAME})
    list(APPEND MPI_TARGETS ${TARGET_NAME})
  endforeach()

  set_property(TARGET mpi
    PROPERTY PUBLIC_HEADER
    "${CMAKE_CURRENT_SOURCE_DIR}/sion_datatypes_mpi.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/sion_mpi.h"
  )
endif()

# OpenMP library
if(SIONlib_OMP)
  foreach(LOCKING IN LISTS LOCKING_VARIANTS)
    set(TARGET_NAME omp${LOCKING_SUFFIX_${LOCKING}})
    add_library(${TARGET_NAME}
      sion_omp_cb_gen.c
      sion_omp_gen.c
      sion_omp_internal_gen.c
    )
    target_include_directories(${TARGET_NAME}
      PUBLIC
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
      $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
    )
    target_link_libraries(${TARGET_NAME}
      PUBLIC
      OpenMP::OpenMP_C
      SIONlib::common${LOCKING_SUFFIX_${LOCKING}}
      SIONlib::generic${LOCKING_SUFFIX_${LOCKING}}
    )
    target_compile_definitions(${TARGET_NAME}
      PUBLIC
      SION_OMP
    )
    set(SION_LIBNAME_OMP lsion_${TARGET_NAME})
    set_target_properties(${TARGET_NAME} PROPERTIES
      OUTPUT_NAME ${SION_LIBNAME_OMP}
    )
    add_library(SIONlib::${TARGET_NAME} ALIAS ${TARGET_NAME})
    list(APPEND OMP_TARGETS ${TARGET_NAME})
  endforeach()

  set_property(TARGET omp
    PROPERTY PUBLIC_HEADER
    ${CMAKE_CURRENT_SOURCE_DIR}/sion_omp.h
  )
endif()

# Hybrid library
if(SIONlib_OMPI)
  foreach(LOCKING IN LISTS LOCKING_VARIANTS)
    set(TARGET_NAME ompi${LOCKING_SUFFIX_${LOCKING}})
    add_library(${TARGET_NAME}
      sion_ompi_cb_gen.c
      sion_ompi_coll_cb_gen.c
      sion_ompi_gen.c
      sion_ompi_internal_gen.c
      sion_ompi_util.c
    )
    target_include_directories(${TARGET_NAME}
      PUBLIC
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
      $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
    )
    target_link_libraries(${TARGET_NAME}
      PUBLIC
      MPI::MPI_C
      OpenMP::OpenMP_C
      SIONlib::common${LOCKING_SUFFIX_${LOCKING}}
      SIONlib::generic${LOCKING_SUFFIX_${LOCKING}}
    )
    target_compile_definitions(${TARGET_NAME}
      PUBLIC
      SION_OMPI
    )
    set(SION_LIBNAME_OMPI lsion_${TARGET_NAME})
    set_target_properties(${TARGET_NAME} PROPERTIES
      OUTPUT_NAME ${SION_LIBNAME_OMPI}
    )
    add_library(SIONlib::${TARGET_NAME} ALIAS ${TARGET_NAME})
    list(APPEND OMPI_TARGETS ${TARGET_NAME})
  endforeach()

  set_property(TARGET ompi
    PROPERTY PUBLIC_HEADER
    ${CMAKE_CURRENT_SOURCE_DIR}/sion_ompi.h
  )
endif()

install(TARGETS
  ${GENERIC_TARGETS}
  ${MPI_TARGETS}
  ${OMP_TARGETS}
  ${OMPI_TARGETS}
  EXPORT SIONlibParallelTargets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(EXPORT SIONlibParallelTargets
  FILE SIONlibParallelTargets.cmake
  NAMESPACE SIONlib::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SIONlib
)
