我有一个具有以下目录结构的项目:
foo/
foo/Makefile
foo/bar/
我的目标是添加文件foo/bar/Makefile
,这样如果我在make
中调用foo/bar
,将使用父目录的Makefile。它是一种反向递归的Makefile结构(我希望每个Makefile都调用父目录,直到它到达项目根目录。)
Symlinking失败,因为从错误的目录调用它会破坏所有相对路径:
$ ln -s ../Makefile foo/bar/Makefile
$ make -C foo/bar
[error]
我找到的唯一解决方案是编写一个Makefile,它捕获我感兴趣的所有目标并调用该目标的父目录:
$ cat foo/bar/Makefile
all clean:
$(MAKE) -C .. $@
这很费力且易于破裂。有更优雅的解决方案吗?
理由
该项目是一个大型的LaTeX文档,其中包含用于章节,图形等的.tex
个文件的多个子目录。我希望能够从这些目录中的任何一个调用make
来构建文档
答案 0 :(得分:3)
感谢Etan Reisner指出match-anything rule。这个Makefile将捕获所有目标并将它们传递给父Makefile:
all:
@make -C .. $@
%:
@make -C .. $@
请注意,除了匹配任何规则之外,还必须提供默认的所有规则,否则make
会在没有参数的情况下进行调用时抱怨:make: *** No targets. Stop.
答案 1 :(得分:2)
您可以创建自定义函数以在右侧文件夹中运行make
:
make-foo() {
make -C /absolute/path/to/foo "$@"
}
答案 2 :(得分:1)
您不应该在此处需要多次Makefile
和递归调用Make
。递归Make
本身就很糟糕,除非您完全了解其局限性,否则不应使用递归Make
。
GNU Make功能取决于其环境。因此,应始终(在严肃的系统中,而不是玩具中)控制环境并将Make
包装在设置环境的包装器shell脚本中,然后调用Makefile
(从顶部开始一次)。你对#34; make-only"的渴望被误导了。
在你的情况下,你的包装器脚本进入一个循环,在那里它查找一个名为cd
的文件,如果没有找到,Make
到父目录并重复。找到后,使用给定的参数执行subdir>make foobar
。
在我的实践中,我还使用了上面更详细的版本,其中包装脚本研究给定的参数,对于那些作为目标的,将它们添加到它从其开始的子目录的路径。那么
>make subdir/foobar
相当于
{{1}}