我有一个生成两个版本文件的生成器程序,比如ver.h
和ver.cpp
。我的最终构建目标取决于这两个文件,并且构建两者的规则是一个程序。如果我这样做了:
build : ver.h ver.cpp
ver.h ver.cpp :
./gen/version/program
然后并行构建可以运行program
两次,而不是坏只是过量。我想我可以让他们都依赖于虚假的目标:
ver.h ver.cpp : do-version-impl
do-version-impl:
./gen/version/program
.PHONY : do-version-impl
这是最好的方法吗?为了做到这一点,必须引入虚假的规则,闻起来有点好笑。
答案 0 :(得分:2)
使用虚假目标作为先决条件是一个坏主意。即使存在program
个文件,也会运行ver.*
,这是一个误报错误。
更巧妙的是,GNU Make只保证更新其文件时间戳,如果该文件是带有配方的规则的目标。所以在这里,即使始终运行program
,依赖于ver.*
文件的任何内容都可能根本不会更新!
在我看来,最好不要为每个目标制作不自然的模式,而是明确地说:
有一个"主要"您正在生成的文件,即ver.cpp
。使用" no-op"另一个的食谱;
,可以像这样放在同一行:
ver.h: ver.cpp ;
ver.cpp: Makefile
./gen/version/program
此方法从您编写的内容开始,但添加了非常重要的;
。
如果你没有#34; main"文件,然后在我看来,最好使用" sentinel":
ver.h ver.cpp: sentinel ;
sentinel: Makefile
./gen/version/program
touch $@
同样,此方法与您的某个方法类似,但非常重要的是,不使用虚假文件,而是使用真实文件。
答案 1 :(得分:1)
具体见10.5.1 Introduction to Pattern Rules最后一段:
10.5.1模式规则简介
...
模式规则不需要包含'%'的任何先决条件,或者根本不需要任何先决条件。这样的规则实际上是一般的通配符。它提供了一种使任何文件与目标模式匹配的方法。见最后的度假胜地。
...
模式规则可能有多个目标。与普通规则不同,这并不会使用相同的先决条件和配方来执行许多不同的规则。如果模式规则具有多个目标,则make知道规则的配方负责制作所有目标。配方仅执行一次以制作所有目标。当搜索模式规则以匹配目标时,除了匹配需要规则的目标的规则之外的规则的目标模式是偶然的:仅担心给出当前有问题的文件的配方和先决条件。但是,当运行此文件的配方时,其他目标将标记为已自行更新。
所以你可以使用这样的东西:
v%r.h v%r.cpp:
./gen/version/program
我相信您需要使用奇怪的模式来考虑匹配的模式(我不认为它会匹配%
与ver%.h ver%.cpp
所需的空字符串相匹配)。 (我现在在手册中找不到对此的引用。)