为什么这个makefile总是重新编译

Why this makefile is always recompiling?

本文关键字:新编译 编译 makefile 为什么      更新时间:2023-10-16

我已经为我正在做的一个项目做了一个makefile,我的代码总是被重新编译,我不知道为什么…我试过将。phony添加到所有目标,但没有工作。下面是makefile:

TARGET  = csv2sqlite
CXX     = g++
CXXFLAGS    = -std=c++11 -Wall -I $(INCDIR) -fdiagnostics-color=always -D_DEBUG
OBJECTS = csv.o main.o
BINDIR  = bin
OBJDIR  = obj
INCDIR  = inc
SRCDIR  = src
.PHONY:default
default: $(OBJECTS) $(TARGET)
%.o: $(SRCDIR)/%.cpp
    @echo "Compiling dependecies..."
    $(CXX) $(CXXFLAGS) -c  $< -o $(OBJDIR)/$@
    @echo "Done compiling $@"
$(TARGET): $(addprefix $(OBJDIR)/, $(OBJECTS))
    @echo "Linking $@ file..."
    $(CXX) $(CXXFLAGS) $^ -o $(BINDIR)/$@
    @echo "Linking $@ file..."
run:
    bin/$(TARGET)
clean:
    rm -f obj/* bin/$(TARGET)

目录树为:

project
├── inc
│   └── csv.hpp
├── src
│   ├── csv.cpp
│   └── main.cpp
├── obj
│   ├── csv.o
│   └── main.o
├── bin
│   └── csv2sqlite
└── makefile

如果你想看的话,这里是完整的项目。还有,我能做些什么改进呢?

谢谢!

此处:

%.o: $(SRCDIR)/%.cpp
    ...
    $(CXX) $(CXXFLAGS) -c  $< -o $(OBJDIR)/$@
    @echo "Done compiling $@"

不,你不是。你没有构建foo.o,你构建了obj/foo.o,所以下次你让Make构建foo.o时,它会看到foo.o不存在,并试图重建它——用这个规则,它不会做它声称要做的事情。同样:

$(TARGET): $(addprefix $(OBJDIR)/, $(OBJECTS))
    @echo "Linking $@ file..."
    $(CXX) $(CXXFLAGS) $^ -o $(BINDIR)/$@
    @echo "Linking $@ file..."

这不会构建$(TARGET),它会构建$(BINDIR)/$(TARGET),所以Make每次被告知构建$(TARGET)时都会运行此规则。

修复方法很简单:

OBJECTS = $(addprefix $(OBJDIR)/, csv.o main.o)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
    ...
    $(CXX) $(CXXFLAGS) -c  $< -o $@
    @echo "Done compiling $@"
TARGET  = $(BINDIR)/csv2sqlite
$(TARGET): $(OBJECTS)
    @echo "Linking $@ file..."
    $(CXX) $(CXXFLAGS) $^ -o $@
    @echo "Linking $@ file..."