我一直在编写一个执行依赖项生成的Makefile,我发现自己不得不复制规则,因为(遗留)代码库包含.cpp
和.cc
文件的混合。看起来有点不雅观。无论如何要指定目标的先决条件可以是.cpp
还是.cc
个文件?
所以而不是:
%.d : %.cpp
$(CPP) -MM $(CPPFLAGS) $<
%.d : %.cc
$(CPP) -MM $(CPPFLAGS) $<
创建没有重复的内容,如:
%.d : %.(cpp | cc)
$(CPP) -MM $(CPPFLAGS) $<
或者这种强制冗余只是GNU Make设计的一个不幸因素吗?
答案 0 :(得分:3)
第一个选项,使用变量定义规则体一次,并根据需要重复使用它:
DEPGEN=$(CPP) -MM $(CPPFLAGS) $<
%.d: %.cpp ; $(DEPGEN)
%.d: %.cc ; $(DEPGEN)
第二个选项,使用$(eval)
动态生成规则:
$(foreach src,cpp cc,$(eval %.d: %.$(src) ; $$(CPP) -MM $$(CPPFLAGS) $$<))
答案 1 :(得分:1)
这应该有效:
%.d :: %.cpp
$(CPP) -MM $(CPPFLAGS) $<
%.d :: %.cc
$(CPP) -MM $(CPPFLAGS) $<
另一个想法:
%.d : %.c
$(CPP) -MM $(CPPFLAGS) $<
%.c : %.cpp
ln $< $@ # or cp -p
另一个想法是让GNU make生成两个模式规则。 有两种方法可以做到这一点:
%-cc.mk
语句include
或类似文件)
$(eval)
和$(call)
函数生成并评估它们与C / Unix开发工具链中的大多数其他内容一样,这些技术本质上是一种预处理形式,使得它们易于理解且价格难以使用(大量的双重或三重逃逸,很难保持跟踪什么是扩展的时候;调试可能是一种皇家的痛苦,至少在我的经验中。)
因此,请将它们保留用于更复杂的用例(Stack Overflow列出了一些用例)。