有没有办法直接 make/gmake 对条件依赖采取行动?
我有这个规则:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CPPC) -c $(FLAGS_DEV) $< -o $@
一般情况下,每个 .cpp 文件都有一个对应的 .h 文件;但是也有一些例外。有没有办法用gmake实现“如果它存在就依赖它”?如果做不到这一点,这种设置是否有最佳实践?
提前致谢; 干杯!
更新:我正在使用 GCC
有没有办法直接 make/gmake 对条件依赖采取行动?
我有这个规则:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CPPC) -c $(FLAGS_DEV) $< -o $@
一般情况下,每个 .cpp 文件都有一个对应的 .h 文件;但是也有一些例外。有没有办法用gmake实现“如果它存在就依赖它”?如果做不到这一点,这种设置是否有最佳实践?
提前致谢; 干杯!
更新:我正在使用 GCC
您可以通过在您的 makefile 中明智地使用模式规则来实现这一点,这要归功于 gmake 模式规则匹配的两个特性。首先,gmake 尝试按照声明的顺序匹配模式;其次,当且仅当模式中的所有先决条件都可以满足时,模式才匹配(它们已经作为文件存在,或者有一个规则来制作它们)。所以,如果你这样写你的makefile:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
$(CPPC) -c $(FLAGS_DEV) $< -o $@
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CPPC) -c $(FLAGS_DEV) $< -o $@
gmake 将匹配具有相应 .h 文件的那些文件的第一个模式,而那些没有的则匹配第二个模式。当然,最新的检查也会像预期的那样运行(例如,如果“foo.h”存在并且更新,“foo.o”将被认为是过时的)。
您可能希望使用另一个变量来消除这两个规则之间的冗余;例如:
COMPILE=$(CPPC) -c $(FLAGS_DEV) $< -o $@
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
$(COMPILE)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(COMPILE)
更好的方法是使用 gcc -MM 实际确定 cpp 文件的依赖关系并将它们包含在 makefile 中。
SRCS = main.cpp other.cpp
DEPS = $(SRCS:%.cpp=$(DEP_DIR)/%.P)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CPPC) -c $(FLAGS_DEV) $< -o $@
$(DEP_DIR)/%.P: $(SRC_DIR)/%.cpp
$(CPPC) -MM $(FLAGS_DEV) -MT $(OBJ_DIR)/$*.o -MP -MF $@ $<
-include $(DEPS)
一个更强大的解决方案是让 gcc 为您生成依赖项。如果您制定规则来生成(例如).d
包含已生成依赖项的文件,那么您不必担心.h
任何给定.cpp
文件是否存在文件,并且您会自动为每个.cpp
文件获取.h
它所依赖的任何文件的正确依赖项。
例如
DEPFILES=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.d,$(wildcard $(SRC_DIR)/*.cpp))
$(OBJ_DIR)/%.d: $(SRC_DIR)/%.cpp
g++ -MF $@ -MM -MT $@ -MT $(basename $@).o %<
include $(DEPFILES)
请注意,我使用该选项同时创建了 make 规则.d
的目标和目标,以便在对任何当前依赖项进行任何更改后正确地重新创建依赖项。.o
-MT