2017-05-08 49 views
1

根据Gnu Make Manual和GNU Makefile - Pattern rule with multiple targets with one dependency ignores all targets but the first,具有多个目标的模式规则表现出不同于正常规则。后者相当于多个规则,每个规则只有一个目标。因为我正在设计一个像make这样的工具,我想知道这种不同行为背后的基本原理,为什么这两种规则都不会使用相同的逻辑呢?GNU Makefile - 为什么具有多个目标的模式规则的行为与正常规则有所不同?

编辑:

例如,我有一个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 

但​​给我:

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

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

回答

1

想象一下,你有以下几种:

%.o: %.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

%.o: %.xx 
    $(XX) [email protected] $< 

第一条规则告诉make如何在.c文件存在构筑.o文件。下一个规则告诉它如何在.xx文件存在的情况下建立一个.o文件。因为有多种方式来生成.o文件,make会尝试找到一个匹配的规则(其中依赖关系都被考虑在内的规则)。

现在考虑:

foo.o : foo.dep 

foo.o : foo.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

在这种情况下,foo.o的是特定目标,你想使运行特定规则。假定makefile的作者提前知道它来自哪里,因此作者可以编写正确的规则。请注意,在这种情况下,存在额外的依赖关系foo.o : foo.dep。这告诉make,如果foo.d过期了,它应该重建foo.o.这种事情对于模式规则来说是没有意义的,在这种模式下,可以有多个规则生成同一个文件(因为那么,额外的依赖关系适用于哪个规则?)。不知道这是否澄清事情。

顺便说一句 - 为什么要重新发明轮子 - 为什么你会想要设计一个工具就像 make,而不仅仅是使用make?

+0

我需要在日常工作中做很多数据处理,这样的任务经常涉及各种脚本语言中的许多代码片段,例如python,ruby,R等等。如果有像make这样的工具可以粘合所有代码片段都放到一个文件中并自动解析依赖关系。 GNU Make主要用于C/C++项目,对于数据处理来说太复杂了,我发现[Drake](https://github.com/Factual/drake)非常适合我的情况。然而,Drake是用Clojure编写的,即使有滴漏,启动时间也非常缓慢,而且由于我对Clojure知之甚少,所以很难延长。 –