f

2014-12-29

gfortran has no include and library path envrironmental variable

gfortranでコンパイル時にインクルードパスやライブラリを指定する環境変数がないか調べた。gfortranにはインクルードパスやライブラリパスの環境変数が存在しないことがわかった。

Introduction

Fortranの自由なコンパイラにはいくつかある。その中でも安定していて将来性があるのはgfortranだ。そのため,自分でFortranプログラムを作るときはgfortranでコンパイルする。しかし,Fortranには標準ライブラリがないため,以下のどちらかの方法をとるしかない。

  • 低レベルな演算から自分で実装
  • 外部ライブラリに頼る

ある程度汎用的な演算などはモジュールやヘッダとしてまとめて使いまわせたほうが開発効率が高い。そのようにして分離されたモジュールやライブラリはコンパイル時にオプションでディレクトリを指定することで利用できる。しかし,コンパイルの度にいちいちディレクトリを指定するのは面倒だ。 Makefileに書き込んでおいてmakeでビルドする方法もある。大規模なプログラムならそれもありだが,たいした規模でないプログラムのためにいちいちMakefileを用意するのは煩雑だ。コマンドラインからコンパイルしたほうが楽だ。

自由なC/C+コンパイラであるgccg++であれば,に示した環境変数でインクルードファイル(ヘッダファイル)とライブラリのパスを指定できる。

GCCで使われるサーチパス環境変数
環境変数 説明
CPATH C言語のヘッダファイルのサーチパス
LD_LIBRARY_PATH ライブラリのサーチパス

gfortranもGCC(GNU Compiler Collection)の一部であるので同様の環境変数があってもおかしくない。そこで,これらの環境変数に該当するものがgfortranにもないか調査した。

環境変数の調査

調査にあたっては以下で公開されているGNU Fortranのマニュアルを参考にした。

GCC online documentation - GNU Project - Free Software Foundation (FSF) https://gcc.gnu.org/onlinedocs/

このgfortranのマニュアルの2.10 Environment Variables(https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gfortran/Environment-Variables.html#Environment-Variables )でgfortranの環境変数について以下のように言及されている。

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 Environment Variables Affecting GCC, for information on environment variables.

訳:gfortranは現在,上記(2.1~2.9節のコマンドオプション)とgccの動作に影響するものを超えて,動作を制御するために環境変数を使わない。

つまり,gfortranはコンパイラの動作の制御に環境変数を使わないようだ。次の3節にTMPDIRや既定の標準入力,出力,エラー出力の番号など実行時の環境変数が掲載されている。しかし,インクルードファイルやライブラリへのパスの環境変数は本当に存在しないようだ。

Runtime - The GNU Fortran Compiler https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gfortran/Runtime.html#Runtime

ちなみにIntel Fortran Compiler(ifort)など不自由なコンパイラなどではFPATHLD_LIBRARY_PATHなどでインクルードパスなどが実装されているようだ。

参考:https://software.intel.com/sites/default/files/m/f/8/5/8/0/6366-ifort.txt

個人的にはLD_LIBRARY_PATHであれば共通で使えるのではないかと思っていたが,無理のようで残念だ。自分でもINCLUDE変数などにパスを設定しコンパイルできるか試したが無理だった。

以上のことから,gfortranで外部ライブラリやモジュールを取り込む場合は面倒だがコンパイル時にフルパスで指定する必要がある。

コマンドラインからの実行

コンパイルオプションにより,インクルードやライブラリへのパスの指定方法は以下で説明されている。内容をにまとめた。

Directory Options - The GNU Fortran Compiler https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gfortran/Directory-Options.html#Directory-Options

gfortranでのコンパイル時のパス設定
オプション 説明
-I[dir] USE文(.modファイル)とINCLUDE文(.h,.f90ファイル)の検索ディレクトリ。
-J[dir] .modファイルの検索ディレクトリ。既定はカレントディレクトリ。
-L[dir] ライブラリの検索ディレクトリ。
-l[lib] ライブラリ(lib[lib].aなどの形式のファイル)名の指定。

この表の内容から,基本的には以下の書式でコンパイルすることになる。

gfortran [source1.f90 ... sourceN.f90]  -I/path/to/include -L/path/to/lib -l[lib]

例:

gfortran hi.f90 -I$HOME/local/f90/mod -L$HOME/local/lib -lposix90

この-I以降や-L以降にうまくCPATHLD_LIBRARY_PATHを当てて以下のようにできないか試してみた。

gfortran hi.f90 -I$CPATH -L$LD_LIBRARY_PATH -lposix90

うまくいかない。通常,CPATHLD_LIBRARY_PATHには複数のパスを:で区切って格納している。この:が原因でうまくパスが認識されない。複数のディレクトリを指定するときは確実にひとつずつ-I/path/to/include1 -I/path/to/include2 -L/path/to/libのように-Iや-Lを付けないと認識されない

私は$HOME/local/{include,lib}に,自分でインストールしたライブラリやインクルードを格納している。なので,LD_LIBRARY_PATHなども共通で使えたほうが忘れる心配がない。どうにかしてこれらの変数を使えないか試行錯誤した。その結果以下のようにすればCPATHLD_LIBRARY_PATHを使ってコンパイルできた。

# bash
gfortran hi.f90 -I${CPATH//:/ -I/} -L${LD_LIBRARY_PATH//:/ -L/} -lposix90
# zsh
gfortran hi.f90 -I${=CPATH//:/ -I/} -L${=LD_LIBRARY_PATH//:/ -L/} -lposix90

ここではCPATHLD_LIBRARY_PATHに含まれている:を全て -Iで置換している。zshだと空白も文字として扱われるので変数展開により対処している。これにより共通のCPATHLD_LIBRARY_PATHをうまく使ってコンパイルできる。

ただ,相変わらず面倒なことに変わりはない。ifortと同様にFPATH変数にFortranのインクルードやmodファイルのディレクトリを指定してコンパイル時にその都度指定したほうがわかりやすいだろう。

export FPATH=$HOME/local/f90/mod
gfortran hi.f90 -I$FPATH

Conclusion

今回の調査内容を以下にまとめた。

  • gfortranでインクルードファイルやライブラリのサーチパス変数がないか調べた。
  • gfortranのマニュアルからgfortranにはサーチパス変数が存在しないことがわかった。
  • 代替案として,以下二つの方法を示した。
    • CPATHLD_LIBRARY_PATHを展開して使う方法。
    • FPATH変数にインクルードファイルのディレクトリを指定して利用。

結論としては,gfortranにはサーチパス変数がないということであまりたいした成果はなかった。しかし,Fortranについてはネット上での情報が不足しているので,こうした情報も役に立つのではないかと考える。

現実的にはFPATH変数に自分のFortranモジュールの格納先を指定してコンパイル時に-I$FPATHで指定するのがよいだろう。

0 件のコメント:

コメントを投稿