ソースファイルとオブジェクトファイルを分離してMakefileを書き込もうとしていますが、これを実現するための適切な方法がわからないようです。私には2つの方法がありますが、誰かがこれを行うための「正しい」方法を指摘できることを望んでいます。
私のプロジェクトは、これらと同じレベルのMakefileを含むフォルダーにsrc
分割されています。obj
最初の方法では、ワイルドカード関数を使用してソースファイルを検索し、src
テキスト置換を使用して対応するオブジェクトファイルを決定します。
SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:.cpp=.o)
prog: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(patsubst src/,obj/,$(OBJ))
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)
これは機能しているようですが、実行するたびにmake prog
すべてのオブジェクトファイルが再コンパイルされます。OBJ
変数はすべてのオブジェクトの前にある必要があります。src/
そうしないと、「ターゲットを作成するルールがありません」というメッセージが表示されます。prog
プラス面として、ターゲットのpatsubstを使用して、オブジェクトファイルを簡単に指定できます。
2番目の方法も同様ですが、OBJ
変数にvpathとテキスト置換を使用します。
vpath = %.cpp src
vpath = %.o obj
SRC = $(wildcard src/*.cpp)
OBJ = $(subst src/,,$(SRC:.cpp=.o))
POBJ = $(patsubst src/,obj/$(SRC:.cpp=.o))
prog: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(POBJ)
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)
POJB
これにより、オブジェクトファイルの再コンパイルは不要になりますが、ターゲットに別の変数を追加する必要がありますprog
(basedirがないとオブジェクトファイルだけでpatsubstを実行できないため)。
どちらの方法も機能し、それぞれに利点がありますが、どちらが「正しい」アプローチであり、どちらでもない場合、このタイプの建物を実現するための適切な方法は何ですか。