cmakefilefortranintel

Intel Compilers: linking a fortran compiled library to main program of C


So I wanted to use a special maths function but couldn't find a C library that had it, however I found an old Fortran library slatec that had implemented it, so in order to use it, I adapted these instructions to my case :http://difdop.polytechnique.fr/wiki/index.php/How_to_Bessel_Functions_in_C

I'm using a makefile to compile, here's an extract of its contents in the GNU case

CFLAGS=-Wall -O2
CC=gcc
MPICC=mpicc -DDEBUG_INPUT
LIBS=-lm -lgfortran

THIS_DIR=$(shell pwd)

WEAKWEAK_OBJECTS=manager_weakweak.o worker_weakweak.o bunch_weak.o transform_weak.o cyclic_array.o
WEAKSTRONG_OBJECTS=manager_weakstrong.o worker_weakstrong.o bunch_strong.o fbi_weakstrong.o rw_weakstrong.o
../mbtrack-mpi : ./besselh/libamos.a mbtrack-mpi.o confmpi.o input.o test.o ${WEAKWEAK_OBJECTS} ${WEAKSTRONG_OBJECTS} bunch.o stats.o physic.o statistics.o tracking.o rw_table.o rw_new.o lagrange.o feedback.o nrutil.o
    ${MPICC} $(CFLAGS) $^ -o $@ $(LIBS) -L$(THIS_DIR)/besselh $(THIS_DIR)/besselh/libamos.a

Everything works marvelously with the GNU compilers, but I am currently trying to compile on a cluster that predominantly uses Intel Compilers, and -lgfortran is not found.

I read up in Intel's documentation that using the -nofor-main flag should allow the linking to occur, but the compiler just complains about a linking error:

    cc -DDEBUG_INPUT -Wall -O2  -I/opt/local/include besselh/libamos.a mbtrack-mpi.o 
 confmpi.o input.o test.o manager_weakweak.o worker_weakweak.o bunch_weak.o 
 transform_weak.o cyclic_array.o manager_weakstrong.o worker_weakstrong.o 
 bunch_strong.o fbi_weakstrong.o rw_weakstrong.o bunch.o stats.o physic.o statistics.o 
 tracking.o rw_table.o rw_new.o lagrange.o feedback.o nrutil.o -o ../mbtrack-mpi -lm -
 lifcore -lifcoremt  -L/global/u1/j/jackb/work/new_rw_2/src/besselh 
 /global/u1/j/jackb/work/new_rw_2/src/besselh/libamos.a

/opt/intel/composer_xe_2013_sp1.2.144/compiler/lib/intel64/libifcore.a(for_main.o): dans la fonction « main »:

for_main.c:(.text+0x54): référence indéfinie vers « MAIN__ »
/usr/bin/ld: erreurs de lien trouvés, destruction de l'exécutable « ../mbtrack-mpi »
make: *** [../mbtrack-mpi] Erreur 1

I was wondering if there was anything as simple as the -lgfortran library flag that I used with the GNU compilers?

In an attempt to adapt the compilers on the cluster:

Here is the rule to compile the library:

   ./besselh/libamos.a : FORCE
               cd besselh/; $(MAKE) libamos.a

And the contents of the Makefile in the besselh directory:

libamos.a: $(files_o)
#       ftn -nofor-main -fdefault-real-8 -fdefault-double-8 -c $(files_f)
        ar cru libamos.a $(files_o)
        ranlib libamos.a

$(files_o): $(files_f)
        ftn -nofor-main -c $(files_f)
clean: 
        rm -f $(files_o)
        rm -f libamos.a

Solution

  • If you just want Bessel functions in C, aren't those in the C99 standard enough? http://www.gnu.org/software/libc/manual/html_node/Special-Functions.html

    The correct option to disable the Fortran specific main in Intel Fortran is -nofor-main.

    libgfortran is the Fortran runtime library of gfortran. If you compiled the Fortran subroutines with gfortran and are just calling them from C source compiled with icc it should work.

    If you are using Intel Fortran, then it of course doesn't have it. It has its own runtime libraries libifcore and libifcoremt. You should link them via -lifcore -lifcoremt or by linking using ifort instead of icc. But it is quite likely you will not need them.

    Finally, it shouldn't be a problem to find a C library. Try the GNU Scientific Library. I think the Intel's MKL contains them too.