为什么要在shell脚本上使用make?


128

在我看来,Make似乎只是一个shell脚本,具有稍微更易于处理的命令行参数。

为什么标准运行make而不是./make.sh


反向问题:为什么在make上使用shell脚本(由于明显更容易处理命令行参数),尤其是对于系统管理员任务,请阅读:unix.stackexchange.com/a/497601/1170
lesmana

Answers:


125

通常的想法是make(合理地)支持最小限度的重建-即,您告诉它程序的哪些部分取决于其他部分。当您更新程序的某些部分时,它重建依赖于该部分的部分。虽然你可以做到这一点有一个shell脚本,这将是一个很大更多的工作(显式检查上的所有文件,等等。最后修改日期)与shell脚本的唯一明显的办法是每次重建一切。对于小型项目,这是一种完全合理的方法,但是对于大型项目,完整的重建可能很容易花费一个小时或更长时间-使用make,您可能会在一两分钟之内轻松完成同一件事...

我可能还应该补充说,有很多替代方案可以使它们至少具有大致相似的功能。尤其是在仅重建大型项目中的几个文件的情况下,其中一些文件(例如Ninja)通常比make快得多。


66

Make是一个专家系统

使用shell脚本很难完成很多事情...

  • 当然,它会检查是否过时,以便仅构建它需要构建的内容
  • 它执行拓扑排序或其他类型的树分析,以确定什么取决于构建过期事物的内容和顺序,以便每个先决条件在每个依赖项之前构建,并且仅构建一次。
  • 这是用于声明式编程的语言。可以添加新元素,而无需将其合并到命令性控制流中。
  • 它包含一个用于处理规则,模式和日期的推理引擎,当与您特定Makefile中的规则结合使用时,make就会变成一个专家系统
  • 它具有一个宏处理器。
  • 另请参阅:make的早期摘要

2
但是,它作为专家系统非常有限。例如,每个推断只能使用一次相同的规则。
reinierpost

1
为了用更多的外行工程术语详细说明第2点,shell脚本强制执行线性排序,而makefile类似于树。它消除了不必要的时间依赖性(尽管在实践中,生成过程将线性执行)。
Sridhar Sarnobat 2014年

2
...我认为使用Shell脚本制作文件的麻烦类似于使用JavaScript编写CSS的麻烦。执行每个节点的时间顺序几乎不是那么明显。尽管至少使用Makefile,您仍然可以看到实际的shell命令。使用CSS甚至可以将其抽象化。
Sridhar Sarnobat 2014年

如果有人澄清我的意见,我不胜感激。1 /从拓扑排序是如何实现增量构建的意义上说,您的第一点和第二点不是相关的吗?2 /您也不能指出使用函数组合实现的3号。3 /我想了解更多关于MakeFile最终用户的4和5的优势,以及为什么不能通过将shell命令组合在一起来实现这些优势
Amine Hajyoussef

这是我第一次遇到被描述为专家系统的Make。作为构建专家系统的人,我不会考虑这一点。Make显然具有一个推理引擎来推断如何通过makefile中指定的声明性规则来构建程序,但是由于(叶子)规则是要执行的Shell命令而不是事实,因此它不是一个基于知识的系统。术语“专家系统”用于指已成功捕获世界一流专家的专业知识的系统,事实并非如此。陪审团仍在我身边。
丹尼斯,

9

Make确保在更改源文件时仅重新编译所需的文件。

例如:

final : 1.o 2.o
    gcc -o final 1.o 2.o

1.o : 1.c 2.h
    gcc -c 1.c

2.o : 2.c 2.h
    gcc -c 2.c

如果我2.h仅更改文件并运行make,它将以相反的顺序执行所有3条命令。

如果我1.c仅更改文件并运行make,它将仅以相反的顺序执行前两个命令。

尝试使用您自己的shell脚本来实现这一点将涉及很多if/else检查。


rsync -r -c -I $SOURCE $DEST_DIR在shell中使用类似的东西。
斯巴达克斯9年

9

和上面一样,Make是一种声明性(-ish)并行编程语言。

假设您有4,000个要转换的图形文件和4个CPU。尝试编写一个10行的shell脚本(我在这里很慷慨),可以在使CPU饱和的同时可靠地执行此操作。

也许真正的问题是人们为什么要花时间编写Shell脚本。


1
是的,您正在将总的线性顺序松散为更像树的顺序。
Sridhar Sarnobat 2014年

4

make处理依赖关系:makefile描述它们:二进制文件取决于目标文件,每个目标文件取决于源文件和头文件...运行make时,将比较文件的日期以确定需要重新编译的内容。

一个人可以直接调用一个目标,而不用构建Makefile中描述的所有内容。

此外,make语法提供了替换,vpath

所有这些都可以用shell脚本编写,使您已经拥有它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.