问题描述
在我的项目中,我有一些包含方法的头文件(例如,用于模板类).所有这些头文件都包含在单个文件header.h
中,然后每个cpp文件中都包含.这样,我必须只在一个地方更改代码.还有一些.h
文件,但没有相应的.cpp
文件.
然后我有这个makefile:
In my project I have some header files which contain methods (e.g. for template classes). All these header files are included in a single file header.h
, which is then included in every cpp file. This way, I have to change the code just in one place. There are also some .h
files without a corresponding .cpp
file.
Then I have this 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
目标的原因),否则编辑将无效.
Everything works fine, except for one small but annoying detail: if I modify a cpp file, then I can do make
and everything is updated correctly, but if I modify a header file then I have to remove everything and recompile from scratch (and this is the reason why I have that ugly rebuild
target), otherwise the edit will have no effect.
有没有一种方法可以使情况更好,而无需重新构建整个代码?
Is there a way to make things better without restructuring the entire code?
我尝试了这个Makefile
I tried with this 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)
但是结果不是我想要的:如果我修改一个头文件并执行make
,它告诉我目标是最新的,而我希望重新编译它.
but the result is not what I want: if I modify a single header file and the do make
, it tells me that the target is up to date, while I would like it to be recompiled.
推荐答案
假设您有foo.cpp
,其中包含以下行:
Suppose you have foo.cpp
, which contains the line:
#include "bar.h"
您的通用规则:
%.o: %.cpp
$(CC) $(CFLAGS) -c $^
修改bar.h
(并要求使用foo.o
)时,
不会重建foo.o
.如果您对foo.o
有一个附加规则,它将起作用:
will not rebuild foo.o
when bar.h
has been modified (and foo.o
is called for). It would work if you had an additional rule for foo.o
:
%.o: %.cpp
$(CC) $(CFLAGS) -c $< # note the change of automatic variable
foo.o: bar.h
手工编写这样的规则会很痛苦,但是g ++会帮您做到这一点:
Writing such rules by hand would be a pain, but g++ will do it for you:
%.o: %.cpp
$(CC) $(CFLAGS) -c -MMD $<
此命令将生成文件foo.d
(作为构建foo.o
的副作用),该文件包含以下行:
This command will produce the file foo.d
(as a side effect of building foo.o
) which contains the line:
foo.o: bar.h
在单独的文件中包含该行对您有什么好处?您可以像下面这样用一行(在makefile的末尾)将其拉入makefile:
What good does it do you, having that line in a separate file? You can pull it into the makefile with a line (at the end of the makefile) like this:
-include *.d
(如果这种方法看起来非常简单,那是因为很多聪明的人投入了很多思想.)
(If this approach seems amazingly simple, that's because a lot of smart people put a lot of thought into it.)
这篇关于Makefile-使用修改后的头文件进行重建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!