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