オブジェクト ファイルを別のディレクトリに取得しようとしましたが、そのディレクトリはソース ディレクトリ ツリーを反映します。これで動作しましたが、行に欠落部分があります$(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 を使用します。
2 番目に、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
。)
そのため、makeは常にそのレシピを実行します。なぜなら、../obj/a
そのファイル名は依存関係としてリストされているため、ファイルを作成する必要があるからです。$(EXE): $(OBJ)