if (POLICY CMP0001)
    cmake_policy(SET CMP0001 OLD)
endif (POLICY CMP0001)
set(CMAKE_BACKWARDS_COMPATIBILITY 2.8.12)
cmake_minimum_required(VERSION 2.8.12)
if (POLICY CMP0048)
    cmake_policy(SET CMP0048 NEW)
endif (POLICY CMP0048)
if (POLICY CMP0054)
    cmake_policy(SET CMP0054 NEW)
endif (POLICY CMP0054)
if (POLICY CMP0076)
    cmake_policy(SET CMP0076 NEW)
endif (POLICY CMP0076)

project(parLIB VERSION 2.3
        DESCRIPTION "INM ParLib is a high level library facilitating the coding of finite difference and spectral approximation weather and climate prediction models on distributed memory parallel computers."
        HOMEPAGE_URL "http://tesla.parallel.ru/debol/parlib"
        LANGUAGES C CXX Fortran)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED False)

# Force verbose make output
set(CMAKE_VERBOSE_MAKEFILE ON)
# auto-configure style checks, other CMake modules.
INCLUDE(CheckLibraryExists)
INCLUDE(CheckIncludeFile)
INCLUDE(CheckIncludeFiles)
INCLUDE(CheckTypeSize)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckCSourceCompiles)
INCLUDE(TestBigEndian)
INCLUDE(CheckSymbolExists)
INCLUDE(GetPrerequisites)
INCLUDE(CheckCCompilerFlag)
FIND_PACKAGE(PkgConfig QUIET)

# A macro to check if a C linker supports a particular flag.
MACRO(CHECK_C_LINKER_FLAG M_FLAG M_RESULT)
    SET(T_REQ_FLAG "${CMAKE_REQUIRED_FLAGS}")
    SET(CMAKE_REQUIRED_FLAGS "${M_FLAG}")
    CHECK_C_SOURCE_COMPILES("int main() {return 0;}" ${M_RESULT})
    SET(CMAKE_REQUIRED_FLAGS "${T_REQ_FLAG}")
ENDMACRO()
message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX}")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()
message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}")

# Set variable to define the build type.
INCLUDE(GenerateExportHeader)

#Global Config

##
# Default building shared libraries.
# BUILD_SHARED_LIBS is provided by/used by
# CMake directly.
##
OPTION(BUILD_SHARED_LIBS "Configure parLIB as a shared library." ON)
IF(BUILD_SHARED_LIBS)
    SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF()
OPTION(BUILD_STATIC_LIBS "Configure parLIB as a static library." ON)
#Specifying if we want to build Fortran libraries
option(BUILD_FORT_LIBS "build Fortran libraries" True)


# Set some default linux gcc & apple compiler options for
# debug builds.
IF(CMAKE_COMPILER_IS_GNUCC OR APPLE)
    # Check to see if -Wl,--no-undefined is supported.
CHECK_C_LINKER_FLAG("-Wl,--no-undefined" LIBTOOL_HAS_NO_UNDEFINED)

IF(LIBTOOL_HAS_NO_UNDEFINED)
    SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--no-undefined")
ENDIF()
SET(CMAKE_REQUIRED_FLAGS "${TMP_CMAKE_REQUIRED_FLAGS}")
ENDIF(CMAKE_COMPILER_IS_GNUCC OR APPLE)


ADD_DEFINITIONS()
#Fixing installation directories
include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
        ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
        ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
        ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})

set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables")
set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files")
if(WIN32 AND NOT CYGWIN)
    set(DEF_INSTALL_CMAKEDIR CMake)
else()
    set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME})
    foreach(p LIB BIN INCLUDE CMAKE)
        file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path )
        message(STATUS "Installing ${p} components to ${_path}")
        unset(_path)
    endforeach()
endif()
set(INSTALL_CMAKEDIR ${DEF_INSTALL_CMAKEDIR} CACHE PATH "Installation directory for CMake files")


# Suppress CRT Warnings.
# Only necessary for Windows
IF(MSVC)
    ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ENDIF()

##
# Configuration for post-install RPath
# Adapted from http://www.cmake.org/Wiki/CMake_RPATH_handling
##
IF(NOT MSVC AND BUILD_SHARED_LIBS)
    # use, i.e. don't skip the full RPATH for the build tree
    SET(CMAKE_SKIP_BUILD_RPATH  FALSE)

    # when building, don't use the install RPATH already
    # (but later on when installing)
    SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

    if(APPLE)
        set(CMAKE_MACOSX_RPATH ON)
    endif(APPLE)

    # add the automatically determined parts of the RPATH
    # which point to directories outside the build tree to the install RPATH
    SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

    # the RPATH to be used when installing,
    # but only if it's not a system directory
    LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir)
    IF("${isSystemDir}" STREQUAL "-1")
        SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
    ENDIF("${isSystemDir}" STREQUAL "-1")

ENDIF()

##
# End configuration for post-install RPath
##

# Set the appropriate compiler/architecture for universal OSX binaries.
IF(${CMAKE_SYSTEM_NAME} EQUAL "Darwin")
    SET(CMAKE_OSX_ARCHITECTURES i386;x86_64)
ENDIF(${CMAKE_SYSTEM_NAME} EQUAL "Darwin")

# Macro for replacing '/MD' with '/MT'.
# Used only on Windows, /MD tells VS to use the shared
# CRT libs, MT tells VS to use the static CRT libs.
#
# Taken From:
#   http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
#
MACRO(specify_static_crt_flag)
    SET(vars
            CMAKE_C_FLAGS
            CMAKE_C_FLAGS_DEBUG
            CMAKE_C_FLAGS_RELEASE
            CMAKE_C_FLAGS_MINSIZEREL
            CMAKE_C_FLAGS_RELWITHDEBINFO
            CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG
            CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL
            CMAKE_CXX_FLAGS_RELWITHDEBINFO)

    FOREACH(flag_var ${vars})
        IF(${flag_var} MATCHES "/MD")
            STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
        ENDIF()
    ENDFOREACH()

    FOREACH(flag_var ${vars})
        MESSAGE(STATUS " '${flag_var}': ${${flag_var}}")
    ENDFOREACH()
    MESSAGE(STATUS "")
ENDMACRO()


# Option to Build DLL
IF(WIN32)
    OPTION(ENABLE_DLL "Build a Windows DLL." ${BUILD_SHARED_LIBS})
    IF(ENABLE_DLL)
        SET(BUILD_DLL ON CACHE BOOL "")
        ADD_DEFINITIONS(-DDLL_PARLIB)
        ADD_DEFINITIONS(-DDLL_EXPORT)
        ADD_DEFINITIONS(-DUTF8PROC_DLLEXPORT)
    ENDIF()
ENDIF()

#Checks
CHECK_INCLUDE_FILE("stdio.h"   HAVE_STDIO_H)
IF(MSVC)
    CHECK_INCLUDE_FILE("io.h"      HAVE_IO_H)
ENDIF(MSVC)


enable_testing()

# A cmake script to print out information at the end of the configuration step.
MACRO(print_conf_summary)
    MESSAGE("")
    MESSAGE("")
    MESSAGE("Configuration Summary:")
    MESSAGE("")
    MESSAGE(STATUS "Building Shared Libraries:     ${BUILD_SHARED_LIBS}")
    MESSAGE(STATUS "Building Static Libraries:     ${BUILD_STATIC_LIBS}")
    MESSAGE(STATUS "Building Fortran Libraries:     ${BUILD_FORT_LIBS}")
    MESSAGE("")
    MESSAGE("Tests Enabled:              ${ENABLE_TESTS}")
    MESSAGE("")
    IF(CMAKE_PREFIX_PATH)
        MESSAGE(STATUS "CMake Prefix Path:             ${CMAKE_PREFIX_PATH}")
    ENDIF()
    MESSAGE(STATUS "CMAKE_C_COMPILER_ID:    ${CMAKE_C_COMPILER_ID}")
    MESSAGE(STATUS "CMAKE_LIB_DIR:    ${INSTALL_LIBDIR}")
    MESSAGE(STATUS "CMAKE_INCLUDE_DIR:    ${INSTALL_INCLUDEDIR}")
    MESSAGE(STATUS "Build Type:           ${CMAKE_BUILD_TYPE}")
    MESSAGE(STATUS "CMAKE_C_COMPILER:     ${CMAKE_C_COMPILER}")
    MESSAGE(STATUS "CMAKE_C_FLAGS:        ${CMAKE_C_FLAGS}")
    IF("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
        MESSAGE(STATUS "CMAKE_C_FLAGS_DEBUG:  ${CMAKE_C_FLAGS_DEBUG}")
    ENDIF()
    IF("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
        MESSAGE(STATUS "CMAKE_C_FLAGS_RELEASE:   ${CMAKE_C_FLAGS_RELEASE}")
    ENDIF()
    ENDMACRO(print_conf_summary)
    # Create config.h file.
#configure_file("${parLIB_SOURCE_DIR}/config.h.cmake.in"
#        "${parLIB_BINARY_DIR}/config.h")
#ADD_DEFINITIONS(-DHAVE_CONFIG_H)
#INCLUDE_DIRECTORIES(${parLIB_BINARY_DIR})
# End autotools-style checs for config.h


#INSTALLATION



#Include main list
#Checking if there is an MPI library
find_package(MPI REQUIRED)
if(MPI_FOUND)
    #include(CMakePrintHelpers)
    #   cmake_print_properties(
    #           TARGETS MPI::MPI_C MPI::MPI_Fortran
    #           PROPERTIES INTERFACE_LINK_LIBRARIES )
    #set(CMAKE_C_COMPILE_FLAGS "${CMAKE_C_COMPILE_FLAGS} ${MPI_C_COMPILE_FLAGS} -std=gnu11")
    #list(REMOVE_DUPLICATES CMAKE_C_COMPILE_FLAGS)
    #set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} ${MPI_C_LINK_FLAGS} -std=gnu11")
    #list(REMOVE_DUPLICATES CMAKE_C_COMPILE_FLAGS)
    #set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} ${MPI_CXX_COMPILE_FLAGS}")
    #set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} ${MPI_CXX_LINK_FLAGS}")
    #include_directories(MPI_C_INCLUDE_PATH)
    #include_directories(MPI_CXX_INCLUDE_PATH)
    message(STATUS "Found MPI")
else()
    message(STATUS "MPI NOT FOUND PARLIB WILL NOT BE BUILD")
endif()#Checking if there is an MPI library

INCLUDE(InstallRequiredSystemLibraries)
add_subdirectory(ParLib.src)

#testing
if(BUILD_SHARED_LIBS)
add_test(NAME use_test_shared
        COMMAND $<TARGET_FILE:parlibc_test_shared>
        )
endif(BUILD_SHARED_LIBS)
if(BUILD_STATIC_LIBS)
add_test(NAME use_test_static
        COMMAND $<TARGET_FILE:parlibc_test_static>
        )
endif(BUILD_STATIC_LIBS)
if(BUILD_FORT_LIBS)
    if(BUILD_SHARED_LIBS)
        add_test(NAME use_test_fort_shared
                COMMAND $<TARGET_FILE:parlibf_test_shared>
                )
    endif(BUILD_SHARED_LIBS)
    if(BUILD_STATIC_LIBS)
        add_test(NAME use_test_fort_static
                COMMAND $<TARGET_FILE:parlibf_test_static>
                )
    endif(BUILD_STATIC_LIBS)
endif(BUILD_FORT_LIBS)


include(Ctest)

##
# Brute force, grab all of the dlls from the dependency directory,
# install them in the binary dir. Grab all of the .libs, put them
# in the libdir.
##
IF(MSVC)
    FILE(GLOB COPY_FILES ${CMAKE_PREFIX_PATH}/lib/*.lib)
    INSTALL(FILES ${COPY_FILES}
            DESTINATION ${CMAKE_INSTALL_LIBDIR}
            COMPONENT dependencies)

    FILE(GLOB COPY_FILES ${CMAKE_PREFIX_PATH}/bin/*.dll)
    STRING(REGEX REPLACE "msv[.*].dll" "" COPY_FILES "${COPY_FILES}")
    INSTALL(FILES ${COPY_FILES}
            DESTINATION ${CMAKE_INSTALL_BINDIR}
            COMPONENT dependencies)

ENDIF()

print_conf_summary()