macro(components_init)
  # components
  set(BUILD_BASE_C ON)
  set(BUILD_CBLAS ON)
  set(BUILD_LAPACKE ON)
  option(BUILD_SCALAPACK_C "Build scalapack_c component" ON)
  option(BUILD_EIGENEXA_C "Build eigenexa_c component" ON)
  option(BUILD_BASE_CXX "Build base_cxx component" ON)
  option(BUILD_LAPACK_CXX "Build lapack_cxx component" ON)
  option(BUILD_SCALAPACK_CXX "Build scalapack_cxx component" ON)
  option(BUILD_EIGENEXA_CXX "Build eigenexa_cxx component" ON)
  option(BUILD_ELPA_CXX "Build elpa_cxx component" ON)
  option(BUILD_SERIAL_DENSE_SOLVER "Build serial_dense_solver component" ON)
  option(BUILD_SERIAL_SPARSE_SOLVER "Build serial_sparse_solver component" ON)
  option(BUILD_PARALLEL_DENSE_SOLVER "Build parallel_dense_solver component" ON)
  option(BUILD_PARALLEL_SPARSE_SOLVER "Build parallel_sparse_solver component" ON)
  option(BUILD_C_BINDING "Build C bindings" ON)
  option(BUILD_Fortran_BINDING "Build Fortran binding" ON)
  option(BUILD_Python_BINDING "Build Python binding" OFF)
  option(BUILD_TESTS "Build test suites" ON)
  option(BUILD_EXAMPLES "Build examples" ON)
  option(BUILD_TUTORIALS "Build tutorials" ON)
  option(BUILD_BENCHMARKS "Build benchmark tests" OFF)
  option(BUILD_DEVELOPERS "Build codes for Rokko's developers" OFF)

  # libraries and solvers
  option(DISABLE_MPI "Disable MPI Parallelization" OFF)
  option(DISABLE_SCALAPACK "Disable ScaLAPACK Library" OFF)
  option(ENABLE_PDSYEVR "Enable pdsyevr in ScaLAPACK" OFF)
  option(DISABLE_EIGENEXA "Disable EigenExa Library" OFF)
  option(DISABLE_ELEMENTAL "Disable Elemental Library" OFF)
  option(DISABLE_ELPA "Disable ELPA Library" OFF)
  option(DISABLE_PETSC "Disable PETSc Library" OFF)
  option(DISABLE_SLEPC "Disable SLEPc Library" OFF)
  option(DISABLE_ANASAZI "Disable Anasazi Library" OFF)

  # libraries and solvers
  if(DISABLE_MPI)
    set(ROKKO_HAVE_MPI FALSE)
  else(DISABLE_MPI)
    set(ROKKO_HAVE_MPI TRUE)
  endif(DISABLE_MPI)
  if(DISABLE_SCALAPACK)
    set(ROKKO_HAVE_SCALAPACK FALSE)
  else(DISABLE_SCALAPACK)
    set(ROKKO_HAVE_SCALAPACK TRUE)
  endif(DISABLE_SCALAPACK)
  if(ENABLE_SCALAPACK_PDSYEVR)
    set(ROKKO_HAVE_SCALAPACK_PDSYEVR TRUE)
  else(ENABLE_SCALAPACK_PDSYEVR)
    set(ROKKO_HAVE_SCALAPACK_PDSYEVR FALSE)
  endif(ENABLE_SCALAPACK_PDSYEVR)
  if(DISABLE_EIGENEXA)
    set(ROKKO_HAVE_EIGENEXA FALSE)
  else(DISABLE_EIGENEXA)
    set(ROKKO_HAVE_EIGENEXA TRUE)
  endif(DISABLE_EIGENEXA)
  if(DISABLE_ELPA)
    set(ROKKO_HAVE_ELPA FALSE)
  else(DISABLE_ELPA)
    set(ROKKO_HAVE_ELPA TRUE)
  endif(DISABLE_ELPA)
  if(DISABLE_ELEMENTAL)
    set(ROKKO_HAVE_ELEMENTAL FALSE)
  else(DISABLE_ELEMENTAL)
    set(ROKKO_HAVE_ELEMENTAL TRUE)
  endif(DISABLE_ELEMENTAL)
  if(DISABLE_PETSC)
    set(ROKKO_HAVE_PETSC FALSE)
  else(DISABLE_PETSC)
    set(ROKKO_HAVE_PETSC TRUE)
  endif(DISABLE_PETSC)
  if(DISABLE_SLEPC)
    set(ROKKO_HAVE_SLEPC FALSE)
  else(DISABLE_SLEPC)
    set(ROKKO_HAVE_SLEPC TRUE)
  endif(DISABLE_SLEPC)
  if(DISABLE_ANASAZI)
    set(ROKKO_HAVE_ANASAZI FALSE)
  else(DISABLE_ANASAZI)
    set(ROKKO_HAVE_ANASAZI TRUE)
  endif(DISABLE_ANASAZI)

  # components
  set(ROKKO_HAVE_SCALAPACK_C ${BUILD_SCALAPACK_C})
  set(ROKKO_HAVE_EIGENEXA_C ${BUILD_HAVE_EIGENEXA_C})
  set(ROKKO_HAVE_BASE_CXX ${BUILD_BASE_CXX})
  set(ROKKO_HAVE_LAPACK_CXX ${BUILD_LAPACK_CXX})
  set(ROKKO_HAVE_SCALAPACK_CXX ${BUILD_SCALAPACK_CXX})
  set(ROKKO_HAVE_EIGENEXA_CXX ${BUILD_EIGENEXA_CXX})
  set(ROKKO_HAVE_ELPA_CXX ${BUILD_ELPA_CXX})
  set(ROKKO_HAVE_SERIAL_DENSE_SOLVER ${BUILD_SERIAL_DENSE_SOLVER})
  set(ROKKO_HAVE_SERIAL_SPARSE_SOLVER ${BUILD_SERIAL_SPARSE_SOLVER})
  set(ROKKO_HAVE_PARALLEL_DENSE_SOLVER ${BUILD_PARALLEL_DENSE_SOLVER})
  set(ROKKO_HAVE_PARALLEL_SPARSE_SOLVER ${BUILD_PARALLEL_SPARSE_SOLVER})
  set(ROKKO_HAVE_C_BINDING ${BUILD_C_BINDING})
  set(ROKKO_HAVE_FORTRAN_BINDING ${BUILD_Fortran_BINDING})
  set(ROKKO_HAVE_PYTHON_BINDING ${BUILD_Python_BINDING})
endmacro(components_init)

macro(components_check)
  if(NOT ROKKO_HAVE_BOOST)
    set(BUILD_BASE_CXX OFF)
    set(BUILD_LAPACK_CXX OFF)
    set(BUILD_SCALAPACK_CXX OFF)
    set(BUILD_EIGENEXA_CXX OFF)
    set(BUILD_ELPA_CXX OFF)
    set(BUILD_SERIAL_DENSE_SOLVER OFF)
    set(BUILD_SERIAL_SPARSE_SOLVER OFF)
    set(BUILD_PARALLEL_DENSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
    set(BUILD_C_BINDING OFF)
    set(BUILD_Fortran_BINDING OFF)
    set(BUILD_Python_BINDING OFF)
  endif(NOT ROKKO_HAVE_BOOST)

  if(NOT ROKKO_HAVE_MPI)
    set(BUILD_SCALAPACK_C OFF)
    set(BUILD_EIGENEXA_C OFF)
    set(BUILD_SCALAPACK_CXX OFF)
    set(BUILD_EIGENEXA_CXX OFF)
    set(BUILD_ELPA_CXX OFF)
    set(BUILD_PARALLEL_DENSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
  endif(NOT ROKKO_HAVE_MPI)

  if(NOT ROKKO_HAVE_SCALAPACK)
    set(ROKKO_HAVE_SCALAPACK_PDSYEVR FALSE)
    set(BUILD_SCALAPACK_C OFF)
    set(BUILD_EIGENEXA_C OFF)
    set(BUILD_SCALAPACK_CXX OFF)
    set(BUILD_EIGENEXA_CXX OFF)
    set(BUILD_ELPA_CXX OFF)
    set(BUILD_PARALLEL_DENSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
  endif(NOT ROKKO_HAVE_SCALAPACK)

  if(NOT ROKKO_HAVE_EIGENEXA)
    set(BUILD_EIGENEXA_C OFF)
    set(BUILD_EIGENEXA_CXX OFF)
  endif(NOT ROKKO_HAVE_EIGENEXA)

  if(NOT ROKKO_HAVE_ELPA)
    set(BUILD_ELPA_CXX OFF)
  endif(NOT ROKKO_HAVE_ELPA)

  if(NOT ROKKO_HAVE_SLEPC AND NOT ROKKO_HAVE_ANASAZI)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
  endif(NOT ROKKO_HAVE_SLEPC AND NOT ROKKO_HAVE_ANASAZI)

  if(NOT BUILD_SCALAPACK_C)
    set(BUILD_EIGENEXA_C OFF)
    set(BUILD_SCALAPACK_CXX OFF)
    set(BUILD_EIGENEXA_CXX OFF)
    set(BUILD_ELPA_CXX OFF)
    set(BUILD_PARALLEL_DENSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
  endif(NOT BUILD_SCALAPACK_C)

  if(NOT BUILD_BASE_CXX)
    set(BUILD_LAPACK_CXX OFF)
    set(BUILD_SCALAPACK_CXX OFF)
    set(BUILD_EIGENEXA_CXX OFF)
    set(BUILD_ELPA_CXX OFF)
    set(BUILD_SERIAL_DENSE_SOLVER OFF)
    set(BUILD_SERIAL_SPARSE_SOLVER OFF)
    set(BUILD_PARALLEL_DENSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
    set(BUILD_C_BINDING OFF)
    set(BUILD_Fortran_BINDING OFF)
    set(BUILD_Python_BINDING OFF)
  endif(NOT BUILD_BASE_CXX)

  if(NOT BUILD_SCALAPACK_CXX)
    set(BUILD_EIGENEXA_CXX OFF)
    set(BUILD_ELPA_CXX OFF)
    set(BUILD_PARALLEL_DENSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
  endif(NOT BUILD_SCALAPACK_CXX)

  if(NOT BUILD_SERIAL_DENSE_SOLVER)
    set(BUILD_SERIAL_SPARSE_SOLVER OFF)
    set(BUILD_PARALLEL_DENSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
    set(BUILD_C_BINDING OFF)
    set(BUILD_Fortran_BINDING OFF)
    set(BUILD_Python_BINDING OFF)
  endif(NOT BUILD_SERIAL_DENSE_SOLVER)

  if(NOT BUILD_SERIAL_SPARSE_SOLVER)
    set(BUILD_SERIAL_SPARSE_SOLVER OFF)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
  endif(NOT BUILD_SERIAL_SPARSE_SOLVER)

  if(NOT BUILD_PARALLEL_DENSE_SOLVER)
    set(BUILD_PARALLEL_SPARSE_SOLVER OFF)
  endif(NOT BUILD_PARALLEL_DENSE_SOLVER)

  if(NOT BUILD_C_BINDING)
    set(BUILD_Fortran_BINDING OFF)
  endif(NOT BUILD_C_BINDING)

  set(ROKKO_HAVE_SCALAPACK_C ${BUILD_SCALAPACK_C})
  set(ROKKO_HAVE_EIGENEXA_C ${BUILD_HAVE_EIGENEXA_C})
  set(ROKKO_HAVE_BASE_CXX ${BUILD_BASE_CXX})
  set(ROKKO_HAVE_LAPACK_CXX ${BUILD_LAPACK_CXX})
  set(ROKKO_HAVE_SCALAPACK_CXX ${BUILD_SCALAPACK_CXX})
  set(ROKKO_HAVE_EIGENEXA_CXX ${BUILD_EIGENEXA_CXX})
  set(ROKKO_HAVE_ELPA_CXX ${BUILD_ELPA_CXX})
  set(ROKKO_HAVE_SERIAL_DENSE_SOLVER ${BUILD_SERIAL_DENSE_SOLVER})
  set(ROKKO_HAVE_SERIAL_SPARSE_SOLVER ${BUILD_SERIAL_SPARSE_SOLVER})
  set(ROKKO_HAVE_PARALLEL_DENSE_SOLVER ${BUILD_PARALLEL_DENSE_SOLVER})
  set(ROKKO_HAVE_PARALLEL_SPARSE_SOLVER ${BUILD_PARALLEL_SPARSE_SOLVER})
  set(ROKKO_HAVE_C_BINDING ${BUILD_C_BINDING})
  set(ROKKO_HAVE_FORTRAN_BINDING ${BUILD_Fortran_BINDING})
  set(ROKKO_HAVE_PYTHON_BINDING ${BUILD_Python_BINDING})
endmacro(components_check)

macro(components_summary)
  message(STATUS "Solvers:")
  message(STATUS "  scalapack: " ${ROKKO_HAVE_SCALAPACK})
  message(STATUS "  eigenexa: " ${ROKKO_HAVE_EIGENEXA})
  message(STATUS "  elpa: " ${ROKKO_HAVE_ELPA})
  message(STATUS "  elemental: " ${ROKKO_HAVE_ELEMENTAL})
  message(STATUS "  slepc: " ${ROKKO_HAVE_SLEPC})
  message(STATUS "  anasazi: " ${ROKKO_HAVE_ANASAZI})

  message(STATUS "Components:")
  message(STATUS "  base_c: ON")
  message(STATUS "  cblas: ON")
  message(STATUS "  lapacke: ON")
  message(STATUS "  scalapack_c: " ${BUILD_SCALAPACK_C})
  message(STATUS "  eigenexa_c: " ${BUILD_EIGENEXA_C})
  message(STATUS "  base_cxx: " ${BUILD_BASE_CXX})
  message(STATUS "  lapack_cxx: " ${BUILD_LAPACK_CXX})
  message(STATUS "  scalapack_cxx: " ${BUILD_SCALAPACK_CXX})
  message(STATUS "  eigenexa_cxx: " ${BUILD_EIGENEXA_CXX})
  message(STATUS "  elpa_cxx: " ${BUILD_ELPA_CXX})
  message(STATUS "  serial_dense_solver: " ${BUILD_SERIAL_DENSE_SOLVER})
  message(STATUS "  serial_sparse_solver: " ${BUILD_SERIAL_SPARSE_SOLVER})
  message(STATUS "  parallel_dense_solver: " ${BUILD_PARALLEL_DENSE_SOLVER})
  message(STATUS "  parallel_sparse_solver: " ${BUILD_PARALLEL_SPARSE_SOLVER})
  message(STATUS "  c_binding: " ${BUILD_C_BINDING})
  message(STATUS "  fortran_binding: " ${BUILD_Fortran_BINDING})
  message(STATUS "  python_binding: " ${BUILD_Python_BINDING})
endmacro(components_summary)
