2
votes

I am trying to compile a code that is written in Fortran and then linked through the C compiler. The problem comes when I try the Intel compilers, ifort + icc. If I do the same with GNU compilers, gfortran + gcc, it works.

Bellow we can see their outputs.

ICC, not working:

ifort -c -o fonts/pgpack.o -g -fno-automatic -fPIC fonts/pgpack.f ifort: command line warning #10006: ignoring unknown option '-fno-automatic'
icc -o pgpack fonts/pgpack.o -O2 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/ -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/ -L/lib/../lib64 -L/lib/../lib64/ -L/usr/lib/../lib64 -L/usr/lib/../lib64/ -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4/ -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../ -L/lib64 -L/lib/ -L/usr/lib64 -L/usr/lib -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/ -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/ -L/lib/../lib64 -L/lib/../lib64/ -L/usr/lib/../lib64 -L/usr/lib/../lib64/ -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4/ -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../ -L/lib64 -L/lib/ -L/usr/lib64 -L/usr/lib -lifport -lifcore -limf -lsvml -lm -lipgo -lirc -lpthread -lsvml -lc -lgcc -lgcc_s -lirc_s -ldl -lc
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function '_start':
(.text+0x20): undefined reference to `main'

Note: it is strange to me that icc is linking against gcc libraries (/usr/lib/gcc/...). Is this normal/right?

GCC, working:

gfortran -c -o fonts/pgpack.o -O2 -Wall -fno-second-underscore -g -fno-automatic -fPIC fonts/pgpack.f
Warning: Nonconforming tab character in column 6 of line 15
Warning: Nonconforming tab character in column 6 of line 16
Warning: Nonconforming tab character in column 6 of line 17
Warning: Nonconforming tab character in column 2 of line 19
Warning: Nonconforming tab character in column 2 of line 20
Warning: Nonconforming tab character in column 2 of line 21
Warning: Nonconforming tab character in column 2 of line 24
Warning: Nonconforming tab character in column 2 of line 25
gcc -o pgpack fonts/pgpack.o -O2 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../.. -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../.. -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
: pgpack

I notice that some libraries being linked changed (e.g, libgfortranbegin), but that is automatically added/changed by the make system.

I already tried solutions offered by other posts, for similar errors, like use the flag (ifort)-nofor-main and (icc)-nostartfiles, but it keeps failing.

What am I missing? Thanks.

1
I'm not a Fortran coder, but the problem is that ifort does not export a symbol spelled 'main' when compiling fonts/pgpack.f. Try running nm fonts/pgpack.o and see if there's something similar to 'main' in there (you could paste the output). It could be a C vs. C++ issue for example, if icc uses different symbol naming conventions for those. In C++ this would be solved with extern "C" { <declarations> }.Ulfalizer
You really should link with whatever compiles the main program.Vladimir F
to start, both methods are displaying warnings. Warnings need to be corrected, not ignored! The different compilers have different parameters, so duplicating the parameters is not the right way. for gcc, there should also be -Wextra and -pedantic and probably something like: -std=c99user3629249
looking at the list of parameters to the 'icc' it is obvious (due to numerous repetitions of the paths to the libraries and the paths to libraries that the compiler 'should' already know about, and the '../../../' kinds of sequences in the library paths, that the OP needs to read the documentation on the compilers.user3629249
@user3629249, the path format you are complaining about (and the number of paths) very likely arises from automation, perhaps an Autoconf configure script. It is not inherently an indication of misuse or even uninformed use. It is suspicious, however, that the icc version appears to point to both Intel and GNU library directories.John Bollinger

1 Answers

2
votes

In the icc case, none of the modules you are linking provides a function main() to be the entry point of the program. That gcc nevertheless links the program successfully is probably due in part to the inclusion of -lgfortranbegin in the link. That will provide a standard (for gfortran) main() function that sets up the Fortran environment before handing off control to a differently-named routine corresponding to the PROGRAM subunit defined in pgpack.f.

It is likely possible to link an ifort-compiled object file into a complete program via icc, but apparently you need an ifort-specific starting point routine, and none of the libraries you specified provides one. In any event, it is likely wrong that you are including GCC libraries in the icc link. I presume that your build system is identifying and including those, but it is incorrect in doing so.

In any event, it is surpassingly strange that you are linking with gcc / icc when you have only a single object file derived from a Fortran source. You should be linking with the Fortran linker driver, which in both cases is the same as the Fortran compiler driver (gfortran / ifort). In that case you probably do not need any of the -L or -l options you are currently specifying.

Even if you were linking in some C routines, too, generally you should use the linker driver for the language in which the main routine is written. There are caveats, and it gets more complicated if you roll some other languages into the mix (e.g. C++), but your particular case looks very simple.