我是否可以编写一个包装器makefile,它将cd升级并使用我给出包装器的所有命令选项执行make
?
更详细:
目录project
包含一个包含不同目标的真实Makefile。
目录project/resources
包含应该在project
中调用Makefile的包装器Makefile。
当我在目录project/resources
的shell中时,执行
make TARGET
和那里的Makefile只是cds一个目录并调用
make TARGET
目录project
中的。
这可能吗?怎么样?
答案 0 :(得分:2)
您可以对所有子目录使用非常简单的Makefile
:
%:
$(MAKE) -C .. $@
%
是最后的匹配任何模式规则,它将匹配任何目标...没有隐式规则(GNU make具有非常多的隐式规则)。因此,如果您的目标都没有被隐式规则覆盖,那么这应该有效。否则你必须告诉make不要使用它知道的隐含规则。这可以通过使用-r
选项调用make来完成(使用GNU make):
cd project/resources
make -r <anything>
将在project
中为目标<anything>
调用make。主要缺点是-r
标志被传递给子make,因此隐式规则既不适用于project
,也可能是一个问题。如果是,您可以通过向.SUFFIXES
中的Makefile
添加空的project/resources
目标来获得相同的效果:
.SUFFIXES:
%:
$(MAKE) -C .. $@
使用我的GNU make版本(3.82),它就像一个魅力,而sub-make具有所有默认的隐式规则。
答案 1 :(得分:1)
是的,你可以有一个适用于“任何”目标的makefile。
GNU make手册在Overriding Part of Another Makefile部分讨论了这个问题:
有时使用一个makefile就像另一个makefile一样有用。您通常可以使用
‘include’
指令将一个包含在另一个中,并添加更多目标或变量定义。但是,对于两个makefile,为同一目标提供不同的配方是无效的。但还有另一种方式。在包含makefile(想要包含另一个的makefile)中,您可以使用match-anything模式规则来重新创建无法根据包含的makefile中的信息创建的任何目标{{1}应该查看另一个makefile。有关模式规则的详细信息,请参阅Pattern Rules。
例如,如果你有一个名为
make
的makefile,它说明了如何制作目标Makefile
(以及其他目标),你可以编写一个名为‘foo’
的makefile,其中包含: / p>GNUmakefile
如果你说
foo: frobnicate > foo %: force @$(MAKE) -f Makefile $@ force: ;
,make会找到‘make foo’
,阅读它,并看到要生成GNUmakefile
,它需要运行配方foo
。如果您说‘frobnicate > foo’
,则‘make bar’
将无法在make
中设置栏,因此它将使用模式规则中的配方:GNUmakefile
。如果‘make -f Makefile bar’
提供更新Makefile
的规则,bar
将应用该规则。同样对于make
没有说明如何制作的任何其他目标。这样做的方式是模式规则只有
GNUmakefile
的模式,所以它匹配任何目标。该规则指定先决条件‘%’
,以确保即使目标文件已存在也将运行配方。我们为force
目标提供一个空配方,以防止force
搜索隐式规则来构建它 - 否则它会将相同的匹配任何规则应用于make
本身并创建先决条件循环!
答案 2 :(得分:0)
一个选项:使用包装器文件执行命令来执行此操作。确保您的目标make文件不包含具有包装器的子目录,否则您可以创建无限循环。例如,
clean:
pushd .. && make clean && popd
答案 3 :(得分:0)
使用用户Renaud Pacalet和answer to a different question的评论,以下单行内容尽可能接近。整个Makefile读取:
IGNORE := $(shell $(MAKE) -C .. $(MAKECMDGOALS))
这个解决方案有几点需要注意:
-B
不会传递给后续的make调用。project
目录中)不会打印到stdout。包装器制作过程最后报告任何给定目标:
make:***没有规则来制作目标TARGET。停止。