min*_*mic 1 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)
Run Code Online (Sandbox Code Playgroud)
一切正常,除了一个小而烦人的细节:如果我修改一个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)
Run Code Online (Sandbox Code Playgroud)
但结果不是我想要的:如果我修改单个头文件和do make,它告诉我目标是最新的,而我希望它被重新编译.
假设你有foo.cpp,其中包含以下行:
#include "bar.h"
Run Code Online (Sandbox Code Playgroud)
您的通用规则:
%.o: %.cpp
$(CC) $(CFLAGS) -c $^
Run Code Online (Sandbox Code Playgroud)
不会重建foo.o时bar.h已被修改(与foo.o被调用).如果你有一个额外的规则,它会工作foo.o:
%.o: %.cpp
$(CC) $(CFLAGS) -c $< # note the change of automatic variable
foo.o: bar.h
Run Code Online (Sandbox Code Playgroud)
手工编写这样的规则会很痛苦,但是g ++会为你做到:
%.o: %.cpp
$(CC) $(CFLAGS) -c -MMD $<
Run Code Online (Sandbox Code Playgroud)
此命令将生成包含以下行的文件foo.d(作为构建的副作用foo.o):
foo.o: bar.h
Run Code Online (Sandbox Code Playgroud)
你有什么好处,把这一行放在一个单独的文件中?您可以使用一行(在makefile的末尾)将其拉入makefile中,如下所示:
-include *.d
Run Code Online (Sandbox Code Playgroud)
(如果这种方法看起来非常简单,那是因为很多聪明人都会考虑很多.)