2016-07-08 14 views
1

私はFortran95で新しいプロジェクトを開始しました。これはすばやく大きくなるはずです(多くのモジュール)。現時点では私は大きなプロジェクト用のFORTRAN Makefile

  • output.f90
  • moldyn.f90

output.f90は、いくつかのパブリック変数、2つのパブリックサブルーチンと2つのプライベートサブルーチンとモジュールが含まれています。 moldyn.f90には、output.f90に含まれる2つのパブリックサブルーチンを呼び出すメインプログラムが含まれています。

私は大規模なプロジェクトに取り組むのは初めてですから、できるだけコンパイルとリンクを一般化して簡単に適応できるMakefileを作成して自動化したいと思います。これまでに作成したMakefileは、コンパイルとリンクのステートメントだけがハードコーディングされており、大規模なプロジェクトでは、プロセスを自動化したい(ただし、他のツールをCMakeとして使用しない)。

これは、残念ながら動作しません。私の試みです:

# ======== 
# Makefile 
# ======== 

# Makefile name 
MF = Makefile 

# ========== 
# Executable 
# ========== 

# Executable name 
EXE = $(BINDIR)/moldyn.x 

# ======== 
# Compiler 
# ======== 

# Fortran compiler 
FC = gfortran 

# Fortran flags 
FFLAGS = -O2 -Wall -Warray-bounds -fbounds-check 

# =========== 
# Directories 
# =========== 
SRCDIR = src 
BINDIR = bin 
OBJDIR = obj 
MODDIR = mod 

# ======== 
# Suffixes 
# ======== 

.SUFFIXES: 
.SUFFIXES: .f90 .o .mod 

# =================== 
# Sources and objects 
# =================== 

SRC = \ 
    $(SRCDIR)/moldyn.f90\ 
    $(SRCDIR)/output.f90 

OBJ = $(SRC:$(SRCDIR)%.f90=$(OBJDIR)%.o) 

# ===== 
# Rules 
# ===== 

all: 
    @echo $(SRC) 
    @echo $(OBJ) 

moldyn: $(OBJDIR)/.o $(EXE) 

$(EXE): $(OBJ) 
    $(FC) $(FFLAGS) -o $(SRCDIR)/[email protected] $(OBJ) 

$(OBJDIR)/.o: 
    $(FC) $(FFLAGS) -c $(SRC) 

$(OBJ): $(MF) 

# ======= 
# Folders 
# ======= 

$(BINDIR): 
    mkdir -p $(BINDIR) 

$(OBJDIR): 
    mkdir -p $(OBJDIR) 

$(MODDIR): 
    mkdir -p $(MODDIR) 

# ===== 
# Clean 
# ===== 

clean: 
    rm -f src/*~ 
    rm -fr $(BINDIR) $(OBJDIR) $(MODDIR) 

私は混乱は、私はSRC /フォルダ内のソースを持っていると私はANでの.oを作成したいということから来ていると思いますobj /フォルダーとbin /フォルダー内の実行可能ファイル。 .modファイルはdaseフォルダ(メークファイルがあるところ)に作成されているので役割も果たしていますが、実際の扱い方はわかりません(これは私の最初のFortranプロジェクトです)。

誰でもコンパイルの問題の原因を理解できますか?私が得るエラーは、次のとおりです。

gfortran -O2 -Wall -Warray-bounds -fbounds-check -c src/moldyn.f90 

src/output.f90 
src/moldyn.f90:20.6: 

    use output, only: title, gpl 
     1 
Fatal Error: Can't open module file 'output.mod' for reading at (1): No such file or directory 
make: *** [obj/.o] Error 1 

.modファイルと関連しているようです。

+0

ディレクトリ内を見て、ファイルが置かれている場所を確認します。どのようにして* .oファイルを$(OBJDIR)に入れるのですか? * .oファイルは$(SRC)ディレクトリにあり、$(OBJDIR)ではありません。 – KeithSmith

+0

@KeithSmith 'make all'を使って、' OBJ = $(SRC:$(SRCDIR)%.f90 = $(OBJDIR)%.O) 'というコマンドがパスをテストしたところ、期待通りに動作します。 $(OBJDIR)/と一緒に。ただし、* .oと* .modはカレントディレクトリに作成されます。 –

+0

手作りのメークファイルは悪夢です。 CMakeは大規模なプロジェクトに適しています。私はSConsを代わりに使用します。なぜなら、私はまだ別の言語を学びたくないからSConsはちょうどPythonだからです。 –

答えて

1

私はあなたのメイクファイルの質問はすべて、このスタックオーバーフローの投稿にかなり答えられていると思う: Automatic Ordering of Obejct Files "*.o" in a Fortran Makefile

具体的なエラー限り、あなたの* .modファイルの場所を教えるために、あなたのgfortranコールに-I $(OBJDIR)を含める必要があります。

gfortran -O2 -Wall -Warray-bounds -fbounds-check -I obj/ -c src/moldyn.f90 

CMakeを再考しないでください。 Fortran/C/C++コードベース(Fortran /〜Cの90万行〜800,000行)が非常に大きく、CMakeにはかなり満足しています。私たちのためには、Windows/Mac/Linux上に/ test/deployをビルドする必要があります.Makeはそれを行います。我々はGNUとインテルのコンパイラも使用し、それを処理します。また、デバッグとリリースビルド、カバレッジテスト、およびメモリリークビルドも行っています。 CTestを使用したテストハーネスと、CDashを使用した継続的な統合ダッシュボードも提供します。それはあなたのプロジェクトが大きくなったら移動することができるものです。だからあなたのプロジェクトが小さい間、Makefileのアプローチを使用してください。限界を感じ始めたら、精巧なMakefile生成スキームに多くの時間をかけないでください。私はその道を歩いています。 CMakeに切り替えるだけです。example of CMake for Fortranへのボーナスリンクがあります。私が迷惑なアドバイスをしている間、「ソース」ビルドをしないでください。理由は、this blog post by Jussi Pakkanenでかなりよくまとめられています。

0

VPATH = <path>を使用して、makeにソースファイルの場所を指定できます。 .modファイルの作成場所を変更するには、コンパイラフラグが必要です。 gfortranの場合、フラグは-J<path>です。.oファイルが構築されますどこ

は、あなたがこのような何かを行うことができ、指定するには:redwizard792が示唆したように、あなたは自動的に .oファイルの依存関係を生成するために this answerを使用することができます

# Current directory 
BASEPATH = $(shell pwd) 

# Absolute paths to the directories 
SRCDIR = $(BASEPATH)/src 
BINDIR = $(BASEPATH)/bin 
OBJDIR = $(BASEPATH)/obj 
MODDIR = $(BASEPATH)/mod 

# Put module files in their own directory 
FFLAGS += -J$(MODDIR) 

# Search path for source code 
VPATH = $(SRCDIR) 

... 

# Using VPATH, so no need to give full path to source 
SRC = \ 
    moldyn.f90\ 
    output.f90 

# Replace .f90 with .o 
OBJ_O = $(patsubst %.f90,%.o,$(SRC) 
# Prepend object path 
OBJ = $(addprefix $(OBJPATH)/,$(OBJ_O)) 

... 

$(OBJDIR)/%.o: %.f90 
    # Check object and binary directories exist, make them if necessary 
    # We can use the $(@D) magic variable to get the directory 
    @mkdir -p $(@D) 
    # [email protected] means the left-hand side of the recipe 
    # $< means all of the right hand side 
    $(FC) $(FFLAGS) -c -o [email protected] $< 

。そうしている場合は、その回答からのメイクファイルへの追加も含める必要があります。

関連する問題