2016-03-21 8 views
1

以下の簡単なMakefileを考えてみましょう。それぞれに対応する.hと.cppファイルを持つ2つのクラスがあることに注目してください。C++プログラム用の堅牢なMakefileの作成

output: main.o class1.o class2.o 
    g++ main.o class1.o class2.o -o output 

main.o: main.cpp 
    g++ -c main.cpp 

class1.o: class1.cpp class1.h 
    g++ -c class1.cpp 

class2.o: class2.cpp class2.h 
    g++ -c class2.cpp 

clean: 
    rm *.o output 

このメイクファイルは堅牢ですか?どうすればより堅牢にすることができますか?誰かがこのMakefileのより堅牢なバージョンを提供できますか? 64ビットRed Hat LinuxまたはCentOSマシン上で実行されます。

それが重要ならば、私が使用しています:

-gcc --version 4.8.4(GNUコンパイラコレクションより)

-gdbバージョン:GNU gdbの(Ubuntuの7.7.1〜14.04 -0ubuntu5を0.2)7.7.1

+0

「堅牢」とは何ですか? Makefileにはいくつかの欠陥があります(例えば、強制フラグとオプションフラグを設定する方法、自動依存トラッキング、VPATHビルドを設定しないなど)。 – ensc

+2

CMakeを使用している場合、なぜMakefileを持っていますか? – Biffen

+0

@ビフェン - 私はCMakeなしで他の誰かに申請書を送付しなければなりません。 –

答えて

2

私が書くと何かのような

CXX = g++ 
# mandatory build flags 
AM_CXXFLAGS = -Wall -W -std=gnu++11 
# optional build flags 
CXXFLAGS = -O2 -Werror 

# mandatory link flags 
AM_LDFLAGS = -Wl,-as-neeeded 

output: main.o class1.o class2.o 
    ${CXX} ${AM_LDFLAGS} ${LDFLAGS} $(filter %.o,$^) -o [email protected] 

%: %.cpp 
    ${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} $< -c -o [email protected] 

class1.o: class1.cpp class1.h 
class2.o: class2.cpp class2.h 
  • *FLAGSですautomakeの記法に従う:AM_*平均必須フラグ、通常のフラグにはローカル設定が含まれています(例:デバッグまたは最適化)。

    通常、プリプロセッサフ​​ラグ(-I ...)とAM_CPPFLAGSCPPFLAGSも使用する必要がありますが、私はoutputターゲットはここでは省略されている

  • すぎ${LIBS}が必要になる場合があります依存関係の追跡がよりある

    ここ
  • それらを省略トリッキーでではないが実装されています。あなたのプログラムがリストされている5つのファイルでのみ構成されている場合、あなたは直接

    output_SOURCES = main.c class1.c class2.c class1.h class2.h 
    
    output: ${output_SOURCES} 
         ${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${AM_LDFLAGS} ${LDFLAGS} $(filter %.cpp,$^) -o [email protected] ${LIBS} 
    

    を書くことができます

...ここ-dMコンパイラオプションでプレイする必要があります。

EDIT:依存関係の自動追跡するための

、私はそれをより堅牢にするにはどうすればよい

DEPGENFLAGS = \ 
    -MD -MF ${@D}/.${@F}.d -MT '[email protected]' 

%: %.cpp 
    ${CXX} ${DEPGENFLAGS} ${AM_CXXFLAGS} ${CXXFLAGS} $< -c -o [email protected] 

-include .deps.main.o.d 
-include .deps.class1.o.d 
-include .deps.class2.o.d 
0

を書き込むことができますか?

暗黙のルールを使用して、単純にしてください。

LDLIBS+=-lstdc++ 
output: main.o class1.o class2.o 

clean: 
    rm *.o output 
+0

これは非常に短いです!この実装には他のソリューションと比較して何らかの欠点がありますか? –

+0

移植性が低く、gnu makeでうまくいきます –

2

私はあなたの元のメイクファイルがはるかに目立つとは思わない。 - それは

  • をg ++
  • main.oを作るために、すべての呼び出しでCXXFLAGS環境変数を使用して明示的class1.hclass2.hに依存することは良いことだ

    1. 追加デフォルトallターゲット:私はいくつかの追加を行いました議論したよう
    2. cleanはあなたがclean
    と呼ばれるビルドアーティファクトを追加する場合は念のためにPHONYターゲットであることを指定します
    ALL := output 
    
    all : $(ALL) 
    
    output: main.o class1.o class2.o 
        g++ $(CXXFLAGS) main.o class1.o class2.o -o output 
    
    main.o: main.cpp class1.h class2.h 
        g++ $(CXXFLAGS) -c main.cpp 
    
    class1.o: class1.cpp class1.h 
        g++ $(CXXFLAGS) -c class1.cpp 
    
    class2.o: class2.cpp class2.h 
        g++ $(CXXFLAGS) -c class2.cpp 
    
    .PHONY : clean 
    
    clean: 
        rm *.o output 
    
  • 関連する問題