My general task:
I have a Fortran Tool which uses the functions dgemm, dgemv, dgesvx and dsyev from the MKL Library. I need to compile my code as a shared object (.so) to make it work on a different pc. I am using the gfortran compiler and linker. The linking of the MKL Library must be static as neither the MKL nor gfortran is installed on the other pc.
My .so is not an executable by itself but is part of a Python-Tool which accesses its functions - hence there is nothing like a main() Function in the Fortran code. (I had several errors refering to this, so I wanted to mention it here...)
What I tried:
(1) I used the Intel Link Line Advisor to determin the required flags. The resulting linker (LDFLAGS) and compiler flags (FFLAGS) are:
- FFLAGS := -m64 -fdefault-integer-8 -I"${MKLROOT}/include"
- LDFlAGS := -m64 -Wl,--start-group ${MKLROOT}/lib/libmkl_gf_ilp64.a ${MKLROOT}/lib/libmkl_sequential.a ${MKLROOT}/lib/libmkl_core.a -Wl,--end-group -lpthread -lm -ldl
(2) I added the following Flags due to my personal requirements: FFLAGS:
- -Wall to get all warning printed
- -fPIC for position-independent code
- -O3 for optimization LDFLAGS:
- -Wall to get all warning printed
- -shared to create a shared object (.so)
(3) I combined everything into a Makefile.
OUTPUT_LIBRARY := OI.so
MKLROOT := /opt/intel/oneapi/mkl/latest/
# Name of Compiler
FC := gfortran
# Compileroptions
FFLAGS := -Wall -m64 -fPIC -fdefault-integer-8 -I"${MKLROOT}/include" # -fdec-math ist veraltet, wird daher entfernt
FFLAGS_RELEASE := -O3
FFLAGS_DEBUG := -g
## Linkeroptions
core := $(MKLROOT)/lib/libmkl_core.a
ilp := $(MKLROOT)/lib/libmkl_gf_ilp64.a
sequential := $(MKLROOT)/lib/libmkl_sequential.a
LDFLAGS := -Wall -m64 -shared -Wl,--start-group $(core) $(ilp) $(sequential) -Wl,--end-group -lpthread -lm -ldl
# Source-Files
SRC := S_Module_ivu.for\
s_analyse_IVU.for\
covsrt.for\
gaussj.for\
mrqcof.for\
mrqmin.for\
nrrank.f\
S_acsurf_ivu.for\
S_diff_ivu.for\
S_expo_fit_neu_ivu.for\
S_getac_ivu.for\
S_justl.for\
S_ord_ivu.for\
S_PERCENTILE_ivu.for\
getKanal.f90\
S_fileprocs_ivu.f90\
S_setoiparams_ivu.f90\
SS_oi_ivu.f90\
S_ANA_VARIANZ_IVU.FOR\
S_CORRECS_ivu.FOR\
S_FUNC_DEF_ivu.FOR\
S_LOCGEO_ivu.FOR\
S_NORMC_IVU.FOR\
S_SCALCWTSW_ivu.FOR
SRC_for := $(filter %.for,$(SRC))
SRC_FOR := $(filter %.FOR,$(SRC))
SRC_f := $(filter %.f,$(SRC))
SRC_f90 := $(filter %.f90,$(SRC))
OBJ_for := $(patsubst %.for,%.o,$(SRC_for))
OBJ_FOR := $(patsubst %.FOR,%.o,$(SRC_FOR))
OBJ_f := $(patsubst %.f,%.o,$(SRC_f))
OBJ_f90 := $(patsubst %.f90,%.o,$(SRC_f90))
OBJ_ALL := $(OBJ_for) $(OBJ_FOR) $(OBJ_f) $(OBJ_f90)
# Default-Target: .so in release mode
all: release
release: FFLAGS += $(FFLAGS_RELEASE)
debug: FFLAGS += $(FFLAGS_DEBUG)
release: $(OUTPUT_LIBRARY)
debug: $(OUTPUT_LIBRARY)
# Compile
$(OBJ_for): %.o: %.for
$(FC) $(FFLAGS) -c $< -o $@
$(OBJ_FOR): %.o: %.FOR
$(FC) $(FFLAGS) -c $< -o $@
$(OBJ_f): %.o: %.f
$(FC) $(FFLAGS) -c $< -o $@
$(OBJ_f90): %.o: %.f90
$(FC) $(FFLAGS) -c $< -o $@
# Link
$(OUTPUT_LIBRARY): $(OBJ_ALL)
$(FC) $(LDFLAGS) -o $@ $^
# Option for cleaning up
.PHONY: clean
clean:
rm -f $(OBJ_ALL)
rm -f *.mod
rm -f $(OUTPUT_LIBRARY)
What's not working:
When running make release, I get no error messages and the OI.so is successfully created. Nevertheless, when checking the undefined symbols in OI.so (using nm -u OI.so), they list all the required MKL Functions as undefined. My program doesn't work due to these undefined functions.
Any suggestions what I'm doing wrong here?