如果我只更改一个文件,为什么makefile会重新编译整个文件集?

时间:2013-03-31 22:53:05

标签: makefile

这是我的makefile ...为什么它重新编译所有源代码,即使只有一个更改?

CC = g++
CFLAGS = -w -g -c
LIBS = -lm

EXEC = DFMS_PDS_L2_to_L3

.PHONY : clean tgz wdtgz

HOMEDIR = ../
BIN = bin
SRC = src
OBJ = obj

SRCFILES := $(wildcard $(SRC)/*.cc)
OBJFILES := $(patsubst %.cc, $(OBJ)/%.o, $(notdir $(SRCFILES)))
OBJS := $(patsubst %.cc, %.o, $(notdir $(SRCFILES)))

# Executable Targets
all:    $(EXEC)

$(EXEC) : $(OBJS)
$(CC) $(LIBS) $(OBJFILES) -o $(BIN)/$(EXEC)

# Dependencies
%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $(OBJ)/$@

# Miscellaneous Targets 
clean:
rm -rf $(BIN)/$(EXEC) obj/*.o *~

tgz:
tar cvzf $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild --exclude=data
cp $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild.tgz.allow

wdtgz:
tar cvzf $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild
cp $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild.tgz.allow

我使用gnu make

在Linux 3.0上运行

是否在$(EXEC)定义中?

1 个答案:

答案 0 :(得分:3)

我的猜测是,即使 none 发生变化,这也会重新编译所有来源。

看看这两条规则:

$(EXEC) : $(OBJS)
$(CC) $(LIBS) $(OBJFILES) -o $(BIN)/$(EXEC)

%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $(OBJ)/$@

假设foo.cc是唯一的源文件。第一条规则说目标取决于foo.o,但实际上是从obj/foo.o构建的。可以调用第二个来构建foo.o(第一个规则要求),但它实际构建obj/foo.o。因此,第一次运行Make它将正确构建可执行文件(和obj/foo.o)。但每次以后,Make都会看到foo.o不存在,并尝试构建它并重建可执行文件。

解决方案是重写规则,以便他们构建 - 并依赖 - 他们声称的内容:

all: $(BIN)/$(EXEC)

$(BIN)/$(EXEC) : $(OBJFILES)
$(CC) $(LIBS) $^ -o $@

$(OBJ)/%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $@