【问题标题】:What is the difference between make and gcc?make 和 gcc 有什么区别?
【发布时间】:2010-10-20 13:58:30
【问题描述】:

article的最后一句话引起了我的注意

[F] 或 C/C++ 开发人员和 有兴趣学习的学生 用 C/C++ 编写程序而不是用户 Linux。这是因为编译 源代码变得简单 GNU/Linux 使用“make” 命令。

我一直使用 gcc 来编译我的 C/C++ 程序,而 javac 来编译我的 Java 程序。我只使用 make 通过 configure/make/make install 将程序安装到我的计算机上。

看来你显然可以用 make 命令编译所有程序。

ma​​ke 和 gcc 有什么区别?

【问题讨论】:

  • 需要注意的是,javac 包含一些基本的依赖解析,即也是一个简单的 make。它将递归查找其他类使用的类(源)并在需要时编译它们,即使它们没有作为参数提及。 C 编译器或链接器不这样做,部分原因是一方面的目标文件 resp 库与源之间的连接无法像在 Java 中那样推断出来,其中物理文件名和路径对应于逻辑类名和包。

标签: gcc makefile compiler-construction


【解决方案1】:

嗯... gcc 是一个编译器,make 是一个帮助构建程序的工具。差异是巨大的。你永远不能纯粹使用 make 来构建程序;它不是编译器。是什么让它引入了一个单独的“规则”文件,描述了如何从源代码到完成的程序。然后它解释这个文件,找出需要编译的内容,并为你调用 gcc。这对于具有数百或数千个源代码文件的大型项目非常有用,并且可以跟踪编译器选项、包含路径等内容。

【讨论】:

  • 对于简单的单文件应用程序,Make 不再需要 makefile。如果您有文件application.cpp,那么make application 将构建它。
  • @LokiAstari 那么对单个文件使用 make 或 gcc 没有区别吗?当我使用 gcc 时,我得到一个 .out 文件,但 make 给出了一个同名且没有扩展名的文件。有什么区别?
  • @Manoj:从来没有说过没有区别。当您运行 make plop.cppit 时,它会准确打印出它在做什么:g++ plop.cpp -o plop(实际操作将取决于您的环境,因为 make 也会从中提取设置(因此它永远不会与直接调用 g++ 相同)) .对于make 可能会做正确事情的简单情况,您只是不需要makefile。但总的来说,我认为正在发生的事情非常直观。
【解决方案2】:

gcc 编译和/或链接单个文件。它支持多种语言,但不知道如何将多个源文件组合成一个重要的、正在运行的程序——您通常需要至少两次 gcc 调用(编译和链接)才能创建最简单的程序。

GCC 上的维基百科页面将其描述为“编译器系统”:

GNU Compiler Collection(通常缩写为 GCC)是由 GNU 项目生产的支持各种编程语言的编译器系统。

ma​​ke 是一个“构建工具”,它以特定顺序调用编译器(可能是 gcc)来编译多个源并将它们链接在一起。它还跟踪源文件编译产生的各种源文件和目标文件之间的依赖关系,并且只对自上次构建以来已更改的组件执行操作。

GNUmake 是一种流行的 make 实现。来自 GNUmake 的描述如下:

Make 是一个工具,它控制从程序的源文件生成程序的可执行文件和其他非源文件。

Make 了解如何从名为 makefile 的文件构建程序,该文件列出了每个非源文件以及如何从其他文件计算它。

【讨论】:

    【解决方案3】:

    gcc 是一个 C 编译器:它接受一个 C 源文件并创建机器代码,可以是未链接的目标文件的形式,也可以是实际的可执行程序,它已链接到所有目标模块和库。

    make 对于控制项目的构建过程很有用。一个典型的 C 程序由几个模块 (.c) 和头文件 (.h) 组成。在更改任何内容后总是编译所有内容会很耗时,因此 make 旨在仅编译更改后需要重新编译的部分。

    它通过遵循程序员创建的规则来做到这一点。例如:

    foo.o: foo.c foo.h
        cc -c foo.c
    

    这条规则告诉 make 文件 foo.o 依赖于文件 foo.c 和 foo.h,如果它们中的任何一个发生变化,可以通过运行第二行的命令来构建它。 (上面不是实际的语法:make 想要由 TAB 字符缩进的命令,在这种编辑模式下我不能这样做。但想象一下它就在那里。)

    make 从通常称为 Makefile 的文件中读取其规则。由于这些文件(传统上)是手工编写的,因此 make 有很多魔力可以让您缩短规则。例如,它知道 foo.o 可以从 foo.c 构建,并且它知道这样做的命令是什么。因此,上述规则可以简化为:

    foo.o: foo.h
    

    由三个模块组成的小程序可能有这样的 Makefile:

    mycmd: main.o foo.o bar.o
        $(CC) $(LDFLAGS) -o mycmd main.o foo.o bar.o
    foo.o: foo.h bar.h
    bar.o: bar.h
    

    make 可以做的不仅仅是编译程序。一个典型的 Makefile 会有一个规则来清除不需要的文件:

    clean:
        rm -f *.o core myapp
    

    另一个规则可能会运行测试:

    check: myapp
        ./myapp < test.input > test.output
        diff -u test.correct test.output
    

    Makefile 可以“构建”文档:例如,运行一个工具将文档从某种标记语言转换为 HTML 和 PDF。

    Makefile 可能有一个安装规则,用于将它构建的二进制程序复制到用户或系统管理员希望它安装的任何位置。

    等等。由于 make 是通用且强大的,它通常用于自动化从解压缩源 tarball 到软件可供用户使用的整个过程。

    如果你想全面了解make,还有很多东西要学。 GNU 版本的 make 有特别好的文档:http://www.gnu.org/software/make/manual/ 有各种形式。

    【讨论】:

    • 我会将“make”和“gcc”与网络技术中的“git”和“ftp-transfer”进行比较。:git 就像 make(如果需要,只更新更改的文件,这是常见的)用例)和像 ftp 一样的 gcc(改变一切)
    【解决方案4】:

    Make 经常使用 gcc 编译大量 C 或 C++ 文件。

    【讨论】:

      【解决方案5】:

      Make 是一种工具,可通过执行最少的必要工作来构建各种系统组件之间存在依赖关系的任何复杂系统。

      如果您想了解所有可以使用的东西,GNU make manual 非常好。

      【讨论】:

        【解决方案6】:

        make 在当前目录中使用Makefile 将一组规则应用于其输入参数。 Make 还知道一些默认规则,因此即使在当前目录中找不到Makefile(或类似的)文件,它也会执行。为cpp 文件执行的规则恰好在许多系统上调用gcc

        请注意,您调用make 时不使用输入 文件名,而是使用反映输出规则名称。因此调用make xyz 将努力执行规则xyz,该规则默认构建一个文件xyz(例如基于源代码文件xyz.cpp

        【讨论】:

          【解决方案7】:

          make 本质上是一个用于构建代码的专家系统。您为事物的构建方式以及它们所依赖的内容设置了规则。然后,Make 可以查看所有文件的时间戳,并准确确定需要随时重建的内容。

          gcc 是“gnu 编译器集合”。它支持多种语言(C、C++、Ada 等,具体取决于您的设置),但它仍然只是 make 可用于构建系统的众多工具中的一种。

          【讨论】:

            【解决方案8】:

            您可以使用 make 编译您的 C 和 C++ 程序,方法是在您的 makefile 中调用 gcc 或 g++ 来完成所有编译和链接步骤,让您通过一个简单的命令完成所有这些步骤。它不是编译器的替代品。

            【讨论】:

              【解决方案9】:

              gcc 是类似javac 的编译器。你给它源文件,它给你一个程序。

              make 是一个构建工具。它需要一个文件来描述如何根据文件之间的依赖关系构建项目中的文件,因此当您更改一个源文件时,您不必重新构建所有内容(就像您使用构建脚本一样)。 make 通常使用gcc 来实际编译源文件。

              【讨论】:

              • 正如我在对 OP 问题的评论中所说:javac 不仅仅是一个编译器,它基于内置规则执行依赖项检查(由于 Java 的路径/名称与包/类对应)。
              【解决方案10】:

              'gcc' 是编译器——实际上将源代码转换为可执行文件的程序。您必须告诉它源代码在哪里、要输出什么以及其他各种信息,例如库和选项。

              'make' 更像是一种用于编译程序的脚本语言。这是一种隐藏编译源代码的所有细节(所有那些你必须通过编译器的参数)的方法。您可以在 Makefile 中编写一次上述所有详细信息,因此您不必每次都为每个文件键入它。它还会做一些漂亮的事情,比如只重新编译已经更新的源文件,并处理依赖关系(如果我重新编译这个文件,我就需要重新编译那个文件。)

              【讨论】:

                【解决方案11】:

                最大的不同是 make 是图灵完备的 (Are makefiles Turing complete?) 而 gcc 不是。

                【讨论】:

                  【解决方案12】:

                  我们以gcc 编译器为例。 它只知道如何将给定的.cpp 文件编译成.o 文件给定编译成功所需的文件(即.h 文件等依赖项)。

                  但是,这些依赖项会创建一个图表。例如,b.o 在编译过程中可能需要a.o,这意味着它需要事先独立编译。

                  作为一名程序员,您是否想要跟踪所有这些依赖项并运行它们以构建您的目标 .o 文件?

                  当然不是。你想要一些东西来为你完成这项任务。

                  这些是构建工具 - 有助于简化构建过程(即构建像 .o 文件这样的工件)的工具。一个这样的工具是make

                  我希望澄清区别:)

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-11-14
                    • 1970-01-01
                    • 2010-10-14
                    • 2011-08-16
                    • 2017-07-16
                    • 1970-01-01
                    相关资源
                    最近更新 更多