Makefile は変更されていないファイルをコンパイルします。

Makefile は変更されていないファイルをコンパイルします。

ソースディレクトリツリーを反映する他のディレクトリからターゲットファイルを取得しようとします。うまくいきますが、その行に一部が欠落しているか$(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)

関連情報