【问题标题】:GNU Makefile - Why pattern rule with multiple targets behaves different from normal rule?GNU Makefile - 为什么具有多个目标的模式规则的行为与正常规则不同?
【发布时间】:2017-05-08 11:11:53
【问题描述】:

根据 Gnu Make Manual 和GNU Makefile - Pattern rule with multiple targets with one dependency ignores all targets but the first,具有多个目标的模式规则的行为与正常规则不同。后者相当于多条规则,每条规则只有一个目标。

因为我正在设计一个像make这样的工具,我想知道这种不同行为背后的基本原理,为什么两种规则不使用相同的逻辑?

编辑:

例如,我有一个 Makefile:

%.md %.ps: %.tex
    echo "rule 1"

doc1.tar.gz: doc1.md doc1.ps
    echo "rule 2"

doc2.md doc2.ps: doc2.tex
    echo "rule 3"

doc2.tar.gz: doc2.md doc2.ps
    echo "rule 4"

make doc1.tar.gz 给我:

echo "rule 1"
rule 1
echo "rule 2"
rule 2

但是doc2.tar.gz 给了我:

echo "rule 3"
rule 3
echo "rule 3"
rule 3
echo "rule 4"
rule 4

我的问题是:为什么规则 1 不能像规则 3 一样运行两次?如果这样的模式规则运行多次会有什么问题?

【问题讨论】:

    标签: makefile


    【解决方案1】:

    想象一下你有以下几点:

    %.o: %.c
         $(CC) $(CFLAGS) -c $< -o $@
    
    %.o: %.xx
         $(XX) $@ $<
    

    第一条规则告诉 make 如果存在 .c 文件,如何构建 .o 文件。下一条规则告诉它如果存在 .xx 文件,如何构建 .o 文件。因为有多种方法可以生成 .o 文件,所以 make 会尝试找到一个匹配的规则(一个包含所有依赖项的规则)。

    现在考虑:

    foo.o : foo.dep
    
    foo.o : foo.c
         $(CC) $(CFLAGS) -c $< -o $@
    

    在这种情况下, foo.o 是一个 specific 目标,您希望 make 运行一个 specific 规则。假定 makefile 的作者提前知道它的来源,因此作者可以编写正确的规则。请注意,在这种情况下,有一个额外的依赖项foo.o : foo.dep。这告诉 make,如果 foo.d 过期,它应该重建 foo.o。这种事情对模式规则没有意义,您可以让多个规则生成同一个文件(因为那样的话,额外的依赖项适用于哪些规则?)。不确定这是否能说明问题。

    顺便说一句——为什么要重新发明轮子——为什么要设计一个类似 make 的工具,而不仅仅是使用 make?

    【讨论】:

    • 我在日常工作中需要做大量的数据处理,这样的任务经常会涉及到python、ruby、R等各种脚本语言的很多sn-ps代码,如果有就好了像 make 这样的工具可以将所有代码 sn-ps 粘合到一个文件中并原子地解决依赖关系。 GNU Make 主要用于 C/C++ 项目,对于数据处理来说过于复杂,我发现 Drake 非常适合我的情况。不过 Drake 是用 Clojure 写的,即使有点滴启动时间也很慢,而且由于我对 Clojure 知之甚少,所以很难扩展。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多