Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28592 Discussions

How to compile a library use a subroutine from another library

brickflying
Beginner
378 Views
Hi
I have 3 f90 files. lib1.f90 and lib2.f90 are in directory /path1. main.f90 is in /path1/path2. Details of these files are list below.
The contents of lib1.f90:
subroutine sub1 ()
...
endsubroutine sub1
subroutine sub2 ()
...
endsubroutine sub2
subroutine sub3 ()
...
endsubroutine sub3
The contents of lib2.f90:
module mod1
integer :: i
...
contains
subroutine sub4 ()
...
endsubroutine sub4
subroutine sub5 ()
...
call sub1()
call sub2()
call sub3()
...
endsubroutine sub5
endmodule mod1
The contents of main.f90:
PROGRAM
use mod1
call sub4()
call sub5()
end
I want to compile lib1.f90 as lib1.a and lib2.f90 as lib2.a.
ifort -c lib1.f90 -o lib1.o
ar rcv lib1.a lib1.o
ifort -c lib2.f90 -o lib2.o
ar rcv lib2.a lib2.o
so there will be mod1.mod in /path1
and then create main.x
$ifort -I../mod1.mod -L../lib1.a -L../lib2.a main.f90
main.f90(1): error #7002: Error in opening the compiled module file. Check INCLUDE paths. [MOD1]
use mod1
----^
compilation aborted for main.f90 (code 1)
why I include the mod name and path but compiler can't find it?
Then I change it like this:
$ ifort -I../ -L../lib1.a -L../lib2.a main.f90
/tmp/ifortKAQrlg.o: In function `MAIN__':
main.f90:(.text+0x33): undefined reference to `mod1_mp_sub4_'
main.f90:(.text+0x38): undefined reference to `mod1_mp_sub5_'
It seem mod could be found. But sub4 and sub5 in lib2.a haven't been defined. Some advice?
If I just compile 3 files together:
ifort ../lib1.f90 ../lib2.f90 main.f90
everything goes well.
Thanks a lot.
0 Kudos
1 Solution
Kevin_D_Intel
Employee
378 Views

First, -I accepts only a path argument so that's why the case specifying the path and module file name (mod1.mod) did not work. You only need to specify the path to the module file(s) not the actual name(s).

Similarly, -L only specifies the path to libraries. You should also use the l (lowercase) to specify the actual library names without the leading "lib" and trailing ".a".

Next, the undefined references relate to the order the linker sees the lib (.a) and object file for main.f90.

You can successfully compile/link your sample program using the commands below. I changed your lib names to libONE.a and libTWO.a to help show use of the l option.

cd /path1

ifort -V -c lib1.f90 -o lib1.o
ar rcv libONE.a lib1.o

ifort -V -c lib2.f90 -o lib2.o
ar rcv libTWO.a lib2.o

cd path2
ifort -V -I.. main.f90 -L.. -lTWO -lONE

It is important to note the compilation of main.f90 and subsequent link for the ifort command line above only succeed because of the order the files appear on the command line given their inner dependencies.

You can avoid this ordering requirement using the linker's --start-group/--end-group to repeatedly search archives until all external references are resolved. Normally an archive is searched only once and in the order specified on the command-line. Notice that libONE and libTWO have switched positions below.That's just an attempt to show the link succeeds related to the linker repeatedly searching those two archives to resolve externals.

The alternative to the ifort command for main.f90 above is to compile main.f90 to an object file and then link all components as shown:

ifort -V -I.. -c main.f90
ifort -V -L.. main.o -Wl,--start-group,-lONE,-lTWO -Wl,--end-group

Hope that helps.

View solution in original post

0 Kudos
1 Reply
Kevin_D_Intel
Employee
379 Views

First, -I accepts only a path argument so that's why the case specifying the path and module file name (mod1.mod) did not work. You only need to specify the path to the module file(s) not the actual name(s).

Similarly, -L only specifies the path to libraries. You should also use the l (lowercase) to specify the actual library names without the leading "lib" and trailing ".a".

Next, the undefined references relate to the order the linker sees the lib (.a) and object file for main.f90.

You can successfully compile/link your sample program using the commands below. I changed your lib names to libONE.a and libTWO.a to help show use of the l option.

cd /path1

ifort -V -c lib1.f90 -o lib1.o
ar rcv libONE.a lib1.o

ifort -V -c lib2.f90 -o lib2.o
ar rcv libTWO.a lib2.o

cd path2
ifort -V -I.. main.f90 -L.. -lTWO -lONE

It is important to note the compilation of main.f90 and subsequent link for the ifort command line above only succeed because of the order the files appear on the command line given their inner dependencies.

You can avoid this ordering requirement using the linker's --start-group/--end-group to repeatedly search archives until all external references are resolved. Normally an archive is searched only once and in the order specified on the command-line. Notice that libONE and libTWO have switched positions below.That's just an attempt to show the link succeeds related to the linker repeatedly searching those two archives to resolve externals.

The alternative to the ifort command for main.f90 above is to compile main.f90 to an object file and then link all components as shown:

ifort -V -I.. -c main.f90
ifort -V -L.. main.o -Wl,--start-group,-lONE,-lTWO -Wl,--end-group

Hope that helps.

0 Kudos
Reply