4

ライブラリをビルドしたり、ソース コードを複製したりせずに、複数の Fortran プロジェクト間でコードを共有するかどうか、またはその方法を理解するのに苦労しています。

Linux システムで Intel コンパイラ (ifort) と一緒に Eclipse/Photran を使用していますが、特定のツールよりもモジュールに大きな概念上の問題があると思います。

簡単な例を次に示します。~/workspace/cow には、cow.f90 (プログラム) を含むソース ディレクトリ (src) と、m_graze.f90 と m_moo.f90 にそれぞれ m_graze と m_moo という 2 つのモジュールがあります。このプロジェクトは、実行可能ファイル 'cow' を作成するために適切にビルドおよびリンクされます。実行可能ファイルとモジュール (m_graze.mod および m_moo.mod) は ~/workspace/cow/Debug に保存され、オブジェクト ファイルは ~/workspace/cow/Debug/src に保存されます。

その後、~/workplace/sheep を作成し、src/sheep.f90 をプログラムとして、src/m_baa.f90 をモジュール m_baa として作成します。ruminate() サブルーチンにアクセスするために、sheep.f90 で「m_graze のみ: ruminate を使用」したいと考えています。m_graze.f90 をコピーすることもできますが、コードが同期しなくなり、m_graze の依存関係が考慮されない可能性があります。これらの理由から、m_graze を cow プロジェクトに残して、それに対して shep.f90 をコンパイルしてリンクしたいと思います。

羊のプロジェクトをコンパイルしようとすると、次のようなエラーが発生します。

error #7002: Error in opening the compiled module file.  Check INCLUDE paths.   [M_GRAZE]

[プロパティ: 羊のプロジェクト参照] で、牛のプロジェクトを選択できます。Properties:Fortran Build:Settings:Intel Compiler:Preprocessor の下で、~/workspace/cow/Debug (モジュール ファイルの場所) をインクルード ディレクトリのリストに追加して、コンパイラが牛のモジュールを見つけて、sheep.f90 をコンパイルするようにします。ただし、リンカーは次のようなもので終了します。

Building target: sheep
Invoking: Intel(R) Fortran Linker
ifort -L/home/me/workspace/cow/Debug -o "sheep"  ./src/sheep.o
./src/sheep.o: In function `sheep':
/home/me/workspace/sheep/src/sheep.f90:11: undefined reference to `m_graze_mp_ruminate_'

これは通常、リンクする適切なライブラリがない場合を除いて、ライブラリとライブラリ パスをリンカー設定に追加することで解決されます (これは C ではなく Fortran です)。

牛プロジェクトは、cow.f90、m_graze.f90、および m_moo.f90 を実行可能ファイルにコンパイルおよびリンクすることが完全に可能でした。ただし、sheep プロジェクトは、sheep.f90 および m_baa.f90 をコンパイルし、m_graze.mod モジュールを見つけることができますが、必要な情報がすべてシステムに存在するにもかかわらず、m_graze のシンボルを見つけることができないようです。 .

ifort のリンカ部分に不足している部分を見つけてそれらを結合させるのは簡単な構成のように思えますが、これを実現するために Photran UI のどこにどのマジック ワードを入力する必要があるかわかりません。

私は、C および C のビルド プロセスに対する関心と能力が完全に欠如していることを認めます。これを機能させる唯一の方法でない限り、ライブラリ (.a または .so) を作成する流用は避けたいと思います。

最終的に、私はこの問題に対する純粋な Fortran ソリューションを探しています。これにより、ソース コードの単一のコピーを保持でき、カスタム Makefile の山を手動で維持する必要がなくなります。

それで、これはできますか?

これがすでにどこかに文書化されている場合はお詫びします。Google は、簡単なビルド例、モジュールの作成方法、および既存のライブラリとのリンク方法を示しているだけです。ソースコードの複製を伴わないモジュールでのコードの再利用の例は (m) ないようです。


編集

回答者が指摘しているように、.mod ファイルは必要ですが、十分ではありません。リンク フェーズでは、オブジェクト コード (m_graze.o の形式) または静的ライブラリまたは共有ライブラリのいずれかを指定する必要があります。.mod ファイルは、オブジェクト コード/ライブラリへのインターフェイスを記述しますが、最終的な実行可能ファイルをビルドするには両方が必要です。

このような非常に単純化されたおもちゃの問題の場合、提示された質問に答えるにはこれで十分です。

より複雑な依存関係を持つ大規模なプロジェクト (私の場合、LAPACK95 の MKL バージョンにリンクする F90 の 80 + KLOC) では、IDE またはツールチェーンに、単一の標準的なソース ファイル セットを共有するための十分な自動またはユーザー インターフェイス機能がない場合があります。実行可能な戦略。選択は、重複するソース ファイルが同期しなくなる危険を冒すか、IDE の多くの利点を放棄するか (つまり、make/CMake/SCons ファイルの手動作成を回避する)、またはおそらくその両方のいずれかのようです。リビジョン管理システムと優れたコード編成は役に立ちますが、現在の Eclipse の状態を考えると、プロジェクト間でソース ファイルの単一の標準セットを共有することは決して容易ではないことは明らかです。

4

2 に答える 2

1

はい、オブジェクト コードを提供する必要があります。たとえば、Debian に libnetcdf-dev をインストールすると ( apt-get install libnetcdf-dev)、/usr/include/netcdf.mod含まれるファイルがあります。

Fortran コードですべての netcdf ルーチンを使用できるようになりました。例えば、

program main
use netcdf
...
end 

ただし、netcdf 共有 (または静的) ライブラリへのリンクがあります。つまり、

gfortran -I/usr/include/ main.f90 -lnetcdff

ただし、ユーザー MSB が述べたように、mod ファイルはディストリビューションに付属する gfortran でのみ使用できます ( apt-get install gfortran)。他のコンパイラ (自分でインストールした別のバージョンであっても) を使用したい場合は、その特定のコンパイラを使用して netcdf を自分でビルドする必要があります。

したがって、ライブラリを作成することは悪い解決策ではありません。

于 2013-05-04T12:18:26.133 に答える