ソースディレクトリツリーを反映する他のディレクトリからターゲットファイルを取得しようとします。うまくいきますが、その行に一部が欠落しているか$(OBJ):
(正しいですか)、ソースコードが変更されているかどうかにかかわらず再コンパイルされます。見学する。
SRC_PATH=../src/
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lSDL -lSDL_gfx
INCL=-I $(SRC_PATH)include/
EXE=run
SRC=$(wildcard $(SRC_PATH)*.cpp $(SRC_PATH)game/*.cpp $(SRC_PATH)player/*.cpp)
OBJ=$(subst ../src, ../obj, $(SRC:.cpp=))
OBJ_O=$(addsuffix .o, $(OBJ))
all: $(SRC) $(EXE)
$(EXE): $(OBJ)
$(CC) $(LDFLAGS) $(OBJ_O) -o $@
$(OBJ):
$(CC) $(CFLAGS) $(INCL) -o $(addsuffix .o, $@) $(subst ../obj, ../src, $@).cpp
clean:
rm -rf run $(OBJ_O)
編集する
これは期待どおりに機能します。再コンパイルしません。また、複雑な前後のサフィックスがないため、読みやすくなります。下記の回答とコメントをご覧ください。
SRC_PATH=../src/
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lSDL -lSDL_gfx
INCL=-I $(SRC_PATH)include/
EXE=run
SRC=$(wildcard $(SRC_PATH)*.cpp $(SRC_PATH)game/*.cpp $(SRC_PATH)player/*.cpp)
OBJ=$(subst ../src, ../obj, $(SRC:.cpp=.o))
all: $(SRC) $(EXE)
$(EXE): $(OBJ)
$(CC) $(LDFLAGS) $(OBJ) -o $@
../obj/%.o: ../src/%.cpp
$(CC) $(CFLAGS) $(INCL) -o $@ $<
clean:
rm -rf run $(OBJ)
答え1
いくつかの質問があります:
まず、OBJ変数はビルドされたファイルのリストを参照しません。たとえば、ソースファイルsrc / a.cppとsrc / b.cppがある場合、OBJにはobj / aとobj / bが含まれます。したがって、OBJの代わりにOBJ_Oを使用してください。
第二に、OBJファイルを構築するターゲットは、.cppファイルと.oファイル間の依存関係を提供しません。 .oファイルを生成するための規則をこのように作成することは、その行に依存関係情報を提供できないために問題になります。 .oファイル生成ルールを完全に書き直しましょう。
../obj/%.o: ../src/%.cpp
$(CC) $(CFLAGS) $(INCL) -o "$@" "$<"
これは各 .o ファイルを個別に構築し、各 .o ファイルは対応する .cpp ファイルに依存します。
../obj/**.o
これは、一致する各ファイルからファイルを生成するルールです../src/**.cpp
。
答え2
より明確に説明するには:
最大の問題はラインです。$(OBJ):
問題は、../src/a.cpp
変数OBJ
にソースファイルが含まれてい../obj/a
て、ルールが$(OBJ):
「ファイルを作成するには次のレシピを使用してください../obj/a
」という意味です。しかし、レシピはそうではありません! (代わりにファイルを生成します../obj/a.o
。)
../obj/a
そのファイル名が依存関係としてリストされているため、緊急にそのファイルを生成する必要があるため、makeが常にそのレシピを実行する理由です。$(EXE): $(OBJ)