#******************************************************************************
#                              INTEL CONFIDENTIAL
#  Copyright(C) 2005-2010 Intel Corporation. All Rights Reserved.
#  The source code contained  or  described herein and all documents related to
#  the source code ("Material") are owned by Intel Corporation or its suppliers
#  or licensors.  Title to the  Material remains with  Intel Corporation or its
#  suppliers and licensors. The Material contains trade secrets and proprietary
#  and  confidential  information of  Intel or its suppliers and licensors. The
#  Material  is  protected  by  worldwide  copyright  and trade secret laws and
#  treaty  provisions. No part of the Material may be used, copied, reproduced,
#  modified, published, uploaded, posted, transmitted, distributed or disclosed
#  in any way without Intel's prior express written permission.
#  No license  under any  patent, copyright, trade secret or other intellectual
#  property right is granted to or conferred upon you by disclosure or delivery
#  of the Materials,  either expressly, by implication, inducement, estoppel or
#  otherwise.  Any  license  under  such  intellectual property  rights must be
#  express and approved by Intel in writing.
#
#******************************************************************************
#  Content:
#      Intel(R) Math Kernel Library LAPACK95 library creation
#******************************************************************************

help:
	@echo "Usage: make {lib32|libem64t|lib64} INSTALL_DIR=<path>"
	@echo "            [interface=interface_name] [FC=compiler_name]"
	@echo
	@echo "Intel(R) Fortran Compiler as default"
	@echo
	@echo "INSTALL_DIR    - library and the .mod files will be built and installed"
	@echo "                 in subdirectories of <path> the same way as if <path>"
	@echo "                 were the Intel MKL installation directory."
	@echo "interface_name - can be lp64 or ilp64 for em64t and ia64. Default value is lp64."
	@echo "FC             - can be ifort, gfortran or pgf95. Default value is ifort."

##------------------------------------------------------------------------------
## examples of using:
##
## make lib32 INSTALL_DIR=lib95    - build  by Intel(R) Fortran Compiler  (as default)
##                                   for 32-bit applications, static linking
##
## make lib64 INSTALL_DIR=lib95    - build  by Intel(R) Fortran Compiler  (as default)
##                                   for 64-bit applications - Intel(R) Itanium(R), static linking
##
## make libem64t INSTALL_DIR=lib95 - build  by Intel(R) Fortran Compiler  (as default)
##                                   for 32-bit with Intel(R) EM64T applications - static linking
##------------------------------------------------------------------------------

include lapack95.lst

iface_95 = lapack.f90
iface_77 = lapack_interfaces.f90

ifndef FC
  FC=ifort
else
  ifeq ($(FC),f77)
    FC=ifort
  endif
endif

opts0    =
optsc    = -c $(opts0)
sufobj   = o
suflib   = a
sufmod   = mod
src_path = source
LIBR     = ar -rs

ifndef MKLROOT
MKLROOT = ../..
endif

obj_path = $(INSTALL_DIR)/lib/$(IA)/obj_lapack95_$(IA)_$(interface)
obj77_path = $(obj_path)/obj77

inc_path = $(MKLROOT)/include

MODULE_DIR = $(INSTALL_DIR)/include

objs    = $(src_lapack95:.f90=.$(sufobj))
objects = $(addprefix $(obj_path)/,$(objs))
mod95 = mkl95_lapack.mod
mod77 = $(obj77_path)/$(iface_77:.f90=.obj)

ifeq ($(FC),pgf95)
    auto=-mp
else
    auto=-auto
endif

check:
ifndef PLAT
	$(error Undefined platform: PLAT=$(PLAT). Set one of: lnx32 lnx64 lnx32e)
endif

ifeq ($(PLAT),lnx32)
    IA = 32
    FOPTS = $(auto)
    mod_path = $(MODULE_DIR)/32
    mkl_lapack95_lib      = libmkl_lapack95.$(suflib)
else
    ifeq ($(PLAT),lnx32e)
        IA = em64t
        ifeq ($(interface),ilp64)
            FOPTS = -i8 $(auto)
            mod_path = $(MODULE_DIR)/em64t/ilp64
            mkl_lapack95_lib      = libmkl_lapack95_ilp64.$(suflib)
        else
            FOPTS = $(auto)
            mod_path = $(MODULE_DIR)/em64t/lp64
            mkl_lapack95_lib      = libmkl_lapack95_lp64.$(suflib)
        endif
    else
        ifeq ($(PLAT),lnx64)
            IA = 64
            ifeq ($(interface),ilp64)
                FOPTS = -i8 $(auto)
                mod_path = $(MODULE_DIR)/64/ilp64
                mkl_lapack95_lib      = libmkl_lapack95_ilp64.$(suflib)
            else
                FOPTS = $(auto)
                mod_path = $(MODULE_DIR)/64/lp64
                mkl_lapack95_lib      = libmkl_lapack95_lp64.$(suflib)
            endif
        else
	$(error Unknown platform: PLAT=$(PLAT). Set one of: lnx32 lnx64 lnx32e)
        endif
    endif
endif

ifeq ($(FC),gfortran)
  # no space after J
  opt_mod = -J
  ifeq ($(interface),ilp64)
    FOPTS=-fdefault-integer-8 -fautomatic
  else
    FOPTS=-fautomatic
  endif
else
  # space after module
  opt_mod = -module 
endif

vpath %.f90       $(src_path)
vpath %.f90       $(inc_path)
vpath %.$(sufobj) $(obj_path)

$(obj_path)/%.$(sufobj): %.f90
	$(FC) $(SPEC_OPT) $(FOPTS) $(opt_mod)$(obj77_path) $(optsc) -o $(obj_path)/$(@F) $<

$(mod_path)/$(mod95): $(inc_path)/$(iface_95)
	mkdir -p $(obj77_path)
	mkdir -p $(mod_path)
	$(FC) $(SPEC_OPT) $(FOPTS) $(opt_mod)$(mod_path) $(optsc) -o $(obj77_path)/mkl_lapack.$(sufobj) $<

.PHONY: build lib mod clean check checkdir lib32 libem64t lib64 objects clean_obj clean32 cleanem64t clean64

lib32: checkdir
	make PLAT=lnx32 build MKLROOT=$(MKLROOT) INSTALL_DIR=$(INSTALL_DIR) FC=$(FC)
libem64t: checkdir
	make PLAT=lnx32e build interface=$(interface) MKLROOT=$(MKLROOT) INSTALL_DIR=$(INSTALL_DIR) FC=$(FC)
lib64: checkdir
	make PLAT=lnx64 build interface=$(interface) MKLROOT=$(MKLROOT) INSTALL_DIR=$(INSTALL_DIR) FC=$(FC)

build:	check lib mod clean_obj
lib:	$(INSTALL_DIR)/lib/$(IA)/$(mkl_lapack95_lib)
mod:	$(mod_path)/$(mod95)

$(INSTALL_DIR)/lib/$(IA)/$(mkl_lapack95_lib):
	mkdir -p $(obj77_path)
	$(FC) $(SPEC_OPT) $(FOPTS) $(opt_mod)$(obj77_path) $(optsc) -o $(mod77) $(src_path)/$(iface_77)
	make objects
	cd $(obj_path) ; $(LIBR) $(mkl_lapack95_lib) *.$(sufobj)
	mv $(obj_path)/$(mkl_lapack95_lib) $(INSTALL_DIR)/lib/$(IA)

objects:$(objects)

checkdir:
ifndef INSTALL_DIR
	$(error Not given INSTALL_DIR)
endif

clean: clean32 cleanem64t clean64
clean32: checkdir
	-rm -rf $(INSTALL_DIR)/lib/32/obj_lapack95_32_*
	-rm -f $(INSTALL_DIR)/lib/32/libmkl_lapack95.$(suflib)
	-rm -f $(INSTALL_DIR)/include/32/mkl95_lapack.$(sufmod) $(INSTALL_DIR)/include/32/mkl95_precision.$(sufmod)
cleanem64t: checkdir
	-rm -rf $(INSTALL_DIR)/lib/em64t/obj_lapack95_em64t_*
	-rm -f $(INSTALL_DIR)/lib/em64t/libmkl_lapack95_*lp64.$(suflib)
	-rm -f $(INSTALL_DIR)/include/em64t/*lp64/mkl95_lapack.$(sufmod) $(INSTALL_DIR)/include/em64t/*lp64/mkl95_precision.$(sufmod)
clean64: checkdir
	-rm -rf $(INSTALL_DIR)/lib/64/obj_lapack95_64_*
	-rm -f $(INSTALL_DIR)/lib/64/libmkl_lapack95_*lp64.$(suflib)
	-rm -f $(INSTALL_DIR)/include/64/*lp64/mkl95_lapack.$(sufmod) $(INSTALL_DIR)/include/64/*lp64/mkl95_precision.$(sufmod)

clean_obj: check
	-rm -rf $(obj_path)
