#===============================================================================
# Copyright 2004-2018 Intel Corporation.
#
# This software and the related documents are Intel copyrighted  materials,  and
# your use of  them is  governed by the  express license  under which  they were
# provided to you (License).  Unless the License provides otherwise, you may not
# use, modify, copy, publish, distribute,  disclose or transmit this software or
# the related documents without Intel's prior written permission.
#
# This software and the related documents  are provided as  is,  with no express
# or implied  warranties,  other  than those  that are  expressly stated  in the
# License.
#===============================================================================

##  Content:
##      Intel(R) Math Kernel Library Custom Shared Object builder
##
##******************************************************************************

help:
	@echo
	@echo "Custom Shared Object builder creates MKL custom library"
	@echo
	@echo "Usage: make <target> [<options>]"
	@echo
	@echo "  target"
	@echo "    (static builder: uses static Intel(R) MKL interface+threading+core libraries)"
	@echo "      libia32    - for IA-32 architecture"
	@echo "      libintel64 - for Intel(R) 64 architecture"
	@echo "    help         - prints this help"
	@echo
	@echo "    <options>"
	@echo "        interface={lp64|ilp64} (for libintel64 only)"
	@echo "            Specifies programming interface for libintel64."
	@echo "            Default: lp64."
	@echo "        export=<file_name>"
	@echo "            The name of the file that contains the list of entry points"
	@echo "            to be included to the shared object."
	@echo "            Default: user_example_list (no extension)."
	@echo "        name=<so_name>"
	@echo "            The name of the shared object to be created. The extension .so will be added."
	@echo "            Default: mkl_custom."
	@echo "        xerbla=<err_handlr>"
	@echo "            The name of the object file that contains the user's error handler."
	@echo "            By the default native Intel(R) MKL XERBLA is used."
	@echo "        threading={parallel|sequential} (for libia32 and libintel64)"
	@echo "            Specifies whether to use Intel(R) MKL in the threaded or sequential mode."
	@echo "            Default: parallel."
	@echo "        parallel={intel|gnu} (for libia32 and libintel64)"
	@echo "            Specifies whether to use Intel OpenMP or GNU* OpenMP (for GNU compiler only)."
	@echo "            Default: intel."
	@echo "        MKLROOT=<MKL_directory>"
	@echo "            Specifies the location of Intel(R) MKL libraries used to build the custom shared object."
	@echo "            Default: the Intel(R) MKL installation directory."
	@echo
	@echo "Usage examples:"
	@echo
	@echo "  make libia32"
	@echo "    Creates mkl_custom.so for IA-32 architecture."
	@echo "    Function list is taken from the predefined file user_example_list."
	@echo "    The static-parallel Intel(R) MKL libraries are used to build mkl_custom.so."
	@echo "    Native Intel(R) MKL error handler is used."
	@echo
	@echo "  make libintel64 export=my_blas_list interface=ilp64 name=my_blas"
	@echo "    Creates my_blas.so for Intel(R) 64 architecture."
	@echo "    Function list is taken from the user file my_blas_list."
	@echo "    The static-parallel-ilp64 Intel(R) MKL libraries are used to build my_blas.so."
	@echo

##------------------------------------------------------------------------------

ifndef MKLROOT
MKLROOT = ../..
endif

mklia32_libpath=$(MKLROOT)/lib/ia32
mklintel64_libpath=$(MKLROOT)/lib/intel64
compileria32_libpath=$(MKLROOT)/../compiler/lib/ia32
compilerintel64_libpath=$(MKLROOT)/../compiler/lib/intel64

#ifndef export
export=user_example_list
#endif

#ifndef name
name=mkl_custom
#endif

ifdef xerbla
XERBLA="$(xerbla)"
else
XERBLA=
endif

ifndef interface
interface=lp64
endif

ifndef threading
threading=parallel
endif

IFACE_COMP_PART=intel

ifeq ($(parallel),gnu)
IFACE_THREADING_PART=gnu
OMP_LIB=-lgomp
else
IFACE_THREADING_PART=intel
OMP_LIB=-liomp5
endif

ifeq ($(interface),ilp64)
IFACE_LIB=libmkl_$(IFACE_COMP_PART)_ilp64.a
else
IFACE_LIB=libmkl_$(IFACE_COMP_PART)_lp64.a
endif

ifeq ($(threading),sequential)
THREADING_LIB=libmkl_sequential.a
OMP_LIB=
else
THREADING_LIB=libmkl_$(IFACE_THREADING_PART)_thread.a
endif
OMP_LIB += -lpthread

CORE_LIB=libmkl_core.a
PURE_IFACE_LIB=-lmkl_rt

LIBM=-lm

libia32 ia32: check_export_file_name
	export LIBRARY_PATH=$(LIBRARY_PATH):$(LD_LIBRARY_PATH); \
	gcc -m32 -shared -Wl,-z,relro,-z,now -Bdynamic \
	$(XERBLA) $(addprefix -u ,$(shell grep -v '^[\#;]' "$(export)")) \
	-u mkl_serv_finalize -Wl,-fini=mkl_serv_finalize \
	-Wl,--start-group \
	"$(mklia32_libpath)/libmkl_intel.a" \
	"$(mklia32_libpath)/$(THREADING_LIB)" \
	"$(mklia32_libpath)/$(CORE_LIB)" \
	-Wl,--end-group \
	-L"$(compileria32_libpath)" $(OMP_LIB) $(LIBM) \
	-o "$(name).so"

libintel64 intel64 em64t: check_export_file_name
	export LIBRARY_PATH=$(LIBRARY_PATH):$(LD_LIBRARY_PATH); \
	gcc -shared -Wl,-z,relro,-z,now -Bdynamic \
	$(XERBLA) $(addprefix -u ,$(shell grep -v '^[\#;]' "$(export)")) \
	-u mkl_serv_finalize -Wl,-fini=mkl_serv_finalize \
	-Wl,--start-group \
	"$(mklintel64_libpath)/$(IFACE_LIB)" \
	"$(mklintel64_libpath)/$(THREADING_LIB)" \
	"$(mklintel64_libpath)/$(CORE_LIB)" \
	-Wl,--end-group \
	-L"$(compilerintel64_libpath)" $(OMP_LIB) $(LIBM) \
	-o "$(name).so"

check_export_file_name: $(export)
