Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gfortran include path -- is there an alternative to passing multiple -I options?

I have some Fortran code which uses included modules, and I am wondering what environment variables actually work to set the include path.

To test this out I've been using one of the NAG example codes.

This works:

$ gfortran e04ucfe.f90 -lnag_nag -I/opt/NAG/fll6a23dfl/nag_interface_blocks

This doesn't work:

$ export CPATH=/opt/NAG/fll6a23dfl/nag_interface_blocks
$ gfortran e04ucfe.f90 -lnag_nag
e04ucfe.f90:10.37:

       USE nag_library, ONLY : nag_wp
                                     1
Fatal Error: Can't open module file 'nag_library.mod' for reading at (1): No such file or directory

However, the GCC/GFortran documentation states that:

The gfortran compiler currently does not make use of any environment variables to control its operation above and beyond those that affect the operation of gcc.

(see https://gcc.gnu.org/onlinedocs/gfortran/Environment-Variables.html and https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#Environment-Variables)

I've tried ltrace-ing the gfortran run and can see it looking at other environment variables (e.g. the regular PATH) but not CPATH.

I can work around this with this:

gfortran e04ucfe.f90 -lnag_nag `echo -I$CPATH | sed -e 's/:/ -I/'`

...but why is this necessary? CPATH works fine with gcc, including for other languages than C/C++, so why doesn't this work with gfortran? Is there something I can successfully use to the same effect as CPATH for gcc with gfortran, to avoid having to pass multiple -I arguments?

Side note: LIBRARY_PATH works fine in a similar way, for replacing the -L/path/to/libs on the gfortran command-line.

like image 300
David Gardner Avatar asked Jun 02 '14 09:06

David Gardner


2 Answers

As far as I know gfortran does not support this, which is quite annoying. But it is possible to work around it. If you name the following script gfortran and put it in a directory in your $PATH that is searched before the one with the real gfortran in it, then you will have the behavior you want, with $CPATH transparently being expanded into -I arguments:

#!/bin/bash
/path/to/gfortran $(for i in ${CPATH//:/ }; do echo -I"$i"; done) "$@"

Remember to mark it as executable. For example, if my $PATH is /home/amaurea/local/bin:/usr/local/bin:/usr/bin:/bin and gfortran lives in /usr/local/bin, I would set it up as

$ cd /home/amaurea/local/bin
$ cat <<HERE > gfortran
#!/bin/bash
/usr/bin/gfortran $(for i in ${CPATH//:/ }; do echo -I"$i"; done) "$@"
HERE
$ chmod a+x gfortran

Alternatively you can formulate it as a shell alias, but that would be less flexible and will not work in as many situations.

like image 170
amaurea Avatar answered Nov 11 '22 12:11

amaurea


If you are using Makefiles, I got this to work using the subst command. This replaces the : with -I for each path in the file.

usr/bin/gfortran e04ucfe.f90 -lnag_nag -I${subst :, -I,$(CPATH)}
like image 22
Mr.P Avatar answered Nov 11 '22 10:11

Mr.P