我目前有以下Makefile
test: main.o car.o student.o house.o
$(CXX) $(CXXFLAGS) -o test main.o car.o student.o house.o
objcopy --only-keep-debug test test.debug
main.o: student.h house.h main.cpp
$(CXX) $(CXXFLAGS) -c main.cpp
car.o: car.h
student.o: student.h car.h
house.o: house.h
我的问题是,我可以将文件缩短一些吗?
test: *.o
$(CXX) $(CXXFLAGS) -o test *.o
objcopy --only-keep-debug test test.debug
目标依赖项将如何工作?我之所以要追求这样的原因是因为我不想每次添加新的头文件或cpp文件时都向Makefile中添加内容?
这可以通过自动重新计算依赖关系来完成您想要的事情:
CPPFLAGS += -MMD
SOURCES = $(wildcard *.C *.c *.cpp *.cxx *.c++)
OBJECTS = $(addsuffix .o,$(basename $(SOURCES)))
.PHONY: all
all: appname appname.debug
appname.debug: appname
objcopy --only-keep-debug $< $@
appname: $(OBJECTS)
include *.d
请参阅https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/Preprocessor-Options.html#Preprocessor-Options以获取-MMD
-选项,该选项在编译时会将相关性提取到.d
-文件
我计算了所有可能的源文件,并从中计算了所有目标文件,因为*.o
仅匹配已存在的文件。
您绝对可以在makefile中使用test: *.o
。
您可能不想。新创建的.o
文件将永远不会包含.c
文件,因为它们将不存在。
尽管可以通过使用$^
automatic variable来列出配方正文中的每个文件。
这是good的主意,“每次添加cpp文件时都将内容添加到Makefile中”,您应该说服自己。
[第一个原因是,如果您每次更改源列表时都更改Makefile,并且您将目标依赖于Makefile,则目标将在您更改源列表时自动重新编译,这就是Make的方式。旨在工作。不要打架。
第二个原因是,您想在某处显式声明您的来源,因此您可以向自己和他人阐明意图。我的实践表明,这使代码更易于维护。
第三个原因是,因此您可以添加其他具有相同扩展名的文件(可能是临时文件),这些文件不是源文件。
考虑到这一点,我认为这是重写Makefile的最佳方法。请注意,我在这里没有进行任何自动依赖项生成。如果这样做,则不必像其他人指出的那样,自动生成.o
文件对.h
文件的各种依赖关系。
SRCS := main.cpp car.cpp student.cpp house.cpp
OBJS := $(SRCS:cpp=o)
.PHONY: all
all: test test.debug
test: $(OBJS) Makefile
$(CXX) $(CXXFLAGS) -o $@ $(OBJS)
%.debug: % Makefile
objcopy --only-keep-debug $< $@
$(OBJS): %o: %cpp Makefile
$(CXX) $(CXXFLAGS) -c $<
main.o: student.h house.h
car.o: car.h
student.o: student.h car.h
house.o: house.h