我正在尝试制作一个自包含的Makefile。 我的Makefile有如下规则:
benchmark:
(something that depends on variable CXX)
该规则代表单个编译器的单一基准。我想对几个编译器进行基准测试。
所以我想要完成的是以下内容,而不是从绘图规则(伪语法)中递归调用$(MAKE)
:
plot: benchmark CXX=clang++ benchmark CXX=g++
(generate a plot)
即,我希望这个目标依赖于先决条件基准+一个标志,并将它们视为两个不同的先决条件,即使它们是相同的规则。
答案 0 :(得分:1)
假设GNU Make,我认为您正在寻找的逻辑可以用这种方式表达:
CXXES := clang++ g++
benchmark: $(CXXES:%=benchmark-%)
然后有一条规则来生成基准:
benchmark-%:
# generate a plot using $(CXX), which will be equal to $@
或多个,如果您的绘图生成规则是编译器特定的:
benchmark-clang++: CXX = clang++
# generate a plot using $(CXX)
(...)
benchmark-g++: CXX = g++
# generate a plot using $(CXX)
(...)
最好识别文件名取决于$(CXX)
的输出文件(图?)并将其用作中间目标。
答案 1 :(得分:1)
根据reinierpost的建议,您可以为每个编译器定义一个伪目标。伪目标是没有与之关联的真实文件生成的目标。
但是由于make对真实文件目标非常满意(目标被认为是最新的或不是基于他们的最后修改日期),您也可以使用您的绘图结果作为目标。并且,如同建议的那样,您可以将所有这些包装在foreach
- eval
- call
结构中以分解您的代码。类似的东西:
COMPILERS = clang++ g++
define PLOT_compiler
plotfile-$(1): CXX = $(1)
plotfiles += plotfile-$(1)
endef
$(foreach compiler,$(COMPILERS),$(eval $(call PLOT_compiler,$(compiler))))
all: $(plotfiles)
plotfile-%:
<generate plot file using the CXX variable>
foreach
- eval
- call
构造为每个编译器实例化一组make语句,由PLOT_compiler
变量定义。
如果您更喜欢在名为的单个文件中收集所有结果,我们可以使用plots.txt
代替:
COMPILERS = clang++ g++
define PLOT_compiler
plotfile-$(1): CXX = $(1)
plotfiles += plotfile-$(1)
endef
$(foreach compiler,$(COMPILERS),$(eval $(call PLOT_compiler,$(compiler))))
plots.txt: $(plotfiles)
cat $(plotfiles) > $@
plotfile-%:
<generate plot file using the CXX variable>
clean:
rm -f $(plotfiles)
ultraclean:
rm -f $(plotfiles) plots.txt
clean
和ultraclean
目标将帮助您保持工作区清洁。您可以通过<generate plot file using the CXX variable>
替换echo $(CXX) > $@
食谱,然后:
make
make clean
cat plots.txt