3

CMake を使用して複数の Fortran-90+ 実行可能ターゲットをビルドすると、すべての実行可能ファイルで共有される Fortran モジュールを使用し、make -j. 問題は、コンパイルされたオブジェクトファイルがターゲットごとに異なるサブディレクトリに配置されているようCMakeFiles/targetName.dir/src/file.f90.oですが、モジュールファイルはターゲットごとに同じディレクトリに配置されているようです ( を設定してこのディレクトリを変更できますFortran_MODULE_DIRECTORYが、それでも同じディレクトリになります)すべてのモジュール ファイル)。問題は、すべてのターゲットがこれらのモジュール ファイルを並行して書き始めることです Fatal Error: Can't rename module file 'module.mod0' to 'module.mod': No such file or directory 。gfortran を使用すると、.mod0 ファイルが作成され、名前が .mod に変更されます。-j オプションなしで make を発行した場合 (シリアル ビルド)、問題は発生しません。

2 つの解決策を確認できますが、それらを実装する方法がわかりません。まず、すべてのターゲットのオブジェクト ファイルを、ターゲット固有のディレクトリではなく、同じディレクトリに配置します。N 個のターゲットに対して共有ソース ファイルを N 回コンパイルする必要がないため、これが好ましいオプションかもしれません。make プロセスは、オブジェクト ファイルが存在することを認識し、対応するソース ファイルを再度コンパイルしないため、.mod(0) ファイルに再度触れません (次のすべてのターゲットを最初のものに依存させる必要がある場合があります)。

2 番目の解決策は、.mod(0) ファイルをターゲット固有のディレクトリに配置して、他のターゲットによって上書きまたは削除されないようにすることです。これにより、必要以上のコンパイルが必要になりますが、私の問題は解決します。どちらのオプションを達成する方法もわからないので、ヒントや代替ソリューションを歓迎します。

4

1 に答える 1

2

私が探していた答えは、@RaulLaasner による質問へのコメントで提供されました。

関連するソース ファイルのコア ライブラリの形式で追加のターゲットを作成し、それをすべての実行可能ファイルにリンクできます。これは並行して機能するはずです。mod ファイルは、1 つのディレクトリに配置できます。

add_library()これを達成するためにとを使用しtarget_link_libraries()ました。

たとえば、Gentoo ebuild スクリプト--as-neededがリンカーに追加されるため、コア ライブラリと外部ライブラリをリンクして実行可能ファイルを形成するときに、コア ライブラリで未定義の参照が発生する可能性があることに注意してください。これを防ぐには、最初に外部ライブラリをコア ライブラリにリンクしてください。この目的のために、私の CMakeListst.txt には以下が含まれています。

add_library( "Core" STATIC src/functions.f90 src/routines.f90 )  # creates libCore.a
target_link_libraries( Core ${EXTERNAL_LIBRARIES} )              # link external libraries to libCore.a
...
add_executable( myProgram1 src/myProgram1.f90 )                  # creates the first executable
target_link_libraries( myProgram1 Core )                         # links libCore.a to myProgram1 

最後の 2 行を繰り返して、他の実行可能ファイルをビルドできます (たとえば、foreach() を使用)。

于 2015-04-24T08:21:19.400 に答える