Makefile - 使用修改的头文件重建

时间:2016-02-27 22:08:29

标签: c++ makefile header-files

在我的项目中,我有一些包含方法的头文件(例如用于模板类)。所有这些头文件都包含在单个文件header.h中,然后包含在每个cpp文件中。这样,我必须在一个地方更改代码。还有一些.h个文件没有相应的.cpp文件 然后我有这个makefile:

# Makefile

.PHONY: run clean rebuild

CC     = g++
CFLAGS = -Wall -Ofast -std=c++0x -pthread
RM     = rm -f
EXEC   = main

SRC    = $(wildcard *.cpp)
OBJ    = $(SRC:.cpp=.o)

$(EXEC): $(OBJ)
    $(CC) $(CFLAGS) -o $@ $(OBJ)

%.o: %.cpp
    $(CC) $(CFLAGS) -c $^

run: $(EXEC)
    ./$(EXEC)

clean:
    $(RM) $(EXEC) *.o *.gch *~

rebuild: clean $(EXEC)

一切正常,除了一个小而烦人的细节:如果我修改cpp文件,那么我可以做make并且一切都正确更新,但是如果我修改了头文件,那么我必须删除所有内容并从头开始重新编译(这就是为什么我有那个丑陋的rebuild目标),否则编辑将无效。

如果不重组整个代码,有没有办法让事情变得更好?

修改

我试过这个makefile

.PHONY: run clean rebuild

CC     = g++
CFLAGS = -Wall -Ofast -std=c++0x -pthread
RM     = rm -f
EXEC   = main

SRC    = $(wildcard *.cpp)
OBJ    = $(SRC:.cpp=.o)

$(EXEC): $(OBJ)
    $(CC) $(CFLAGS) -o $@ $(OBJ)

%.o: %.cpp headers.h
    $(CC) $(CFLAGS) -c $<

run: $(EXEC)
    ./$(EXEC)

clean:
    $(RM) $(EXEC) *.o *.gch *.d *~

rebuild: clean $(EXEC)

但结果不是我想要的:如果我修改单个头文件和do make,它会告诉我目标是最新的,而我希望它能够重新编译。

2 个答案:

答案 0 :(得分:7)

假设您有foo.cpp,其中包含以下行:

#include "bar.h"

您的通用规则:

%.o: %.cpp
    $(CC) $(CFLAGS) -c $^
foo.o被修改(并且bar.h被调用)时,

不会重建foo.o。如果您有foo.o的其他规则,则可以使用

%.o: %.cpp
    $(CC) $(CFLAGS) -c $<  # note the change of automatic variable

foo.o: bar.h

手工编写这样的规则会很痛苦,但是g ++会为你做这些:

%.o: %.cpp
    $(CC) $(CFLAGS) -c -MMD $<

此命令将生成包含以下行的文件foo.d(作为构建foo.o的副作用):

foo.o: bar.h

你有什么好处,把这一行放在一个单独的文件中?您可以使用一行(在makefile的末尾)将其拉入makefile中,如下所示:

-include *.d

(如果这种方法看起来非常简单,那是因为很多聪明人都会考虑很多。)

答案 1 :(得分:0)

不是Makefile专家,请查看this。使用-MM-MD-MF gcc标志有多种解决方案。得出的最高答案表明如下:

depend: .depend

.depend: $(SRCS)
        rm -f ./.depend
        $(CC) $(CFLAGS) -MM $^ -MF  ./.depend;

include .depend

据我了解,应为您生成正确的依赖项,这似乎是正确的方法。但是,我从未使用它,我会尝试在依赖项中添加头文件(为%.o添加新目标):

%.o: %.cpp %.h header.h
    $(CC) $(CFLAGS) -c $<

请注意,我已将$^更改为$<以便仅获取第一个依赖项(即cpp),并且我附加了header.h以强制重新编译时此更改。最后可能不需要,取决于你在那里做什么,并且它将导致低效的编译,因为更改它将重新编译所有.o文件