cmake_minimum_required (VERSION 2.6.2)
project (SLEPc C)

set (PETSc_SOURCE_DIR /Users/jroman/soft/petsc-dev)
set (PETSc_BINARY_DIR /Users/jroman/soft/petsc-dev/arch-darwin-c-debug)

include (${PETSc_BINARY_DIR}/conf/PETScConfig.cmake)
include (${SLEPc_BINARY_DIR}/conf/SLEPcConfig.cmake)

if (PETSC_HAVE_FORTRAN)
  enable_language (Fortran)
endif ()
if (PETSC_CLANGUAGE_Cxx)
  enable_language (CXX)
endif ()

include_directories ("${PETSc_SOURCE_DIR}/include" "${PETSc_BINARY_DIR}/include")
include_directories ("${SLEPc_SOURCE_DIR}/include" "${SLEPc_BINARY_DIR}/include")

add_definitions (-D__INSDIR__= ) # CMake always uses the absolute path
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${SLEPc_BINARY_DIR}/lib" CACHE PATH "Output directory for SLEPc archives")
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${SLEPc_BINARY_DIR}/lib" CACHE PATH "Output directory for SLEPc libraries")
set (CMAKE_Fortran_MODULE_DIRECTORY "${SLEPc_BINARY_DIR}/include" CACHE PATH "Output directory for fortran *.mod files")
mark_as_advanced (CMAKE_ARCHIVE_OUTPUT_DIRECTORY CMAKE_LIBRARY_OUTPUT_DIRECTORY CMAKE_Fortran_MODULE_DIRECTORY)
set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

###################  The following describes the build  ####################
  
include_directories (${PETSC_PACKAGE_INCLUDES} ${SLEPC_PACKAGE_INCLUDES})
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCSYS_SRCS
    src/sys/ftn-auto/slepcinitf.c
    src/sys/ftn-auto/slepcutilf.c
    src/sys/ftn-custom/zslepc_start.c
    src/sys/ftn-custom/zslepc_startf.c
    )
endif ()
if (PETSC_USING_F90)
  list (APPEND SLEPCSYS_SRCS
    src/sys/f90-mod/slepcmod.F
    )
endif ()
list (APPEND SLEPCSYS_SRCS
  src/sys/slepcinit.c
  src/sys/slepcutil.c
  )
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCVEC_SRCS
    src/vec/ftn-auto/contiguousf.c
    src/vec/ftn-auto/vecutilf.c
    )
endif ()
list (APPEND SLEPCVEC_SRCS
  src/vec/vecutil.c
  src/vec/veccomp.c
  src/vec/contiguous.c
  )
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCIP_SRCS
    src/ip/ftn-auto/ipbasicf.c
    src/ip/ftn-auto/ipbiorthogf.c
    src/ip/ftn-auto/ipborthogf.c
    src/ip/ftn-auto/ipdotf.c
    src/ip/ftn-auto/ipformf.c
    src/ip/ftn-auto/iporthogf.c
    src/ip/ftn-custom/zipf.c
    )
endif ()
list (APPEND SLEPCIP_SRCS
  src/ip/ipbasic.c
  src/ip/ipdot.c
  src/ip/iporthog.c
  src/ip/ipborthog.c
  src/ip/ipform.c
  src/ip/ipbiorthog.c
  )
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCDS_SRCS
    src/ds/interface/ftn-auto/dsbasicf.c
    src/ds/interface/ftn-auto/dsopsf.c
    src/ds/interface/ftn-custom/zpsf.c
    )
endif ()
list (APPEND SLEPCDS_SRCS
  src/ds/impls/ghep/dsghep.c
  src/ds/impls/hep/dshep.c
  src/ds/impls/ghiep/dsghiep.c
  src/ds/impls/ghiep/dsghiep_hz.c
  src/ds/impls/ghiep/dsghiep_dqds.c
  src/ds/impls/svd/dssvd.c
  src/ds/impls/nhep/dsnhep.c
  src/ds/impls/gnhep/dsgnhep.c
  src/ds/interface/dsbasic.c
  src/ds/interface/dsops.c
  src/ds/interface/dspriv.c
  )
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCST_SRCS
    src/st/impls/shell/ftn-auto/shellf.c
    src/st/impls/shell/ftn-custom/zshell.c
    src/st/impls/cayley/ftn-auto/cayleyf.c
    src/st/impls/precond/ftn-auto/precondf.c
    src/st/interface/ftn-auto/stfuncf.c
    src/st/interface/ftn-auto/stsetf.c
    src/st/interface/ftn-auto/stslesf.c
    src/st/interface/ftn-auto/stsolvef.c
    src/st/interface/ftn-custom/zstf.c
    )
endif ()
list (APPEND SLEPCST_SRCS
  src/st/impls/sinvert/sinvert.c
  src/st/impls/shell/shell.c
  src/st/impls/cayley/cayley.c
  src/st/impls/shift/shift.c
  src/st/impls/fold/fold.c
  src/st/impls/precond/precond.c
  src/st/interface/stfunc.c
  src/st/interface/stset.c
  src/st/interface/stsolve.c
  src/st/interface/stsles.c
  src/st/interface/stregis.c
  src/st/interface/shellmat.c
  )
if (SLEPC_HAVE_ARPACK)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/external/arpack/arpack.c
    )
endif ()
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/power/ftn-auto/powerf.c
    src/eps/impls/cg/rqcg/ftn-auto/rqcgf.c
    src/eps/impls/krylov/krylovschur/ftn-auto/krylovschurf.c
    src/eps/impls/krylov/arnoldi/ftn-auto/arnoldif.c
    src/eps/impls/krylov/lanczos/ftn-auto/lanczosf.c
    src/eps/impls/davidson/jd/ftn-auto/jdf.c
    src/eps/impls/davidson/gd/ftn-auto/gdf.c
    src/eps/interface/ftn-auto/basicf.c
    src/eps/interface/ftn-auto/monitorf.c
    src/eps/interface/ftn-auto/optsf.c
    src/eps/interface/ftn-auto/setupf.c
    src/eps/interface/ftn-auto/solvef.c
    src/eps/interface/ftn-custom/zepsf.c
    )
endif ()
list (APPEND SLEPCEPS_SRCS
  src/eps/impls/power/power.c
  src/eps/impls/lapack/lapack.c
  src/eps/impls/subspace/subspace.c
  src/eps/impls/cg/rqcg/rqcg.c
  src/eps/impls/krylov/krylov.c
  src/eps/impls/krylov/krylovschur/krylovschur.c
  src/eps/impls/krylov/krylovschur/ks-symm.c
  src/eps/impls/krylov/krylovschur/ks-slice.c
  src/eps/impls/krylov/krylovschur/ks-indef.c
  src/eps/impls/krylov/arnoldi/arnoldi.c
  src/eps/impls/krylov/lanczos/lanczos.c
  src/eps/impls/davidson/jd/jd.c
  src/eps/impls/davidson/gd/gd.c
  src/eps/impls/davidson/common/davidson.c
  src/eps/impls/davidson/common/dvd_blas.c
  src/eps/impls/davidson/common/dvd_calcpairs.c
  src/eps/impls/davidson/common/dvd_improvex.c
  src/eps/impls/davidson/common/dvd_initv.c
  src/eps/impls/davidson/common/dvd_schm.c
  src/eps/impls/davidson/common/dvd_testconv.c
  src/eps/impls/davidson/common/dvd_updatev.c
  src/eps/impls/davidson/common/dvd_utils.c
  src/eps/impls/davidson/common/dvd_gd2.c
  src/eps/interface/monitor.c
  src/eps/interface/basic.c
  src/eps/interface/default.c
  src/eps/interface/itregis.c
  src/eps/interface/opts.c
  src/eps/interface/setup.c
  src/eps/interface/solve.c
  src/eps/interface/mem.c
  )
if (PETSC_HAVE_FORTRAN AND SLEPC_HAVE_BLZPACK AND NOT PETSC_USE_COMPLEX)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/external/blzpack/ftn-auto/blzpackf.c
    )
endif ()
if (PETSC_HAVE_FORTRAN AND SLEPC_HAVE_PRIMME)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/external/primme/ftn-auto/primmef.c
    src/eps/impls/external/primme/ftn-custom/zprimmef.c
    )
endif ()
if (SLEPC_HAVE_BLZPACK AND NOT PETSC_USE_COMPLEX)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/external/blzpack/blzpack.c
    )
endif ()
if (SLEPC_HAVE_TRLAN AND NOT PETSC_USE_COMPLEX)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/external/trlan/trlan.c
    )
endif ()
if (SLEPC_HAVE_PRIMME)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/external/primme/primme.c
    )
endif ()
if (SLEPC_HAVE_BLOPEX AND PETSC_USE_REAL_DOUBLE)
  list (APPEND SLEPCEPS_SRCS
    src/eps/impls/external/blopex/blopex.c
    src/eps/impls/external/blopex/slepc-interface.c
    src/eps/impls/external/blopex/petsc-interface.c
    )
endif ()
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCSVD_SRCS
    src/svd/impls/trlanczos/ftn-auto/trlanczosf.c
    src/svd/impls/lanczos/ftn-auto/gklanczosf.c
    src/svd/impls/cross/ftn-auto/crossf.c
    src/svd/impls/cyclic/ftn-auto/cyclicf.c
    src/svd/interface/ftn-auto/svdbasicf.c
    src/svd/interface/ftn-auto/svdmonf.c
    src/svd/interface/ftn-auto/svdoptsf.c
    src/svd/interface/ftn-auto/svdsetupf.c
    src/svd/interface/ftn-auto/svdsolvef.c
    src/svd/interface/ftn-custom/zsvdf.c
    )
endif ()
list (APPEND SLEPCSVD_SRCS
  src/svd/impls/lapack/svdlapack.c
  src/svd/impls/trlanczos/trlanczos.c
  src/svd/impls/lanczos/gklanczos.c
  src/svd/impls/cross/cross.c
  src/svd/impls/cyclic/cyclic.c
  src/svd/interface/svdregis.c
  src/svd/interface/svdbasic.c
  src/svd/interface/svdopts.c
  src/svd/interface/svdsetup.c
  src/svd/interface/svdsolve.c
  src/svd/interface/svdmon.c
  src/svd/interface/svdmat.c
  )
if (PETSC_HAVE_FORTRAN)
  list (APPEND SLEPCQEP_SRCS
    src/qep/impls/linear/ftn-auto/linearf.c
    src/qep/interface/ftn-auto/qepbasicf.c
    src/qep/interface/ftn-auto/qepmonf.c
    src/qep/interface/ftn-auto/qepoptsf.c
    src/qep/interface/ftn-auto/qepsetupf.c
    src/qep/interface/ftn-auto/qepsolvef.c
    src/qep/interface/ftn-custom/zqepf.c
    )
endif ()
list (APPEND SLEPCQEP_SRCS
  src/qep/impls/qarnoldi/qarnoldi.c
  src/qep/impls/linear/linear.c
  src/qep/impls/linear/qeplin_n1.c
  src/qep/impls/linear/qeplin_n2.c
  src/qep/impls/linear/qeplin_s1.c
  src/qep/impls/linear/qeplin_s2.c
  src/qep/impls/linear/qeplin_h1.c
  src/qep/impls/linear/qeplin_h2.c
  src/qep/interface/qepmon.c
  src/qep/interface/qepbasic.c
  src/qep/interface/qepdefault.c
  src/qep/interface/qepregis.c
  src/qep/interface/qepopts.c
  src/qep/interface/qepsetup.c
  src/qep/interface/qepsolve.c
  )

add_library (slepc ${SLEPCSYS_SRCS} ${SLEPCVEC_SRCS} ${SLEPCIP_SRCS} ${SLEPCDS_SRCS} ${SLEPCST_SRCS} ${SLEPCEPS_SRCS} ${SLEPCSVD_SRCS} ${SLEPCQEP_SRCS})
target_link_libraries (slepc ${PETSC_LIB} ${SLEPC_PACKAGE_LIBS} ${PETSC_PACKAGE_LIBS})
if (PETSC_WIN32FE)
  set_target_properties (slepc PROPERTIES RULE_LAUNCH_COMPILE "${PETSC_WIN32FE}")
  set_target_properties (slepc PROPERTIES RULE_LAUNCH_LINK "${PETSC_WIN32FE}")
endif ()

if (PETSC_CLANGUAGE_Cxx)
  foreach (file IN LISTS SLEPCSYS_SRCS
  SLEPCVEC_SRCS
  SLEPCIP_SRCS
  SLEPCDS_SRCS
  SLEPCST_SRCS
  SLEPCEPS_SRCS
  SLEPCSVD_SRCS
  SLEPCQEP_SRCS)
    if (file MATCHES "^.*\\.c$")
      set_source_files_properties(${file} PROPERTIES LANGUAGE CXX)
    endif ()
  endforeach ()
endif()