Recursion 调用父目录的Makefile
我有一个具有以下目录结构的项目:Recursion 调用父目录的Makefile,recursion,build,makefile,latex,Recursion,Build,Makefile,Latex,我有一个具有以下目录结构的项目: foo/ foo/Makefile foo/bar/ 我的目标是添加一个文件foo/bar/Makefile,这样,如果在foo/bar中调用make,将使用父目录的Makefile。它是一种反向递归的Makefile结构(我希望每个Makefile调用父目录,直到它到达项目根目录) 符号链接失败,因为从错误目录调用它会中断所有相关路径: $ ln -s ../Makefile foo/bar/Makefile $ make -C foo/bar [error
foo/
foo/Makefile
foo/bar/
我的目标是添加一个文件foo/bar/Makefile
,这样,如果在foo/bar
中调用make
,将使用父目录的Makefile。它是一种反向递归的Makefile结构(我希望每个Makefile调用父目录,直到它到达项目根目录)
符号链接失败,因为从错误目录调用它会中断所有相关路径:
$ ln -s ../Makefile foo/bar/Makefile
$ make -C foo/bar
[error]
我找到的唯一解决方案是编写一个Makefile,它捕获我感兴趣的所有目标,并使用该目标调用父目录:
$ cat foo/bar/Makefile
all clean:
$(MAKE) -C .. $@
这是一项艰巨的任务,很容易被打破。有更优雅的解决方案吗
理由
该项目是一个大型LaTeX文档,其中包含章节、图表等的
.tex
文件的多个子目录。我希望能够从这些目录中的任何一个调用make
,以构建文档。您可以创建一个自定义函数,在右侧文件夹中运行make
:
make-foo() {
make -C /absolute/path/to/foo "$@"
}
感谢Etan Reisner指出问题所在。此生成文件将捕获所有目标并将其传递给父生成文件:
all:
@make -C .. $@
%:
@make -C .. $@
注意,除了match anything规则之外,还需要提供默认的all规则,否则
make
如果在没有参数的情况下调用,make:**no targets,就会发出抱怨。停止。
您不需要在此处使用多个Makefile
s和递归调用Make
。递归Make
本身就不好,除非您确切了解其局限性,否则不应使用它
GNU Make的功能取决于其环境。因此,应该始终(在一个严肃的系统中,而不是玩具中)控制环境,并将Make
包装在一个包装器shell脚本中,该脚本设置环境,然后调用Make
(一次,从顶部开始)。你对“只做”的渴望被误导了
在本例中,包装器脚本进入循环,在循环中查找名为Makefile
的文件,如果找不到,则将cd
发送到父目录并重复。找到后,使用给定的参数执行Make
在我的实践中,我还使用了上面更详细的版本,其中包装器脚本研究给定的参数,对于那些目标,在它们前面加上它开始的子目录的路径。所以
subdir>make foobar
相当于
>make subdir/foobar
基于@chris cummins之前的回答,最好使用
$(MAKE)
而不是@MAKE
除其他事项外,这将保留并行构建(-j XX),否则会留下大量性能
最终版本将是(在GNU Make 4.2.1上测试):
全部:
美元(MAKE)-C$@
%:
美元(MAKE)-C$@
有关说明,请参见此操作有效,谢谢。不过,我在理想情况下需要一个makeonly解决方案,因为我不想只为一个项目修改shell环境。这也可以通过一个别名来实现:
alias make foo='make-C/abs/path/to/foo'
如果您觉得您的解决方案“费力且容易崩溃”,为什么不让它$(make)-C/path/to/project/root$@
?这样一来,您只需要进行一次递归调用,而不是多次调用,一个已断开的makefile不会断开树中它下面的所有makefile。讨论如何做(以及其他许多事情)。谢谢@EtanReisner<代码>全部%:@make-C$@@EtanReisner您不能混合隐式规则和常规规则,因此会出现重复。这很公平。它在GNU Make 3.81中工作,但在较新版本中会出错。嗨,马克,我很感激你的回答,但我不同意递归Make。递归make本身并不坏,通常对它的批评都不适用于这种简单的情况。除顶层外的所有makefile都是简单的包装器,不会向环境中注入任何内容。@ChrisCummins无需反对,听起来好像,您确实了解递归Make限制,然后,如我所说,如果您喜欢它而不是包装器脚本,那么使用它是可以的。