【问题标题】:How do I ensure my makefile detects changes in my header and cpp files?如何确保我的 makefile 检测到我的头文件和 cpp 文件中的更改?
【发布时间】:2014-06-20 12:37:13
【问题描述】:

目前,每当我执行make 时,我的makefile 都会告诉我

make: `some/obj/file.o' 是最新的。

无论我是否编辑了生成该目标文件所涉及的任何文件。如何让它检测更改?这是一个重现问题的简单生成文件:

SHELL := /bin/bash
src := src
sources := $(shell find $(srcDir) -name "*.cpp")                                
objects := $(sources:%.cpp=%.o)                                                 

-include $(sources:%.cpp=%.d)                                                   

all: prog                                                                       

prog:   $(objects)                                                              
    g++ $(objects) -o /a.out                                                    

%.o: %.cpp                                                                      
    $(CXX) $(CXXFLAGS) -MMD -MP -c $< -I $(srcDir) -o $@                        

clean:                                                                          
    find $(srcDir) -type f -iname "*.o" -delete                                 
    find $(srcDir) -type f -iname "*.d" -delete 

目前我必须每次运行make clean 才能重新编译,这显然不理想!

编辑:这是我根据 Chnossos 的回答所做的尝试:

EXE := a.out                                                                    
SRCDIR := src                                                                   
SRC := $(shell find $(srcDir) -name "*.cpp")                                    
DIR := .obj                                                                     
OBJ := $(SRC:%.cpp=$(DIR)/%.o)                                                  
DEP := $(OBJ:.o=.d)                                                             

CXXFLAGS += -std=c++11                                                          
CXXFLAGS += -I /home/arman/lib/eigen-eigen-6b38706d90a9                  
CXXFLAGS += -I /home/arman/lib/boost_1_55_0                              
CXXFLAGS += -I /home/arman/lib/lodepng/                                  
CXXFLAGS += -L /home/arman/lib/boost_1_55_0/stage/lib                    
CPPFLAGS += -MMD -MP                                                            

.PHONY: all clean                                                               

-include $(DEP)                                                                 

all: $(EXE)                                                                     

$(EXE):   $(OBJ)                                                                
        $(CXX) $(OBJ) -o $@                                                     

$(DIR)/%.o: %.cpp                                                               
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $< -I $(SRCDIR)                 

clean:                                                                          
        $(RM) -f $(DIR)                                                         

我现在收到以下错误:

src/core/file1.cpp:839:1: 致命错误:打开依赖文件 .obj/./src/core/file1.d: 没有这样的文件或目录

请注意,我有以下目录结构:

/prog/makefile -> 生成文件 /prog/dir1/ -> 一些 cpp/hpp 文件 /prog/dir2/ -> 更多 cpp/hpp 文件 /prog/ -> 这里也有一些 cpp/hpp 文件

我有很多文件夹(不仅仅是dir1 和dir2),所以我不想每次都指定它们。

【问题讨论】:

    标签: c++ makefile


    【解决方案1】:
    SRC         := $(wildcard *.cpp)
    OBJ         := $(SRC:.cpp=.o)
    DEP         := $(OBJ:.o=.d)
    
    CPPFLAGS    += -MMD -MP -I.
    
    .PHONY: all clean
    
    all: prog
    
    prog:   $(OBJ)
        $(CXX) $(LDFLAGS) $^ $(LDLIBS)
    
    -include $(DEP)
    
    clean:
        $(RM) $(OBJ) $(DEP)
    

    您还可以通过一些努力将您的 .o 和 .d 文件编译到这样的隐藏文件夹中:

    EXE         := a.out
    SRC         := $(wildcard *.cpp)
    DIR         := .obj
    OBJ         := $(SRC:%.cpp=$(DIR)/%.o)
    DEP         := $(OBJ:.o=.d)
    
    CPPFLAGS    += -MMD -MP -I.
    
    .PHONY: all clean
    
    all: $(EXE)
    
    $(EXE):   $(OBJ)
        $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
    
    $(DIR)/%.o: %.cpp | $(DIR)
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
    
    $(DIR):
        @mkdir $@
    
    -include $(DEP)
    
    clean:
        $(RM) -r $(DIR)
    

    编辑:这是我对您的编辑的尝试:

    一些快速说明,$(LDLIBS) 用于您的-l 标志,而$(LDFLAGS) 用于-L 标志。

    SRCDIR := src
    OBJDIR := .obj
    
    EXE := a.out
    SRC := $(shell find $(SRCDIR) -name "*.cpp")
    OBJ := $(SRC:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
    DEP := $(OBJ:.o=.d)
    
    LDFLAGS += -L /home/arman/lib/boost_1_55_0/stage/lib
    CXXFLAGS += -std=c++11
    CPPFLAGS += -I $(SRCDIR)
    CPPFLAGS += -I /home/arman/lib/eigen-eigen-6b38706d90a9
    CPPFLAGS += -I /home/arman/lib/boost_1_55_0
    CPPFLAGS += -I /home/arman/lib/lodepng/
    CPPFLAGS += -MMD -MP
    
    .PHONY: all clean
    
    all: $(EXE)
    
    $(EXE): $(OBJ)
        $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@    
    
    .SECONDEXPANSION:
    $(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $$(@D)/
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
    
    %/:
        mkdir $@
    
    -include $(DEP)
    
    clean:
        $(RM) -r $(OBJDIR)
    

    如果缺少什么,请告诉我。

    【讨论】:

    • 谢谢 Chnossos,我已经尝试过调整,但遇到了一些麻烦。请看一下我在 OP 末尾发布的示例,并解释了我的文件结构。我需要进行哪些更改才能使其正常工作?
    【解决方案2】:

    -M 系列 gcc 选项(-MM、-MMT)生成您需要的 makefile 片段。一种标准的技术是

    DEPS := $(SOURCES:.c=.d)
    
    .c.d:
        $(CC) -o $< -MM $(CFLAGS)
    
    -include $(DEPS)
    

    【讨论】:

    • 这看起来是个不错的答案,但你能改写一下像我这样的新手吗?我将如何使用我拼凑在一起的现有 makefile 进行这项工作?
    • 他缺少的关键是从 .cpp 文件重新生成 .d 文件的规则——他已经拥有了其余的。另外请将 .c 更改为 .cpp 并将 $(CC) 更改为 $(CXX)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多