###
#
#  @file CMakeLists.txt
# 
#  @project MORSE
#  MORSE is a software package provided by:
#     Inria Bordeaux - Sud-Ouest,
#     Univ. of Tennessee,
#     Univ. of California Berkeley,
#     Univ. of Colorado Denver.
# 
#  @version 0.2.0
#  @author Cedric Castagnede
#  @date 13-07-2012
#   
###

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

#############################################
#                                           #
#      Force compilation out-of-source      #
#                                           #
#############################################
STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" MORSE_COMPILE_INPLACE)
IF(MORSE_COMPILE_INPLACE)
    MESSAGE(FATAL_ERROR "MORSE requires an out of source build.
  1/ remove CMakeCache.txt and CMakeFiles in ${CMAKE_SOURCE_DIR}
  2/ do mkdir build && cd build and tape cmake ../")
ENDIF(MORSE_COMPILE_INPLACE)


#############################################
#                                           #
#        Definition of the project          #
#                                           #
#############################################
PROJECT(MORSE Fortran C CXX)


#############################################
#                                           #
#      Systems checks and parameters        #
#                                           #
#############################################

# CMake can find FindFoo.cmake in this directory
# ----------------------------------------------
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/cmake-2.8-8)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/buildsystem)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/find)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/info)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/install)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/options)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/testing)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/source_generator)

# Active cmake options
# --------------------
INCLUDE(BuildSystemTools)
INCLUDE(CMakeDependentOption)
INCLUDE(CMakeDetermineSystem)
INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckSymbolExists)
INCLUDE(CheckIncludeFiles)
INCLUDE(Summary)

# Active CTEST
# ------------
INCLUDE(CTest)
ENABLE_TESTING()


#############################################
#                                           #
#     Definition of the GENERIC options     #
#                                           #
#############################################

# Define the default install directory
# ------------------------------------
IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Install directory used by install" FORCE)
ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)

# Organize output files in a tree
# -------------------------------
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MORSE_BINARY_DIR}/lib)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MORSE_BINARY_DIR}/lib)

# Set the build type
# ------------------
IF(NOT CMAKE_BUILD_TYPE)
    SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
        "Choose the type of build, options are None, Debug, Release, RelWithDebInfo and MinSizeRel." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)

# Misc options
# ------------
OPTION(BUILD_SHARED_LIBS "Build shared libraries" OFF)

# Set computed precisions
# -----------------------
OPTION(BUILD_SINGLE       "Build MORSE Single Precision"         ON)
OPTION(BUILD_DOUBLE       "Build MORSE Double Precision"         ON)
OPTION(BUILD_COMPLEX      "Build MORSE Complex Precision"        ON)
OPTION(BUILD_COMPLEX16    "Build MORSE Double Complex Precision" ON)
CMAKE_DEPENDENT_OPTION(BUILD_MIXEDREAL    "Build MORSE Mixed Real Precision"    ON
                                          "BUILD_SINGLE;BUILD_DOUBLE"           OFF)
CMAKE_DEPENDENT_OPTION(BUILD_MIXEDCOMPLEX "Build MORSE Mixed Complex Precision" ON
                                          "BUILD_COMPLEX;BUILD_COMPLEX16"       OFF)

# Define precision supported by MORSE
# -----------------------------------
IF(BUILD_SINGLE)
    LIST(APPEND MORSE_PRECISION "s")
ENDIF()

IF(BUILD_DOUBLE)
    LIST(APPEND MORSE_PRECISION "d")
ENDIF()

IF(BUILD_MIXEDREAL)
    LIST(APPEND MORSE_PRECISION "ds")
ENDIF()

IF(BUILD_COMPLEX)
    LIST(APPEND MORSE_PRECISION "c")
ENDIF()

IF(BUILD_COMPLEX16)
    LIST(APPEND MORSE_PRECISION "z")
ENDIF()

IF(BUILD_MIXEDCOMPLEX)
    LIST(APPEND MORSE_PRECISION "zc")
ENDIF()


#############################################
#                                           #
#      Definition of the MORSE options      #
#                                           #
#############################################

# MORSE options
# -------------
#OPTION(MORSE_USE_MULTICORE
#  "Enable/Disable multi-threaded kernels in MORSE" OFF)
IF(NOT MORSE_SCHED_STARPU AND NOT MORSE_SCHED_QUARK)
    OPTION(MORSE_SCHED_STARPU
          "Enable/Disable StarPU scheduler in MORSE" ON)
ELSE()
    OPTION(MORSE_SCHED_STARPU
          "Enable/Disable StarPU scheduler in MORSE" OFF)
ENDIF()
OPTION(MORSE_SCHED_QUARK
      "Enable/Disable Quark scheduler in MORSE" OFF)

OPTION(MORSE_SEPARATE_PROJECTS
       "Enable/disable the separation of different projects in the installation tree" ON)
OPTION(MORSE_DEBUG_CMAKE
       "Enable/disable the verbosity of cmake step" OFF)
OPTION(MORSE_ENABLE_TESTING
       "Enable/disable all the tests in MORSE" ON)
OPTION(MORSE_ENABLE_TIMING
       "Enable/disable all the tests in MORSE" ON)

OPTION(MORSE_NEED_GENERATION
       "Enable/disable generation form plasma" OFF)
OPTION(MORSE_IS_GENERATED
       "Enable/disable generation form plasma" OFF)


#############################################
#                                           #
#      Definition of the Poject library     #
#                                           #
#############################################

# MAGMA libraries
# ---------------
OPTION(MAGMA "Enable/Disable compilation of MAGMA mono-GPU" OFF)

# MAGMA_MORSE libraries
# ---------------------
OPTION(MAGMA_MORSE "Enable/Disable MORSE version of MAGMA" OFF)

# PASTIX libraries
# ----------------
OPTION(PASTIX "Enable/Disable PASTIX" OFF)

# PASTIX_MORSE libraries
# ----------------------
OPTION(PASTIX_MORSE "Enable/Disable MORSE version of PASTIX" OFF)

# SCALFMM libraries
# -----------------
OPTION(SCALFMM "Enable/Disable SCALFMM" OFF)

# SCALFMM_MORSE libraries
# -----------------------
OPTION(SCALFMM_MORSE "Enable/Disable MORSE version of SCALFMM" OFF)

# Define extra options for specific package
# -----------------------------------------
INCLUDE(ExtraOptions)
EXTRA_OPTIONS()


#############################################
#                                           #
#             Check the system              #
#                                           #
#############################################

# Detect the system and set specific options
# ------------------------------------------
INCLUDE(SystemDetection)

# Define Fortran mangling
# -----------------------
INCLUDE(FortranMangling)
FortranMangling()
#INCLUDE(FortranCInterface)
#FortranCInterface_HEADER(${CMAKE_CURRENT_SOURCE_DIR}/magma_morse/include/morse_mangling.h 
#                          MACRO_NAMESPACE "MORSE_"
#                          SYMBOL_NAMESPACE "MORSE_" )

# Verify if ISO C Binding is available
# ------------------------------------
INCLUDE(ISOCBinding)
ISOCBinding()

# PKG_CONFIG
# ----------
FIND_PACKAGE(PkgConfig QUIET)
IF(PKG_CONFIG_EXECUTABLE)
    MESSAGE(STATUS "Found pkg-config: ${PKG_CONFIG_EXECUTABLE}")
ELSE(PKG_CONFIG_EXECUTABLE)
    MESSAGE(STATUS "Looking for pkg-config - not found")
ENDIF(PKG_CONFIG_EXECUTABLE)

# PYTHON
# ------
FIND_PACKAGE(PythonInterp REQUIRED)


#############################################
#                                           #
#       Check options compatibility         #
#                                           #
#############################################

# Create all options and handle user's desires
# --------------------------------------------
INCLUDE(HandleOptions)
HANDLE_OPTIONS()

# Create distribiuted dependencies graph for MORSE
# ------------------------------------------------
INCLUDE(HandleDistrib)
FOREACH(_library ${MORSE_ALL_LIBRARIES};MORSE)
    CREATE_GRAPH_DISTRIB("${CMAKE_BINARY_DIR}" "${_library}")
ENDFOREACH()

# Create requested dependencies graph for MORSE_ALL_LIBRARIES
# -----------------------------------------------------------
INCLUDE(HandleDependencies)
CREATE_GRAPH_DEPENDENCIES("MORSE")


#############################################
#                                           #
#    Look for the required dependencies     #
#                                           #
#############################################

# Looking for dependencies
# ------------------------
INCLUDE(FindDependencies)
FIND_DEPENDENCIES("MORSE")

# Force installation of magma in a particular case
# ------------------------------------------------
IF(MAGMA_MORSE AND CUDA_FOUND)
    MESSAGE(STATUS "Installing MAGMA - installed as an internal project")
    SET(MAGMA ON CACHE BOOL "Enable/Disable compilation of MAGMA mono-GPU" FORCE)
ENDIF(MAGMA_MORSE AND CUDA_FOUND)


#############################################
#                                           #
#        Compilation of the MAGMA           #
#                                           #
#############################################
IF(MAGMA)
    ADD_SUBDIRECTORY(magma)
    INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/magma/include)
    INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/magma/include)
ENDIF()

#############################################
#                                           #
#     Compilation of the MAGMA_MORSE        #
#                                           #
#############################################
IF(MAGMA_MORSE)
    ADD_SUBDIRECTORY(magma_morse)
ENDIF()

#############################################
#                                           #
#    Compilation of the PASTIX_MORSE        #
#                                           #
#############################################

IF(PASTIX OR PASTIX_MORSE)
    ADD_SUBDIRECTORY(pastix_morse)
ENDIF()

#############################################
#                                           #
#    Compilation of the SCALFMM_MORSE       #
#                                           #
#############################################
IF(SCALFMM OR SCALFMM_MORSE)
    ADD_SUBDIRECTORY(scalfmm_morse)
ENDIF()

#############################################
#                                           #
#          Generate documentation           #
#                                           #
#############################################
ADD_SUBDIRECTORY(docs)

#############################################
#                                           #
#    Print the summary of configuration     #
#                                           #
#############################################
SUMMARY()

##
## @end file CMakeLists.txt
##
