Makefile 编译未更改的文件

Ema*_*erg 3 make g++

努力在另一个目录中获取目标文件,但该目录将反映源目录树。让它工作,但行中有一个缺失的部分$(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)
Run Code Online (Sandbox Code Playgroud)

编辑

这按预期工作:不重新编译。此外,没有来回复杂的后缀,更容易阅读。请参阅下面的答案和评论。

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)
Run Code Online (Sandbox Code Playgroud)

dan*_*ann 5

有几个问题:

首先,您的 OBJ 变量不引用构建的文件列表。例如,当您有源文件 src/a.cpp 和 src/b.cpp 时,OBJ 将包含 obj/a 和 obj/b。所以使用 OBJ_O 而不是 OBJ。

其次,您构建 OBJ 文件的目标不会提供 .cpp 和 .o 文件之间的依赖关系。以这种方式编写用于创建 .o 文件的规则是一个问题,因为您无法在该行中提供依赖项信息。我会完全重写创建 .o 文件的规则:

../obj/%.o: ../src/%.cpp
    $(CC) $(CFLAGS) $(INCL) -o "$@" "$<"
Run Code Online (Sandbox Code Playgroud)

这会分别构建每个 .o 文件,每个 .o 文件依赖于相应的 .cpp 文件。

这是../obj/**.o从匹配的每个文件创建文件的规则../src/**.cpp