如果尚未安装,我想将要生成的包添加到生成列表中。目标是安装一些没有pip和本地源代码的python包。我没有权限访问PIP…所以我写了一个文件,看起来像:all: natsort foo bar foobar ...natsort: natsort-4.0.4.tar.gz tar xvzf $< cd $(patsubst %.tar.gz,%, $<) && python setup.py install rm -rf $(patsubst %.tar.gz,%, $<) python -c 'import natsort' echo -e "Installation of $< [done]\n" >> install.log此实现的问题是,每次运行make命令时,将重新生成并重新安装所有包。我想检查模块是否已经安装。我的想法是这样做:ifdef $(shell python -c 'import natsort')all: natsortendif我怎样重写才能让它工作? 最佳答案 你完全可以这样做。但每次运行make时,它都会“消耗”一个shell调用和一个python调用,这是一个相对较高的成本。基本上,有两种方法可以以更便宜的方式做你想做的事。配方中的戳记文件和短路逻辑。stamp file方法基本上就是您所拥有的,除了在配方末尾添加touch $@。natsort: natsort-4.0.4.tar.gz tar xvzf $< cd $(patsubst %.tar.gz,%, $<) && python setup.py install rm -rf $(patsubst %.tar.gz,%, $<) python -c 'import natsort' echo -e "Installation of $< [done]\n" >> install.log touch $@这样,在第一次运行配方时会创建戳记文件,并且在natsort-4.0.4.tar.gz比戳记文件更新或戳记文件被删除之前,配方将永远不会再次运行。注意第二点。删除印记文件,然后重新安装。这就是短路逻辑解决方案解决的问题。与原来的多个命令规则不同,您可以将其全部打包到一个命令中(这是可选的,但可以节省重复的检查成本),并在执行任何工作之前检查要安装的模块。natsort: natsort-4.0.4.tar.gz if ! python -c 'import natsort'; then \ tar xvzf $< || exit 1; \ cd $(patsubst %.tar.gz,%, $<) && python setup.py install || exit 1; \ rm -rf $(patsubst %.tar.gz,%, $<); \ python -c 'import natsort' || exit 1; \ echo -e "Installation of $< [done]\n" >> install.log; \ fi请注意,需要添加|| exit 1,因为我们不再需要为我们处理它。还要注意,现在它总是运行规则(我们应该标记natsort和.PHONY),但在最常见的情况下,它将在if测试之后停止。所有这些都表明,你可以结合这些方法,以获得最好的两个世界。natsort: natsort-4.0.4.tar.gz if ! python -c 'import natsort'; then \ tar xvzf $< || exit 1; \ cd $(patsubst %.tar.gz,%, $<) && python setup.py install || exit 1; \ rm -rf $(patsubst %.tar.gz,%, $<); \ python -c 'import natsort' || exit 1; \ echo -e "Installation of $< [done]\n" >> install.log; \ fi touch $@两种方法都有好处。第一次运行make 文件不存在,并运行配方。natsort未安装,因此natsort测试失败并进行安装。在那之后if文件就被编辑了。下次安装make时natsort比touch更新,所以natsort认为它与此无关。如果由于某种原因,删除了natsort-4.0.4.tar.gz文件,然后下一次make运行,检查该模块是否存在,跳过安装并再次使用natsort文件,以恢复同步。关于linux - 使用Make构建 shell 条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33630829/ 10-10 12:44