# Configuration for Microsoft Build Engine

LINKER = link
AR = lib
CP = copy
MV = move
RM = del


# See win32.mak for details. 

!include <win32.mak>
#!include <C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\win32.mak>

# Configuration for Microsoft Visual C++

CC = cl
CFLAGS = $(cflags) -DHAVE_CONFIG_WIN_H -I ../include -w 

!ifdef msvcrt
CFLAGS = $(CFLAGS) $(cvarsdll)
LDFLAGS = $(LDFLAGS) $(conlflags) $(conlibsdll)
!ifdef omp
CFLAGS = $(CFLAGS) -openmp
!endif
!else
!ifdef omp
CFLAGS = $(CFLAGS) $(cvarsmt) -openmp
LDFLAGS = $(LDFLAGS) $(conlibsmt) 
!else
CFLAGS = $(CFLAGS) $(cvars)
LDFLAGS = $(LDFLAGS) $(conlibs)
!endif
!endif

CFLAGS = $(cdebug) $(CFLAGS) $(USER_CFLAGS)
LDFLAGS = $(ldebug) $(conlflags) $(LDFLAGS) $(USER_LDFLAGS)


# Configuration for Intel FPU

!ifndef noifpu
CFLAGS = $(CFLAGS) -DHAS_X87_FPU -DUSE_QUAD_PRECISION -DUSE_FMA2_SSE2 -DUSE_SSE2 -DUSE_FAST_QUAD_ADD
!endif


# Configuration for Intel C Compiler 

!ifdef intelc
CC = icl
CFLAGS = $(cflags) $(USER_CFLAGS) \
       -O3 -Qansi_alias -DHAVE_CONFIG_WIN_H -I ../include -w 

!ifdef omp
CFLAGS = $(CFLAGS) $(cdebug) $(cvarsmt) -Qopenmp -Qopenmp-lib:compat
!else
CFLAGS = $(CFLAGS) $(cdebug) $(cvars)
!endif
!endif


# Configuration for Fortran interface

!ifdef fortran
FC = ifort
CFLAGS = $(CFLAGS) -DUSE_FORTRAN
FFLAGS = $(USER_FFLAGS) \
       -c -O3 -fpp -Qansi_alias -DZERO_ORIGIN=1 -I ../include -w 

!ifdef omp
FFLAGS = $(FFLAGS) -Qopenmp -Qopenmp-lib:compat 
!else
FFLAGS = $(FFLAGS) -MT
!endif
!endif


# Configuration for SA-AMG preconditioning

!ifdef saamg
CFLAGS = $(CFLAGS) -DUSE_SAAMG
!endif


# Configuration for 64bit integer

!ifdef longlong
CFLAGS = $(CFLAGS) -D_LONG__LONG
FFLAGS = $(FFLAGS) -DLONG__LONG 
!ifdef intel
FFLAGS = $(FFLAGS) -integer-size:64
!endif
!endif


# Configuration for long double precision operations

!ifdef longdouble
CFLAGS = $(CFLAGS) -D_LONG__DOUBLE
FFLAGS = $(FFLAGS) -DLONG__DOUBLE
!ifdef intel
CFLAGS = $(CFLAGS) -Qlong-double
FFLAGS = $(FFLAGS) -real-size:128
!endif
!endif


# Configuration for complex arithmetic

!ifdef complex
CFLAGS = $(CFLAGS) -D_COMPLEX
FFLAGS = $(FFLAGS) -DCOMPLEX
!endif


# Configuration for 32bit Microsoft MPI

!ifdef mpi 
MPIDIR = "C:\Program Files\Microsoft MPI"
CFLAGS = $(CFLAGS) -DUSE_MPI -I $(MPIDIR)\Inc
FFLAGS = $(FFLAGS) -DUSE_MPI -I $(MPIDIR)\Inc
LDFLAGS = $(LDFLAGS) $(MPIDIR)\Lib\i386\msmpi.lib $(MPIDIR)\Lib\i386\msmpifec.lib
MPIRUN = "mpiexec -n 2"
!endif


# Configuration for 64bit Microsoft MPI

!ifdef mpi 
!ifdef mpi64
MPIDIR = "C:\Program Files\Microsoft MPI"
CFLAGS = $(CFLAGS) -DUSE_MPI -I $(MPIDIR)\Inc
FFLAGS = $(FFLAGS) -DUSE_MPI -I $(MPIDIR)\Inc
LDFLAGS = $(LDFLAGS) $(MPIDIR)\Lib\amd64\msmpi.lib $(MPIDIR)\Lib\amd64\msmpifec.lib
MPIRUN = "mpiexec -n 2"
!endif
!endif


# Configuration for 32bit MPICH

!ifdef mpich 
MPIDIR = "C:\Program Files (x86)\MPICH2"
CFLAGS = $(CFLAGS) -DUSE_MPI -I $(MPIDIR)\include
FFLAGS = $(FFLAGS) -DUSE_MPI -I $(MPIDIR)\include
LDFLAGS = $(LDFLAGS) $(MPIDIR)\lib\mpi.lib $(MPIDIR)\lib\fmpich2.lib
MPIRUN = "mpiexec -localonly 2"
!endif


# Configuration for 64bit MPICH

!ifdef mpich
!ifdef mpi64
MPIDIR = "C:\Program Files\MPICH2"
CFLAGS = $(CFLAGS) -DUSE_MPI -I $(MPIDIR)\include
FFLAGS = $(FFLAGS) -DUSE_MPI -I $(MPIDIR)\include
LDFLAGS = $(LDFLAGS) $(MPIDIR)\lib\mpi.lib $(MPIDIR)\lib\fmpich2.lib
MPIRUN = "mpiexec -localonly 2"
!endif
!endif


!ifdef fortran
all: libs exes_test exes_etest exes_spmvtest \
     libs_lisf_init exes_testf exes_etestf
!else
all: libs exes_test exes_etest exes_spmvtest
!endif

!ifdef saamg
libs: objs_array objs_esolver objs_fortran objs_matrix objs_matvec \
      objs_precision objs_precon objs_solver objs_system objs_vector objs_saamg 
!else
libs: objs_array objs_esolver objs_fortran objs_matrix objs_matvec \
      objs_precision objs_precon objs_solver objs_system objs_vector
!endif
	$(AR) *.obj -out:lis.lib

objs_array: ..\src\array\*.obj 
objs_esolver: ..\src\esolver\*.obj 
objs_fortran: ..\src\fortran\*.obj 
objs_matrix: ..\src\matrix\*.obj 
objs_matvec: ..\src\matvec\*.obj 
objs_precision: ..\src\precision\*.obj 
objs_precon: ..\src\precon\*.obj 
objs_solver: ..\src\solver\*.obj 
objs_system: ..\src\system\*.obj 
objs_vector: ..\src\vector\*.obj

!if defined(mpi) || defined(mpich)
objs_saamg: ..\src\fortran\amg\lis_m_data_type_AMGCG.obj \
	    ..\src\fortran\amg\lis_m_queue.obj \
	    ..\src\fortran\amg\lis_m_hash.obj \
	    ..\src\fortran\amg\lis_m_solver_Gnum.obj \
	    ..\src\fortran\amg\lis_m_solver_SR2.obj \
	    ..\src\fortran\amg\lis_m_aggregate.obj \
	    ..\src\fortran\amg\lis_m_count_time_mod.obj \
	    ..\src\fortran\amg\lis_m_sort.obj \
	    ..\src\fortran\amg\lis_m_data_creation_AMGCG.obj \
	    ..\src\fortran\amg\lis_m_solver_AMGCG.obj \
	    ..\src\fortran\amg\lis_m_finit.obj 
!else
objs_saamg: ..\src\fortran\amg\lis_s_data_type_AMGCG.obj \
	    ..\src\fortran\amg\lis_s_queue.obj \
	    ..\src\fortran\amg\lis_s_aggregate.obj \
	    ..\src\fortran\amg\lis_s_sort.obj \
	    ..\src\fortran\amg\lis_s_data_creation_AMGCG.obj \
	    ..\src\fortran\amg\lis_s_solver_AMGCG.obj \
	    ..\src\fortran\amg\lis_s_finit.obj
!endif

exes_test: test1.exe test2.exe test2b.exe test3.exe test3b.exe test3c.exe test4.exe test5.exe test6.exe
exes_etest: etest1.exe getest1.exe etest2.exe etest3.exe etest4.exe etest5.exe getest5.exe etest6.exe etest7.exe
exes_spmvtest: spmvtest1.exe spmvtest2.exe spmvtest2b.exe spmvtest3.exe spmvtest3b.exe spmvtest4.exe spmvtest5.exe

exes_testf: test1f.exe test2f.exe test4f.exe test6f.exe
exes_etestf: etest1f.exe etest4f.exe

test1.exe: ..\test\$*.obj
test2.exe: ..\test\$*.obj
test2b.exe: ..\test\$*.obj
test3.exe: ..\test\$*.obj
test3b.exe: ..\test\$*.obj
test3c.exe: ..\test\$*.obj
test4.exe: ..\test\$*.obj
test5.exe: ..\test\$*.obj
test6.exe: ..\test\$*.obj
etest1.exe: ..\test\$*.obj
getest1.exe: ..\test\$*.obj
etest2.exe: ..\test\$*.obj
etest3.exe: ..\test\$*.obj
etest4.exe: ..\test\$*.obj
etest5.exe: ..\test\$*.obj
getest5.exe: ..\test\$*.obj
etest6.exe: ..\test\$*.obj
etest7.exe: ..\test\$*.obj
spmvtest1.exe: ..\test\$*.obj
spmvtest2.exe: ..\test\$*.obj
spmvtest2b.exe: ..\test\$*.obj
spmvtest3.exe: ..\test\$*.obj
spmvtest3b.exe: ..\test\$*.obj
spmvtest4.exe: ..\test\$*.obj
spmvtest5.exe: ..\test\$*.obj

libs_lisf_init:
	$(FC) $(FFLAGS) -out:lisf_init.obj ..\src\fortran\lisf_init.f lis.lib

test1f.exe: ..\test\$*.obj
	$(LINKER) $(LDFLAGS) $*.obj lisf_init.obj lis.lib

test2f.exe: ..\test\$*.obj
	$(LINKER) $(LDFLAGS) $*.obj lisf_init.obj lis.lib

test4f.exe: ..\test\$*.obj
	$(LINKER) $(LDFLAGS) $*.obj lisf_init.obj lis.lib

test6f.exe: ..\test\$*.obj
	$(LINKER) $(LDFLAGS) $*.obj lisf_init.obj lis.lib

etest1f.exe: ..\test\$*.obj
	$(LINKER) $(LDFLAGS) $*.obj lisf_init.obj lis.lib

etest4f.exe: ..\test\$*.obj
	$(LINKER) $(LDFLAGS) $*.obj lisf_init.obj lis.lib 

.c.obj:
	$(CC) $(CFLAGS) $*.c

.f.obj:
	$(FC) $(FFLAGS) $*.f 

.f90.obj:
	$(FC) $(FFLAGS) $*.f90

.obj.exe:
	$(LINKER) $(LDFLAGS) $*.obj lis.lib 

check:
!ifdef omp
	@set OMP_NUM_THREADS=2
!else
	@set OMP_NUM_THREADS=1
!endif
	@echo checking linear solvers...
	@$(MPIRUN) test1.exe ..\test\testmat.mtx 0 nul nul
	@echo checking eigensolvers...
	@$(MPIRUN) etest1.exe ..\test\testmat.mtx nul nul
!ifdef fortran
	@echo checking Fortran interface...
	@echo.
	@$(MPIRUN) test4f.exe
	@echo.
!endif
!ifdef saamg
	@echo SAAMG preconditioner...
	@$(MPIRUN) test2.exe 10 10 1 nul nul -i cg -p saamg
!endif

install:
	if not exist $(PREFIX) mkdir $(PREFIX)
	if not exist $(PREFIX)\bin mkdir $(PREFIX)\bin
	if not exist $(PREFIX)\include mkdir $(PREFIX)\include
	if not exist $(PREFIX)\lib mkdir $(PREFIX)\lib
	if not exist $(PREFIX)\doc mkdir $(PREFIX)\doc
	$(CP) test1.exe $(PREFIX)\bin\lsolve.exe
	$(CP) etest5.exe $(PREFIX)\bin\esolve.exe
	$(CP) getest5.exe $(PREFIX)\bin\gesolve.exe
	$(CP) test3b.exe $(PREFIX)\bin\hpcg_kernel.exe
	$(CP) spmvtest3b.exe $(PREFIX)\bin\hpcg_spmvtest.exe
	$(CP) spmvtest1.exe $(PREFIX)\bin
	$(CP) spmvtest2.exe $(PREFIX)\bin
	$(CP) spmvtest2b.exe $(PREFIX)\bin
	$(CP) spmvtest3.exe $(PREFIX)\bin
	$(CP) spmvtest3b.exe $(PREFIX)\bin
	$(CP) spmvtest4.exe $(PREFIX)\bin
	$(CP) spmvtest5.exe $(PREFIX)\bin
	$(CP) lis.lib $(PREFIX)\lib
	$(CP) ..\include\lis_config.h $(PREFIX)\include
	$(CP) ..\include\lis.h $(PREFIX)\include
	$(CP) ..\include\lisf.h $(PREFIX)\include
	$(CP) ..\doc\lis-ug-en.pdf $(PREFIX)\doc
	$(CP) ..\doc\lis-ug-ja.pdf $(PREFIX)\doc

uninstall: 
	$(RM) $(PREFIX)\bin\lsolve.exe
	$(RM) $(PREFIX)\bin\esolve.exe
	$(RM) $(PREFIX)\bin\gesolve.exe
	$(RM) $(PREFIX)\bin\hpcg_kernel.exe
	$(RM) $(PREFIX)\bin\hpcg_spmvtest.exe
	$(RM) $(PREFIX)\bin\spmvtest1.exe
	$(RM) $(PREFIX)\bin\spmvtest2.exe
	$(RM) $(PREFIX)\bin\spmvtest2b.exe
	$(RM) $(PREFIX)\bin\spmvtest3.exe
	$(RM) $(PREFIX)\bin\spmvtest3b.exe
	$(RM) $(PREFIX)\bin\spmvtest4.exe
	$(RM) $(PREFIX)\bin\spmvtest5.exe
	$(RM) $(PREFIX)\lib\lis.lib
	$(RM) $(PREFIX)\include\lis_config.h
	$(RM) $(PREFIX)\include\lis.h
	$(RM) $(PREFIX)\include\lisf.h
	$(RM) $(PREFIX)\doc\lis-ug-en.pdf
	$(RM) $(PREFIX)\doc\lis-ug-ja.pdf
	rmdir $(PREFIX)\bin $(PREFIX)\lib $(PREFIX)\include $(PREFIX)\doc
	rmdir $(PREFIX)

clean:
	$(RM) *.obj *.mod *.pdb 

distclean: 
	$(RM) *.lib *.exe *.obj *.mod *.pdb Makefile

