##*************************************************************************##
##  CUBE        http://www.scalasca.org/                                   ##
##*************************************************************************##
##  Copyright (c) 2024                                                     ##
##  Forschungszentrum Juelich GmbH, Juelich Supercomputing Centre          ##
##                                                                         ##
##  This software may be modified and distributed under the terms of       ##
##  a BSD-style license.  See the COPYING file in the package base         ##
##  directory for details.                                                 ##
##*************************************************************************##


cmake_minimum_required(VERSION 3.16)

#####################################################################################
# get version info from build-config/VERSION or git
#####################################################################################
include(./cmake-modules/CubeWVersion.cmake)
message(STATUS "CubeW version: ${CUBEW_VERSION} revision ${CUBEW_REVISION} ${CUBEW_FULL_NAME}" )

#####################################################################################
# project settings
#####################################################################################
project(CubeW VERSION ${CUBEW_VERSION_MAJOR}.${CUBEW_VERSION_MINOR}.${CUBEW_VERSION_PATCH} LANGUAGES C CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
include(GNUInstallDirs)
set(CMAKE_CXX_STANDARD 11)

# set(CMAKE_VERBOSE_MAKEFILE ON)

# release build type is about 8 times faster than debug build type -> set as default for every cmake run
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-O2")

if (WIN32)
  add_definitions( -D__MINGW32__ )
endif()

#####################################################################################
# generate header files with version info
#####################################################################################
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake-include/cubew-version.h.in ${CMAKE_BINARY_DIR}/src/cubew-version.h @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake-include/cubew-config.h.in ${CMAKE_BINARY_DIR}/src/cubew-config.h @ONLY)
file(CREATE_LINK ${CMAKE_BINARY_DIR}/src/cubew-config.h ${CMAKE_BINARY_DIR}/src/config.h COPY_ON_ERROR SYMBOLIC)

#####################################################################################
# generate utils object library
#####################################################################################
add_subdirectory(common/utils)

#####################################################################################
# generate cubew library
#####################################################################################

set ( CUBEW_SOURCES
    src/cubew/cubew_allocs.c
    src/cubew/cubew_cartesian.c
    src/cubew/cubew_cnode.c
    src/cubew/cubew_compat_platform.c
    src/cubew/cubew_cube.c
    src/cubew/cubew_file_layout_embedded.c
    src/cubew/cubew_location.c
    src/cubew/cubew_location_group.c
    src/cubew/cubew_location_group_plain.c
    src/cubew/cubew_location_plain.c
    src/cubew/cubew_memory.c
    src/cubew/cubew_meta_data_writer.c
    src/cubew/cubew_metric.c
    src/cubew/cubew_region.c
    src/cubew/cubew_services.c
    src/cubew/cubew_system_tree_node.c
    src/cubew/cubew_system_tree_node_plain.c
    src/cubew/cubew_system_tree_writer.c
    src/cubew/cubew_tar_writing.c
)

add_library(cubew SHARED
    ${CUBEW_SOURCES}
)
target_link_libraries( cubew PRIVATE
    utils
)

target_include_directories(cubew PRIVATE
    src
    common/utils/include
    ${CMAKE_BINARY_DIR}/src
)

# include directory, which is used by external projects
target_include_directories(cubew INTERFACE
     $<INSTALL_INTERFACE:include/cubew> # cubelib headers are installed into subdirectory cubelib
)

# set library version
# SOVERSION = the oldest interface that the library is compatible with.
math(EXPR SOVERSION "${CUBEW_LIBRARY_CURRENT} - ${CUBEW_LIBRARY_AGE}")
set_target_properties(cubew
    PROPERTIES
    OUTPUT_NAME cube4w
    SOVERSION ${SOVERSION}
    VERSION ${SOVERSION}.${CUBEW_LIBRARY_AGE}.${CUBEW_LIBRARY_REVISION}
)

#####################################################################################
# optional zlib support for compression
#####################################################################################
if (WIN32)
     target_compile_definitions( cubew PUBLIC FRONTEND_CUBE_COMPRESSED_READONLY )
     target_link_libraries( cubew PUBLIC z )
else()
     set(CUBELIB_COMPRESSION "ReadOnly" CACHE STRING "Compression support (ReadOnly/ReadWrite/None)" )
     set_property(CACHE CUBELIB_COMPRESSION PROPERTY STRINGS "ReadOnly" "ReadWrite" "None")
     if (NOT CUBELIB_COMPRESSION STREQUAL "None")
          find_package(ZLIB QUIET)
          if (NOT ZLIB_FOUND)
               message("zlib is not available, compression is disabled")
          else()
               if (CUBELIB_COMPRESSION STREQUAL "ReadOnly")
                    target_compile_definitions( cubew PUBLIC FRONTEND_CUBE_COMPRESSED_READONLY )
               elseif (CUBELIB_COMPRESSION STREQUAL "ReadWrite")
                    target_compile_definitions( cubew PUBLIC FRONTEND_CUBE_COMPRESSED )
               endif()
               target_link_libraries( cubew PRIVATE ZLIB::ZLIB )
          endif()
     endif()
endif()

#####################################################################################
# install
#####################################################################################

file(GLOB CUBEW_HEADERS_PUBLIC "src/cubew/*.h")
list(APPEND CUBEW_HEADERS_PUBLIC
    ${CMAKE_BINARY_DIR}/src/cubew-version.h
)

install(TARGETS cubew
    EXPORT CubeWTargets # target CubeWTargets will be used for the cmake export configuration (see below)
    LIBRARY DESTINATION lib
)
install(FILES
    ${CUBEW_HEADERS_PUBLIC}
    DESTINATION include/cubew
)
install(FILES
    README OPEN_ISSUES
    DESTINATION share/doc/cubew
)
install(DIRECTORY
    examples/cubew/
    DESTINATION share/doc/cubew/example
)
##################################################################################
# create export configuration (required for other cmake-packages to find cubew)
##################################################################################

include(CMakePackageConfigHelpers)

# install the configuration targets for find_package()
install(EXPORT CubeWTargets
  FILE CubeWTargets.cmake
  DESTINATION lib/cmake/CubeW
)
# provide version information for find_package()
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/CubeWConfigVersion.cmake"
  VERSION ${CubeW_VERSION_MAJOR}.${CubeW_VERSION_MINOR}.${CubeW_VERSION_PATCH}
  COMPATIBILITY AnyNewerVersion
)
# create the configuration file for find_package()
configure_package_config_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/src/cmake-include/CubeWConfig.cmake.in"
  "${CMAKE_CURRENT_BINARY_DIR}/CubeWConfig.cmake"
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CubeW
)
install( FILES
    "${CMAKE_CURRENT_BINARY_DIR}/CubeWConfig.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/CubeWConfigVersion.cmake"
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CubeW
)
export( EXPORT CubeWTargets
  FILE "${CMAKE_BINARY_DIR}/CubeWTargets.cmake"
)
