使目标取决于具有不同标志

时间:2015-08-22 13:05:04

标签: makefile gnu-make gnu

我正在尝试制作一个自包含的Makefile。 我的Makefile有如下规则:

benchmark:
      (something that depends on variable CXX)

该规则代表单个编译器的单一基准。我想对几个编译器进行基准测试。

所以我想要完成的是以下内容,而不是从绘图规则(伪语法)中递归调用$(MAKE)

plot: benchmark CXX=clang++ benchmark CXX=g++
    (generate a plot)

即,我希望这个目标依赖于先决条件基准+一个标志,并将它们视为两个不同的先决条件,即使它们是相同的规则。

2 个答案:

答案 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

cleanultraclean目标将帮助您保持工作区清洁。您可以通过<generate plot file using the CXX variable>替换echo $(CXX) > $@食谱,然后:

轻松测试所有这些
make
make clean
cat plots.txt