### CMakeLists.txt to build PASTIX drivers
cmake_minimum_required(VERSION 2.8)

# We need some local ".h" to be included
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

### libraries to link with
set(PASTIX_LINK_DEP ${PASTIX_ORDER_LIBS} ${PASTIX_EXTRA_LIBS})
# additional MPI libraries for CXX and Fortran languages
if (PASTIX_WITH_MPI)
  if (MPI_CXX_LIBRARIES)
    list(APPEND PASTIX_LINK_DEP ${MPI_CXX_LIBRARIES})
  endif()
  if (MPI_Fortran_LIBRARIES)
    list(APPEND PASTIX_LINK_DEP ${MPI_Fortran_LIBRARIES})
  endif()
endif()
set(PASTIX_LIBRARIES matrix_drivers ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES} pastix ${PASTIX_LINK_DEP})
set(PASTIX_MURGE_LIBRARIES matrix_drivers ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES} pastix_murge pastix ${PASTIX_LINK_DEP})

# when adding the exe targets we will collect the exe names for the install
set(PASTIX_EXAMPLES_EXE_LIST)
list(APPEND PASTIX_EXAMPLES_EXE_LIST link_pastix)
# process link_pastix exe
add_executable(link_pastix link_pastix_cmake.c)
add_dependencies(link_pastix pastix_murge pastix matrix_drivers)
list(APPEND PASTIX_EXAMPLES_EXE_LIST link_pastix)
target_link_libraries(link_pastix ${PASTIX_MURGE_LIBRARIES})
set(EXAMPLES_FLOAT_HEADER utils.h utils.hpp)
set(EXAMPLES_FLOAT
  murge.c)
set(EXAMPLES_MEMTRACE)
set(EXAMPLES_FORTRAN)

# Matrix Drivers requires Fortran library
list(APPEND PASTIX_LIBRARIES_DEP matrix_drivers
  ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES})
# With clang + gfortran we also need these libraries
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  list(APPEND PASTIX_LIBRARIES_DEP gcc_ext.10.5)
endif()
list(APPEND EXAMPLES_MEMTRACE plot_memory_usage.c)
list(APPEND EXAMPLES_FLOAT
  simple.c
  simple_param.c)

if(CMAKE_CXX_COMPILER_ID)
  list(APPEND EXAMPLES_FLOAT cppsimple.cpp)
endif(CMAKE_CXX_COMPILER_ID)

if (PASTIX_EXAMPLES_USE_MPI)
  list(APPEND EXAMPLES_FLOAT
simple_dist.c
simple_dist_redist.c)
  if(CMAKE_CXX_COMPILER_ID)
list(APPEND EXAMPLES_FLOAT cppsimple_dist.cpp)
  endif(CMAKE_CXX_COMPILER_ID)
endif()

set(EXAMPLES
  do_not_redispatch_rhs.c
  step-by-step.c
  reentrant.c
  schur.c
  schur2.c
  refinement.c
  isolate_zeros.c
  algotech.c
  mult-rhs.c)

if (PASTIX_EXAMPLES_USE_MPI)
  list(APPEND EXAMPLES
mult-rhs-dist.c
step-by-step_dist.c
multi-comm.c
multi-comm-step.c
murge_sequence.c
murge-product.c)
  list(APPEND EXAMPLES_FORTRAN
fsimple.F90
fstep-by-step.F90)
endif()
list(APPEND EXAMPLES_MEMTRACE
  murge_2Dlap.c
  murge_3Dlap.c)

# Generate all precision files
foreach (_file ${EXAMPLES_FLOAT_HEADER} ${EXAMPLES_FLOAT})
  get_filename_component(_dir ${_file} PATH)
  get_filename_component(_name_we ${_file} NAME_WE)
  get_filename_component(_ext ${_file} EXT)

  FILE(READ ${_file} _txt)
  STRING(REPLACE "PaStiX::pastix_float_t"   "float"			 _txt "${_txt}")
  STRING(REPLACE "pastix_float_t"	    "float"			 _txt "${_txt}")
  STRING(REPLACE "MPI_PASTIX_FLOAT"	    "MPI_FLOAT"			 _txt "${_txt}")
  STRING(REPLACE "\"utils.h\""		    "\"sutils.h\""		  _txt "${_txt}")
  STRING(REPLACE "\"utils.hpp\""	    "\"sutils.hpp\""		 _txt "${_txt}")
  STRING(REPLACE " read_matrix("	    " s_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE " dread_matrix("	    " s_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE " pastix_checkMatrix("	    " s_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeNbr(" " s_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeLst(" " s_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE " cscd_redispatch("	    " s_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE " pastix("		    " s_pastix("		 _txt "${_txt}")
  STRING(REPLACE "PRINT_RHS("		    "PRINT_RHS_REAL("		 _txt "${_txt}")
  STRING(REPLACE "CONJ("		    "CONJ_REAL("		 _txt "${_txt}")
  STRING(REPLACE " dpastix("		    " s_dpastix("		 _txt "${_txt}")
  STRING(REGEX REPLACE "([^A-Za-z]*)MURGE_([A-Za-z0-9]*\\\()" "\\1SMURGE_\\2"	     _txt "${_txt}")
  STRING(REPLACE "murge.h"		    "smurge.h"			 _txt "${_txt}")
  STRING(REPLACE ":read_matrix("	    ":s_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":dread_matrix("	    ":s_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":pastix_checkMatrix("	    ":s_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeNbr(" ":s_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeLst(" ":s_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE ":cscd_redispatch("	    ":s_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE ":pastix("		    ":s_pastix("		 _txt "${_txt}")
  STRING(REPLACE ":dpastix("		    ":s_dpastix("		 _txt "${_txt}")
  FILE(WRITE ${CMAKE_BINARY_DIR}/s${_file} "${_txt}")


  FILE(READ ${_file} _txt)
  STRING(REPLACE "PaStiX::pastix_float_t"   "double"			 _txt "${_txt}")
  STRING(REPLACE "pastix_float_t"	    "double"			 _txt "${_txt}")
  STRING(REPLACE "MPI_PASTIX_FLOAT"	    "MPI_DOUBLE"		 _txt "${_txt}")
  STRING(REPLACE "\"utils.h\""		    "\"dutils.h\""		  _txt "${_txt}")
  STRING(REPLACE "\"utils.hpp\""	    "\"dutils.hpp\""		 _txt "${_txt}")
  STRING(REPLACE " read_matrix("	    " d_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE " dread_matrix("	    " d_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE " pastix_checkMatrix("	    " d_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeNbr(" " d_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeLst(" " d_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE " cscd_redispatch("	    " d_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE " pastix("		    " d_pastix("		 _txt "${_txt}")
  STRING(REPLACE "PRINT_RHS("		    "PRINT_RHS_REAL("		 _txt "${_txt}")
  STRING(REPLACE "CONJ("		    "CONJ_REAL("		 _txt "${_txt}")
  STRING(REPLACE " dpastix("		    " d_dpastix("		 _txt "${_txt}")
  STRING(REGEX REPLACE "([^A-Za-z]*)MURGE_([A-Za-z0-9]*\\\()" "\\1DMURGE_\\2"	     _txt "${_txt}")
  STRING(REPLACE "murge.h"		    "dmurge.h"			 _txt "${_txt}")
  STRING(REPLACE ":read_matrix("	    ":d_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":dread_matrix("	    ":d_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":pastix_checkMatrix("	    ":d_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeNbr(" ":d_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeLst(" ":d_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE ":cscd_redispatch("	    ":d_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE ":pastix("		    ":d_pastix("		 _txt "${_txt}")
  STRING(REPLACE ":dpastix("		    ":d_dpastix("		 _txt "${_txt}")
  FILE(WRITE ${CMAKE_BINARY_DIR}/d${_file} "${_txt}")


  FILE(READ ${_file} _txt)
  STRING(REPLACE "PaStiX::pastix_float_t"   "std::complex<float>"	 _txt "${_txt}")
  STRING(REPLACE "pastix_float_t"	    "float complex"		 _txt "${_txt}")
  STRING(REPLACE "MPI_PASTIX_FLOAT"	    "MPI_COMPLEX"		  _txt "${_txt}")
  STRING(REPLACE "\"utils.h\""		    "\"cutils.h\""		  _txt "${_txt}")
  STRING(REPLACE "\"utils.hpp\""	    "\"cutils.hpp\""		 _txt "${_txt}")
  STRING(REPLACE " read_matrix("	    " c_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE " dread_matrix("	    " c_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE " pastix_checkMatrix("	    " c_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeNbr(" " c_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeLst(" " c_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE " cscd_redispatch("	    " c_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE " pastix("		    " c_pastix("		 _txt "${_txt}")
  STRING(REPLACE "PRINT_RHS("		    "PRINT_RHS_CPLX("		 _txt "${_txt}")
  STRING(REPLACE "CONJ("		    "CONJ_CPLX("		 _txt "${_txt}")
  STRING(REPLACE " dpastix("		    " c_dpastix("		 _txt "${_txt}")
  STRING(REGEX REPLACE "([^A-Za-z]*)MURGE_([A-Za-z0-9]*\\\()" "\\1CMURGE_\\2"	     _txt "${_txt}")
  STRING(REPLACE "murge.h"		    "cmurge.h"			 _txt "${_txt}")
  STRING(REPLACE ":read_matrix("	    ":c_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":dread_matrix("	    ":c_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":pastix_checkMatrix("	    ":c_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeNbr(" ":c_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeLst(" ":c_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE ":cscd_redispatch("	    ":c_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE ":pastix("		    ":c_pastix("		 _txt "${_txt}")
  STRING(REPLACE ":dpastix("		    ":c_dpastix("		 _txt "${_txt}")
  FILE(WRITE ${CMAKE_BINARY_DIR}/c${_file} "
#define TYPE_COMPLEX
${_txt}")


  FILE(READ ${_file} _txt)
  STRING(REPLACE "PaStiX::pastix_float_t"   "std::complex<double>"	  _txt "${_txt}")
  STRING(REPLACE "pastix_float_t"	    "double complex"		  _txt "${_txt}")
  STRING(REPLACE "MPI_PASTIX_FLOAT"	    "MPI_DOUBLE_COMPLEX"		 _txt "${_txt}")
  STRING(REPLACE "\"utils.h\""		    "\"zutils.h\""		  _txt "${_txt}")
  STRING(REPLACE "\"utils.hpp\""	    "\"zutils.hpp\""		 _txt "${_txt}")
  STRING(REPLACE " read_matrix("	    " z_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE " dread_matrix("	    " z_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE " pastix_checkMatrix("	    " z_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeNbr(" " z_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE " pastix_getLocalNodeLst(" " z_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE " cscd_redispatch("	    " z_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE " pastix("		    " z_pastix("		 _txt "${_txt}")
  STRING(REPLACE "PRINT_RHS("		    "PRINT_RHS_CPLX("		 _txt "${_txt}")
  STRING(REPLACE "CONJ("		    "CONJ_CPLX("		 _txt "${_txt}")
  STRING(REPLACE " dpastix("		    " z_dpastix("		 _txt "${_txt}")
  STRING(REGEX REPLACE "([^A-Za-z]*)MURGE_([A-Za-z0-9]*\\\()" "\\1ZMURGE_\\2"	     _txt "${_txt}")
  STRING(REPLACE "murge.h"		    "zmurge.h"			 _txt "${_txt}")
  STRING(REPLACE ":read_matrix("	    ":z_read_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":dread_matrix("	    ":z_dread_matrix("		 _txt "${_txt}")
  STRING(REPLACE ":pastix_checkMatrix("	    ":z_pastix_checkMatrix("	 _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeNbr(" ":z_pastix_getLocalNodeNbr(" _txt "${_txt}")
  STRING(REPLACE ":pastix_getLocalNodeLst(" ":z_pastix_getLocalNodeLst(" _txt "${_txt}")
  STRING(REPLACE ":cscd_redispatch("	    ":z_cscd_redispatch("	 _txt "${_txt}")
  STRING(REPLACE ":pastix("		    ":z_pastix("		 _txt "${_txt}")
  STRING(REPLACE ":dpastix("		    ":z_dpastix("		 _txt "${_txt}")
  FILE(WRITE ${CMAKE_BINARY_DIR}/z${_file} "
#define TYPE_COMPLEX
${_txt}")
endforeach()

# Produce executables for all precision
foreach (_file ${EXAMPLES_FLOAT})
  get_filename_component(_dir ${_file} PATH)
  get_filename_component(_name_we ${_file} NAME_WE)
  get_filename_component(_ext ${_file} EXT)
  list(APPEND PASTIX_EXAMPLES_EXE_LIST ${_name_we})
  add_executable(${_name_we} ${_file})
  add_dependencies(${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(${_name_we} ${PASTIX_MURGE_LIBRARIES})

  list(APPEND PASTIX_EXAMPLES_EXE_LIST s${_name_we})
  add_executable(s${_name_we} ${CMAKE_BINARY_DIR}/s${_name_we}${_ext})
  add_dependencies(s${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(s${_name_we} ${PASTIX_MURGE_LIBRARIES})

  list(APPEND PASTIX_EXAMPLES_EXE_LIST d${_name_we})
  add_executable(d${_name_we} ${CMAKE_BINARY_DIR}/d${_name_we}${_ext})
  add_dependencies(d${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(d${_name_we} ${PASTIX_MURGE_LIBRARIES})

  list(APPEND PASTIX_EXAMPLES_EXE_LIST c${_name_we})
  add_executable(c${_name_we} ${CMAKE_BINARY_DIR}/c${_name_we}${_ext})
  add_dependencies(c${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(c${_name_we} ${PASTIX_MURGE_LIBRARIES})

  list(APPEND PASTIX_EXAMPLES_EXE_LIST z${_name_we})
  add_executable(z${_name_we} ${CMAKE_BINARY_DIR}/z${_name_we}${_ext})
  add_dependencies(z${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(z${_name_we} ${PASTIX_MURGE_LIBRARIES})
endforeach()

# FLOAT only precision executables
foreach (_file ${EXAMPLES})
  get_filename_component(_dir ${_file} PATH)
  get_filename_component(_name_we ${_file} NAME_WE)
  get_filename_component(_ext ${_file} EXT)
  list(APPEND PASTIX_EXAMPLES_EXE_LIST ${_name_we})
  add_executable(${_name_we} ${_file})
  add_dependencies(${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(${_name_we} ${PASTIX_MURGE_LIBRARIES})
endforeach()

# Fortran FLOAT only precision executables
foreach (_file ${EXAMPLES_FORTRAN})
  get_filename_component(_dir ${_file} PATH)
  get_filename_component(_name_we ${_file} NAME_WE)
  get_filename_component(_ext ${_file} EXT)
  list(APPEND PASTIX_EXAMPLES_EXE_LIST ${_name_we})
  add_executable(${_name_we} ${_file} utils.F90)
  add_dependencies(${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(${_name_we} ${PASTIX_MURGE_LIBRARIES})
endforeach()

# These executables requires mem_trace.c in addition
foreach (_file ${EXAMPLES_MEMTRACE})
  get_filename_component(_dir ${_file} PATH)
  get_filename_component(_name_we ${_file} NAME_WE)
  get_filename_component(_ext ${_file} EXT)
  list(APPEND PASTIX_EXAMPLES_EXE_LIST ${_name_we})
  add_executable(${_name_we} ${_file} mem_trace.c)
  add_dependencies(${_name_we} matrix_drivers pastix_murge pastix)
  target_link_libraries(${_name_we} ${PASTIX_MURGE_LIBRARIES})
endforeach()

install(TARGETS ${PASTIX_EXAMPLES_EXE_LIST} DESTINATION ${CMAKE_INSTALL_PREFIX}/examples)

###
### END CMakeLists.txt
###
