ChatGPT解决这个技术问题 Extra ChatGPT

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

在我看来,Make 只是一个 shell 脚本,对命令行参数的处理稍微容易一些。

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

对于相反的问题:为什么要使用 shell 脚本而不是 make(因为显然更容易处理命令行参数),尤其是对于系统管理员任务,请阅读此处:unix.stackexchange.com/a/497601/1170

J
Jerry Coffin

一般的想法是 make 支持(合理地)最少的重建——即,你告诉它你的程序的哪些部分依赖于其他部分。当您更新程序的某些部分时,它重建依赖于它的部分。虽然您可以使用 shell 脚本来执行此操作,但这将是很多更多的工作(明确检查所有文件的最后修改日期等)。唯一明显的使用 shell 脚本的替代方法是每次都重建所有内容。对于小型项目,这是一种非常合理的方法,但对于大型项目,完全重建可能需要一个小时或更长时间——使用 make,您可能在一两分钟内轻松完成相同的事情......

我可能还应该补充一点,有很多替代品至少具有大致相似的功能。尤其是在大型项目中只有少数文件被重建的情况下,其中一些文件(例如,Ninja)通常比 make 快得多。


C
Community

Make是一个专家系统

有很多事情是用 shell 脚本很难做到的......

当然,它会检查什么是过时的,以便只构建它需要构建的东西

它执行拓扑排序或某种其他类型的树分析,以确定什么依赖于什么以及构建过时事物的顺序,这样每个先决条件都在每个依赖项之前构建,并且只构建一次。

它是一种用于声明式编程的语言。可以添加新元素,而无需将它们合并到命令式控制流中。

它包含一个推理引擎来处理规则、模式和日期,当与特定 Makefile 中的规则结合使用时,它就变成了一个专家系统。

它有一个宏处理器。

另请参阅:make 的早期摘要。


但是,它作为专家系统非常有限。例如,每个推理只能使用相同的规则一次。
只是为了用更通俗的工程术语详细说明第 2 点,shell 脚本强制执行线性排序,而 makefile 是树状的。它消除了不必要的时间依赖(尽管在实践中 make 过程将线性执行)。
...我认为 Makefiles 在 shell 脚本上的问题类似于 CSS 在 javascript 上的问题。每个节点执行的时间顺序并不那么明显。尽管至少使用 Makefiles 你仍然可以看到实际的 shell 命令。使用 CSS 甚至可以将其抽象掉。
如果有人澄清它们,我有一些意见我很感激。 1/你的第一点和两点不是相关的,从某种意义上说,拓扑排序是增量构建的实现方式吗? 2/你不能指出使用函数组合实现的第 3 点吗。 3/ 我想了解更多关于MakeFile最终用户4和5的优势,以及为什么这些优势不能通过组合shell命令来实现
这是我第一次遇到被描述为专家系统的 Make。作为构建专家系统的人,我不会考虑这件事。 Make 显然有一个推理引擎来推断如何通过 makefile 中指定的声明性规则来构建程序,但它是一个基于知识的系统不太明显,因为(叶)规则是要执行的 shell 命令而不是事实。而“专家系统”这个词是用来指一个系统,它成功地捕捉到了世界级专家的专业知识,事实并非如此。陪审团还在找我。
C
Chris Dodd

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,它只以相反的顺序执行前 2 个命令。

尝试使用您自己的 shell 脚本完成此操作将涉及大量 if/else 检查。


或在 shell 中使用类似 rsync -r -c -I $SOURCE $DEST_DIR 的东西。
b
bobbogo

除了上述之外,Make 是一种声明性(-ish)并行编程语言。

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

也许真正的问题是人们为什么要费心编写 shell 脚本。


是的,您正在将整个线性排序放松为更像树的排序。
这是我的用例。你能举个例子吗?
p
philant

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

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

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

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