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

include(cmake/TBPLASVars.cmake)
include(cmake/TBPLASUtils.cmake)
include(cmake/TBPLASDetectCXXCompiler.cmake)
cmake_minimum_required(VERSION ${MIN_VER_CMAKE})
tbp_check_build_dir()

# DO NOT put the following line before detecting compilers. Otherwise cmake will
# fall into infinite loop.
project("tbplas-cpp"
  VERSION ${TBPLAS_VERSION}
  DESCRIPTION "TBPLAS is an tight-binding package for large-scale simulation."
  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)
  add_compile_definitions(WITH_OPENMP)
  include(cmake/TBPLASDetectOpenMP.cmake)
endif()

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

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

# MathLib
include(cmake/TBPLASMathLib.cmake)

# I/O library
if(WITH_HDF5)
  add_compile_definitions(WITH_HDF5)
  find_package(HDF5 REQUIRED COMPONENTS CXX)
  add_compile_definitions(${HDF5_CXX_DEFINITION})
  include_directories(${HDF5_CXX_INCLUDE_DIRS})
  link_libraries(${HDF5_CXX_LIBRARIES})
endif()

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

# Save libs and executables in the same place
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Output directory for applications")

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()

# ----------------------------------------------------------------------------
# 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})
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()
