我有这个Makefile:
PROJECT_DIR = $(abspath ..)
BUILDDIR = $(PROJECT_DIR)/build
OBJDIR = $(BUILDDIR)/obj
BINDIR = $(BUILDDIR)/bin
SRCDIR = $(PROJECT_DIR)/src/app
SOURCES := $(wildcard $(SRCDIR)/*.cpp)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
APPNAME=blink
APP=$(BINDIR)/$(APPNAME)
all: $(APP).elf
dirs:
@echo "Project dir: " $(PROJECT_DIR)
mkdir -p $(BUILDDIR)
mkdir -p $(OBJDIR)
mkdir -p $(BINDIR)
# Link
$(APP).elf: $(OBJECTS)
$(CPP) $(CPPFLAGS) -o $@ $^
@echo "Linked "$<" successfully!"
# Compile:
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp dirs
$(CPP) $(CPPFLAGS) -c $< -o $@
@echo "Compiled successfully"
当我运行时:make
每次都重新编译所有文件,而不是仅在源代码更改时才执行此操作。我怀疑是因为build
目录时间戳与${APP}.elf
目标一起更新,但不知道如何解决它。
答案 0 :(得分:2)
dirs
的食谱永远不会成为目标:它永远不会创建文件
叫dirs
。因此这条规则:
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp dirs
总是有一个过时的预处理,dirs
,所以它的配方总是运行。
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp | dirs
将补救无根据的重新编译和重新连接。但dirs
仍然存在
从未通过其配方制作的目标,以便仍然可以运行配方。
要解决这个问题,请执行以下操作:
ODIRS := $(BUILDDIR)/$(OBJDIR) $(BUILDDIR)/$(BINDIR)
...
$(ODIRS):
mkdir -p $@
$(APP).elf: $(OBJECTS) | $(BINDIR)
...
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp | $(OBJDIR)
...
此外,all
是phony target:您应该这样说:
.PHONY: all
all: $(APP).elf
...
...
提供clean
目标是正常的:
.PHONY: all clean
all: $(APP).elf
...
...
clean:
rm -fr $(BUILDDIR)
答案 1 :(得分:1)
问题是1-NeuralNetworksDeeplearning/Assignment/
。
您的$(OBJDIR)/%.o : $(SRCDIR)/%.cpp dirs
文件取决于.o
。 Makefile会将dirs
解释为文件名,并搜索当前目录,然后发现没有名为dirs
的文件,因此规则为:
dirs
将被执行,这意味着您的dirs:
@echo "Project dir: " $(PROJECT_DIR)
...
依赖项已更新,因此本身也需要更新。这就是你
$(OBJDIR)/%.o
将一次又一次地执行。
要进行修复,请从此依赖项中删除$(OBJDIR)/%.o : $(SRCDIR)/%.cpp dirs
$(CPP) $(CPPFLAGS) -c $< -o $@
。它只需要在开始时执行。