2016-07-27 13 views
0

私のプログラムはintel MKLを使用するmpiプログラムです。シンプルなため、そこに、私たちはa.f90は、他の人が必要と呼ばれるモジュールmymodFortran 90のメークファイルが生成され、未解決の外部シンボル

通常

私が原因初めて、私はちょうどそれを2回行い、この

mpiifort *90 /fast /Qmkl /MD -o main.exe 

のようにそれをコンパイルします含まれているmain.f90 a.f90 b.f90があると仮定しましょうmymod.mod

今、私は再コンパイル時間を短縮したいので、私はmakefileを使いたいと思います。私はこのように書いています。

IFORT = /fast 
MKL =/Qmkl 
LDFLAGS = /MD 
main:main.obj b.obj 
    mpiifort $(IFORT) $(MKL) $(LDFLAGS) $< -o [email protected] 
mymod.mod:a.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
main.obj:main.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
b.obj:b.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 

ただし、ここに何か間違いがあります。私はunresolved external symbolの束を得た。なにが問題ですか?

+2

私はメイクファイルのエキスパートではありませんが、 'main'ターゲットは' mymod.mod'に明示的な依存関係を持たないように見えるので、これは構築されません。私も完全に間違っている可能性があります –

答えて

0

まず、他の誰かがより良い/より完全な回答を書くことができます(または私たちに指示してください)。私はこれを歓迎しますが、私は非常に簡単な例を示します。

今、私たちは、エラーの(可能性)のソースを識別することができます:私たちはちょうどtouchとコンパイルコマンドを交換する場合、我々はその後、私たちの「ソースを構築した場合、我々はこの問題に

main:main.obj b.obj 
     touch [email protected] 
mymod.mod:a.f90 
     touch [email protected] 
main.obj:main.f90 
     touch [email protected] 
b.obj:b.f90 
     touch [email protected] 

を示して簡単な例を生成することができます私たちはその後、私たちのmain実行ファイルをビルドしようとすることができます

>touch main.f90 b.f90 a.f90 

とファイル」:

>make main 

た出力は以下となります。これはmymod.modファイルを作成しませんか

touch main.obj 
touch b.obj 
touch main 

注意。つまり、あなたのケースでは、mainをビルドするときにa.f90がコンパイルされず、したがって必要なsymobolsが利用できません(つまり、関数/ルーチンなどがある場合、a.objは使用できません)。私たちは今

main:main.obj b.obj mymod.mod 
     touch [email protected] 
mymod.mod:a.f90 
     touch [email protected] 
main.obj:main.f90 
     touch [email protected] 
b.obj:b.f90 
     touch [email protected] 

をする私たちのメイクファイルを調整することにより、mainmymod.modに依存していることが示された場合は、我々は今、(最初rm *.obj mymod.mod mainを実行してクリーンアップ後)mainを構築しようとすることができ、我々が得る:だから私たちは

>make main 
touch main.obj 
touch b.obj 
touch mymod.mod 
touch main 

建物mainの一部としてmymod.modターゲットを構築するには、makeが成功しました。実際には、一部のターゲットが他のターゲットの前に構築されていることを確認することをお勧めします(例えばa.f90b.f90の前にコンパイルしたいとします)。自動的に生成する依存関係リストを使用してこれを行うことができます(例えば、this questionを参照)。

+0

ありがとうd_1999。私は簡単な方法を見つけます:) – user15964

0

私たちは、インテルFortran

インテルFORTRANを使用している場合、私は一種の自動化されて方法を考え出すオプションがgen-depと呼ばれ、それが自動的に解析し、出力依存情報は、メイクファイルに使用することができます提供します。MODファイルの欠落が原因のエラーメッセージが表示されている場合だから、を次のコマンドを実行し、2回だけそれを実行

mpiifort *90 /Qmkl /gen-dep > dependency.txt 

我々はdependency.txtを得ました。それを開くと、このようなものが見つかるでしょう

mpifc.bat for the Intel(R) MPI Library 5.1.2 for Windows* 
Copyright(C) 2007-2015, Intel Corporation. All rights reserved. 

mymod.mod : \ 
    a.f90 

a.obj : \ 
    a.f90 

b.obj : \ 
    b.f90 mymod.mod 

main.obj : \ 
    main.f90 \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi_base.mod \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi_sizeofs.mod \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi_constants.mod \ 
    c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\include\mpi.mod \ 
    mymod.mod 

Microsoft (R) Incremental Linker Version 14.00.23026.0 
Copyright (C) Microsoft Corporation. All rights reserved. 

-out:a.exe 
-subsystem:console 
"-libpath:c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mkl\lib\intel64_win" 
"/LIBPATH:c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\lib\release_mt" 
"/LIBPATH:c:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2016.1.146\windows\mpi\intel64\bin\..\..\intel64\lib" 
impi.lib 
a.obj 
b.obj 
main.obj 

これらのmpiに関連するモジュールは静的なので、削除してください。簡単なテキスト操作(regexを使うのはよい選択です)をして、もっと明確かつコンパクトにするために、このような正しいmakefileを得ることができます。(私の疑問にはいくつかのエラーを修正しました)

IFORT = /fast 
MKL =/Qmkl 
LDFLAGS = /MD 
a: a.obj b.obj main.obj 
    mpiifort $(IFORT) $(MKL) $(LDFLAGS) $^ -o [email protected] 
mymod.mod : a.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
a.obj : a.f90 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
b.obj : b.f90 mymod.mod 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
main.obj : main.f90 mymod.mod 
    mpiifort /c $(IFORT) $(MKL) $(LDFLAGS) $< 
+0

それでも、プロジェクトに新しいファイルを導入するのは大きな苦労です。だから私はもうFortranに 'make'を使わないのです。 'cmake'、' scons'、 'waf'といった自動ビルドツールがはるかに優れています。 –

+0

@VladimirFこんにちは、ウラジミール。数年前、私はmakefileが単なる不要だと思った。ビルド、クリーンアップなど、さまざまな作業モードをカスタマイズするのに便利なので、私はmakefileを使い始めました。数日前、私はバグを激しくトレースしているので、再コンパイルがうまくいかず、依存関係を指定するより良いmakefileを書く必要があります。近い将来、私はあなたのようなメイクファイルに完全に疲れています:)ところで、伝統的な方法を比較するためにfortranのためのcmakeまたは他のツールの簡単なイラストを追加したいですか?私はこのサイトを検索し、問題の良い答えは見つかりませんでした。 – user15964

+0

ここに何かを置くのは、話題にならないでしょう。ここではcmakeについて多くの質問がありますhttp://stackoverflow.com/search?q=cmake%2Bfortranそしてsconsについてはgithub https://github.com/LadaF/PoisFFT/blob/master/src/SConstructで何かを見つけてください1つは私のものです)。 cmakeのドキュメントサイトもあります。http://stackoverflow.com/documentation/cmake/topics –

関連する問題