【问题标题】:Why use make over a shell script?为什么在 shell 脚本上使用 make?
【发布时间】:2011-04-17 10:44:34
【问题描述】:

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

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

【问题讨论】:

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

标签: shell makefile compilation


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    与上述一样,Make 是一种声明式(-ish)并行编程语言。

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

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

    【讨论】:

    • 是的,您正在将总线性排序松散为更像树的排序。
    • 这是我的用例。你能举个例子吗?
    【解决方案3】:

    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 检查。

    【讨论】:

    • 或者在shell中使用类似rsync -r -c -I $SOURCE $DEST_DIR的东西。
    【解决方案4】:

    Make 是一个 expert system

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

    • 当然,它会检查什么是过时的,以便只构建它需要构建的东西
    • 它执行 topological sort 或其他类型的树分析,以确定构建过时事物的依据和顺序,例如每个先决条件都在每个依赖项之前构建,并且只构建一次。
    • 这是 declarative programming 的语言。无需将新元素合并到命令式控制流中即可添加新元素。
    • 它包含 an inference engine 来处理规则、模式和日期,当与特定 Makefile 中的规则结合使用时,它会将 make 变成expert system
    • 它有一个宏处理器。
    • 另请参阅:an earlier summary of make

    【讨论】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-12-14
      • 2017-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      相关资源
      最近更新 更多