# ----------------------------------------------------------------------------
#  Root CMake file for TBPLAS
#
#    From the off-tree build directory, invoke:
#      $ cmake <PATH_TO_TBPLAS_ROOT>
#
# ----------------------------------------------------------------------------

# DO NOT CHANGE THE ORDER OF INCLUDES!
include(cmake/TBPLASVars.cmake)
include(cmake/TBPLASUtils.cmake)
include(cmake/TBPLASDetectCompiler.cmake)
cmake_minimum_required(VERSION 3.15)
tbp_check_build_dir()

project(${TBPLAS_PROJECT_NAME}
    VERSION ${TBPLAS_VERSION_FULL}
    DESCRIPTION ${TBPLAS_DESCRIPTION}
    LANGUAGES CXX C)

# ----------------------------------------------------------------------------
# Configuration options
# ----------------------------------------------------------------------------
# Parallelization
OPTION(WITH_OPENMP "Include OpenMP support" OFF)
OPTION(WITH_MPI "Include MPI support" OFF)
OPTION(WITH_CUDA "Include NVidia CUDA support" OFF)

# Math library
# 1. Command-line arguments EIGEN_BACKEND, DIAG_BACKEND and TBPM_BACKEND controls
#    the backend of corresponding modules.
# 2. LAPACKE solver is enabled automatically if DIAG_BACKEND is mkl or openblas.
OPTION(WITH_FEAST "Include FEAST eigenvalue solver support" OFF)

# I/O library
OPTION(WITH_HDF5 "Include HDF5 support" OFF)

# Components
OPTION(BUILD_SHARED_LIBS        "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF)
OPTION(BUILD_DOCS               "Create build rules for TBPLAS Documentation" OFF)
OPTION(BUILD_TESTS              "Build accuracy & regression tests"           OFF)
OPTION(BUILD_EXAMPLES           "Build realistic examples"                    OFF)
OPTION(BUILD_PYTHON_INTERFACE   "Build Python interface"                      OFF)

# Installation
OPTION(INSTALL_C_EXAMPLES       "Install C examples"        OFF)
OPTION(INSTALL_PYTHON_EXAMPLES  "Install Python examples"   OFF)

# ----------------------------------------------------------------------------
# Library settings
# ----------------------------------------------------------------------------
# OpenMP
if(WITH_OPENMP)
    include(cmake/TBPLASDetectOpenMP.cmake)
endif()

# MPI
if(WITH_MPI)
    include(cmake/TBPLASDetectMPI.cmake)
endif()

# CUDA
if(WITH_CUDA)
  include(cmake/TBPLASDetectCUDA.cmake)
endif()

# MathLib
include(cmake/TBPLASMathLib.cmake)

# I/O library
if(WITH_HDF5)
    include(cmake/TBPLASDetectHDF5.cmake)
endif()

# Built-in 3rd party libraries
include_directories(${CMAKE_SOURCE_DIR}/3rdparty)

# Project headers
include_directories(${CMAKE_SOURCE_DIR}/sources)

# ----------------------------------------------------------------------------
#  Build & install layouts
# ----------------------------------------------------------------------------

# Save libs and executables in the same place
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin)
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/lib)
# set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib)
include(cmake/TBPLASInstallLayout.cmake)

# ----------------------------------------------------------------------------
# Process subdirectories
# ----------------------------------------------------------------------------

# Generate targets for documentation
add_subdirectory(doc)
add_subdirectory(sources)

# examples
if(BUILD_EXAMPLES)
    add_subdirectory(samples)
endif()

# tests
if(BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

# python interface
if(BUILD_PYTHON_INTERFACE)
    include(cmake/TBPLASDetectPython.cmake)
    add_subdirectory(python)
endif()

# packaging, must be included by main CMakeLists.txt after all the settings.
include(cmake/TBPLASPack.cmake)

# ----------------------------------------------------------------------------
# Echo build configurations
# ----------------------------------------------------------------------------
# C/C++ options
if(CMAKE_CXX_COMPILER_VERSION)
    set(TBPLAS_COMPILER_STR "${CMAKE_CXX_COMPILER} (ver ${CMAKE_CXX_COMPILER_VERSION})")
endif()

message(STATUS "")
message(STATUS "  C/C++:")
message(STATUS "    Built as dynamic libs?:" BUILD_SHARED_LIBS THEN YES ELSE NO)
if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD)
    message(STATUS "    C++ standard:"           "${CMAKE_CXX_STANDARD}")
endif()
message(STATUS "    C++ Compiler:"           ${CMAKE_CXX_COMPILER})
message(STATUS "    C++ flags (Release):"    ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE})
message(STATUS "    C++ flags (Debug):"      ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG})
message(STATUS "    C Compiler:"             ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1})
message(STATUS "    C flags (Release):"      ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE})
message(STATUS "    C flags (Debug):"        ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_DEBUG})
# Why is Win32 different?
if(WIN32)
    message(STATUS "    Linker flags (Release):" ${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_RELEASE})
    message(STATUS "    Linker flags (Debug):"   ${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_DEBUG})
else()
    message(STATUS "    Linker flags (Release):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_RELEASE})
    message(STATUS "    Linker flags (Debug):"   ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_DEBUG})
endif()
