2016-04-12 14 views
2

一般的なmakeファイルを作成しようとしています。追加するファイルの数とプロジェクトツリーに入れるファイルの数とは関係なくプロジェクトをコンパイルできます。パターンマッチングを使用すると "make"が失敗する

私のステップバイステップアプローチでは、私はこのメイクファイルにうまくいきます。

CC=g++ 
OBJECTS=main.o board.o 
VPATH=src:\ 
      src/board:\ 
      include/board:\ 
      build:\ 
      bin 

boardG : main.o board.o 
    $(CC) -o bin/boardG build/main.o build/board.o 

main.o : main.cpp board.hpp 
    $(CC) -c -I include $< -o build/[email protected] 

board.o : board.cpp board.hpp 
    $(CC) -c -I include $< -o build/[email protected] 

このバージョンでは問題なく機能します。以下の出力を参照してください。

[email protected]:~/code/projects/boardG$ make 
g++ -c -I include src/main.cpp -o build/main.o 
g++ -c -I include src/board/board.cpp -o build/board.o 
g++ -o bin/boardG build/main.o build/board.o 

ここでの問題は、.cppファイルごとに1つのルールを作成する必要があることです。それはまさに私が避けようとしているものです。したがって、私はこのようなマッチングパターンを使用して、上記のバージョンを適応させることを試みた。その中に

[email protected]:~/code/projects/boardG$ make 
g++ -c -o main.o src/main.cpp 
src/main.cpp:2:27: fatal error: board/board.hpp: No such file or directory 
compilation terminated. 
<builtin>: recipe for target 'main.o' failed 
make: *** [main.o] Error 1 

私のプロジェクトはfollwing構造を有している/ファイル:

CC=g++ 
OBJECTS=main.o board.o 
VPATH=src:\ 
      src/board:\ 
      include/board:\ 
      build:\ 
      bin 

boardG : main.o board.o 
    $(CC) -o bin/boardG build/main.o build/board.o 

%.o : %.cpp %.hpp 
    $(CC) -c -I include $< -o build/[email protected] 

私は今、私はfollwing出力を得るmakeを実行し

./bin/ 
./build/ 
./include/board/board.hpp 
./src/main.cpp 
./src/board/board.cpp 
./makefile 

パターンマッチングを使用するときにmakeがコマンドを変更するのはなぜでしょうか?あるいは、おそらくもっと正確には、私は何が間違っていて、失敗するのでしょうか?

+2

これはおそらく組み込みの '%.o:%.cpp'ルールを使用しています。ターゲットに一致する'%.hpp'ファイルが見つからないためです。これらのルール( '-r')を無効にすると、違う方法で失敗するはずです。 'make -d'を実行することは、makeがあなたの目標を見つけたときに何をしようとしているのかを示す点で有用かもしれません。 (私はVPATHがどのように単一のターゲットで複数のパターンの前提条件を持っているかわかりません) –

+0

ビルドすることを約束したファイル以外のファイルをビルドするいくつかのルールがあります(例えば 'board.o '')、そしてこのフィクションと一緒に演じる別のルール、ビルドされていないファイルが必要であると主張し、次にそれらのファイルを使用することです。当然これを一般化しようとするとすぐに壊れます。 – Beta

答えて

0

オブジェクトファイルについては、VPATHを使用しないでください。実際には、makeは実際には%.oの組み込みルールを使用していて、ルールをまったく使用していないということが起こります。

ディレクトリにすべてのオブジェクトを接頭辞場合、これは動作するはずです:

CC=g++ 
OBJDIR = build 
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/board.o 
VPATH = src:\ 
      src/board:\ 
      include/board:\ 

bin/boardG : $(OBJECTS) 
    $(CC) -o [email protected] $^ 

$(OBJDIR)/%.o : %.cpp %.hpp 
    $(CC) -c -I include $< -o [email protected] 

ここでは、多かれ少なかれ、正確にあなたがに実行した問題を説明helpful resource、です。

+0

VPATHを使って*オブジェクトファイル*を探すのに何も問題はないことに注意してください。問題は、VPATHがまだ存在しないファイルを見つけるのに役立たないということです。 – Beta

+0

残念ながら、私は残念ながら新しいエラーに遭遇しています。 "... 'bin/boardG' ... 'が必要とするターゲット' build/main.o 'を作るルールはありません。とにかく、あなたが提供したリソースは非常に面白いです。主に[Paul's Rules of Makefiles](http://make.mad-scientist.net/papers/rules-of-makefiles/)は大いに役立ちます。 [3番目の](http://make.mad-scientist.net/papers/rules-of-makefiles/#rule3)によると、ターゲットはカレントディレクトリにビルドされているはずなので、私は人生を不必要に複雑にしていますそうみたいです。私はそのルールを尊重し、その結果が何かを見て一緒に何かを入れます。 – Pat

+0

さて、私は今すぐ動作するようになった。依存関係の%はターゲットからのステムに一致します。したがって、main.oをコンパイルしている間、makeは依存関係がmain.hppであり、実際にはboard.hppであると仮定します。 main.hppが存在しないため、結果として失敗しました。依存関係を%.hppからboard.hppに変更しました。現在はうまくいきます。私は現在、依存関係に対処するためのよりきれいな方法と、私がPaulのルール#3を壊さないようにする方法が必要ですが、それは手元の質問とは異なるテーマです。 @バリー、私のフォルダ/ VPATHの問題への答えを提供してくれてありがとう。 – Pat

関連する問題