Linux make 命令

2025年03月17日 | 阅读 9 分钟

Linux 中的 make 命令用于从源代码构建和维护程序和文件组。在 Linux 中,它是开发人员最常用的命令之一。它帮助开发人员在终端中安装和编译许多实用程序。此外,它还处理大型项目的编译过程。它可以节省编译时间。

make 命令的主要目的是将一个大型程序分解成多个部分,并检查是否需要重新编译。同时,它还会发出必要的命令来重新编译它们。

在本节中,我们将使用 C++ 程序,因为 C++ 编程语言是一种面向对象的语言,但您可以使用机器上安装的任何语言。它不仅仅限于程序;我们还可以使用它来描述其他任务。

make 命令如何工作?

make 命令将目标作为参数。这些参数在 'Makefile' 中指定。makefile 包含目标以及与这些目标相关的操作。

当我们执行 make 命令时,它会查找 makefile 并扫描它以找到目标并访问其依赖项。如果未指定依赖项,它将搜索依赖项并进行构建。在构建完依赖项后,它将构建主目标。

例如,如果我们只想更改一个源文件并执行 make 命令;那么,这将只编译与该源文件关联的对象文件。这将在项目的最终编译过程中节省大量时间。

什么是 Makefile?

make 命令调用 makefile 的执行。它是一个特殊文件,其中包含我们为维护项目而创建的 shell 命令。makefile 包含目标和执行命令。不允许创建多个 makefile。建议为其创建一个单独的目录。

它会跟踪最近修改的文件,因此只更新需要更新的文件。如果我们有一个包含许多源文件的大型程序,我们必须重新编译所有依赖文件。因此,这可能是一个非常耗时的过程。

makefile 有一系列的标准。这些标准有助于系统理解我们要执行的命令。这些标准分为两部分,并用换行符分隔。第一行是依赖行,后续行被视为操作或命令。命令在新行的制表符处分隔。

依赖项指定每个文件与源文件的关系。而目标是一个可执行文件,它是在 make 命令执行后创建的。

选项

make 命令提供了各种选项使其更加具体。一些重要选项如下:

  • -b, -m: 这些选项用于忽略不同版本 make 命令的兼容性。
  • -B, --always-make: 这些选项用于无条件地构建所有目标。
  • -C dir, --directory=dir: 这些选项用于在执行 makefile 之前更改目录。
  • -d: 用于打印调试信息。
  • --debug[=FLAGS]: 用于在正常处理的同时打印调试信息。如果跳过标志,则其结果与 '-d' 选项相同。
  • -e, --environment-overrides: 用于提供来自环境优先级的变量到 makefile。
  • -f file, --file=file, --makefile=FILE: 用于使用文件作为 makefile。
  • -i, --ignore-errors: '-i' 选项用于忽略命令中的所有错误。
  • -I dir, --include-dir=dir: 用于指定一个目录来搜索指定的 makefile。如果指定了多个 '-I' 选项,它将按指定的顺序在多个目录中搜索。
  • -j [jobs], --jobs[=jobs]: 用于指定同时运行的作业数。如果提供多个 '-j' 选项,则最后一个将被考虑执行。如果不指定作业数,则不会限制可以同时运行的作业数。
  • -k, --keep-going: 用于在遇到错误后,尽可能继续执行程序。
  • -l [load], --load-average[=load]: 用于指定,如果队列中有其他任务且负载平均值最低,则不启动新任务。
  • -n, --just-print, --dry-run, --recon: 用于显示将要运行的命令。
  • -o file, --old-file=file, --assume-old=file: 用于确保即使文件比其依赖项旧,make 也不会重新构建它。
  • -O[type], --output-sync[=type]: 用于确保每个任务的输出是聚合在一起的,而不是其他任务输出的混合。这对于使用 '-j' 选项的多任务处理很有用。
  • -p, --print-data-base: 用于打印在读取 makefiles 后生成的数据库。与 '-v' 选项一起使用时,它也有助于打印版本信息。要打印数据库而不尝试重新构建任何文件,请按如下方式执行命令:
    make -p -f/dev/null.
  • -q, --question: '-q' 选项用于问询模式。它不会运行任何命令或打印任何内容。如果指定的目标已经同步,它将只返回零退出状态;否则,它将显示非零退出状态。
  • -r, --no-builtin-rules: 用于消除内置隐式规则的使用。
  • -R, --no-builtin-variables: 如果我们不想定义任何内置变量,则此选项很有用。
  • -s, --silent, --quiet: 这些选项被称为静默操作。它限制打印正在执行的命令。
  • -S, --no-keep-going, --stop: 用于取消 "-k, --keep-going" 操作的效果。
  • -t, --touch: 用于触摸文件而不是运行它们的命令。
  • --trace: 用于跟踪每个目标的处理过程。
  • -v, --version: 用于打印 make 工具的已安装版本。此外,它还显示作者、版权以及关于 make 工具的一些通知。
  • -w, --print-directory: 用于在执行其他处理之前和之后打印包含工作目录的消息。这对于从复杂的递归 make 命令结构中跟踪错误很有用。
  • --no-print-directory: 用于关闭 '-w' 选项。
  • -W file, --what-if=file, --new-file=file, --assume-new=file: 这些选项假装目标文件刚刚被修改。
  • --warn-undefined-variables: 此选项用于警告引用了未定义变量。

让我们通过一些 make 命令的例子来理解。我们将看到 makefile 的基本用法,然后我们将创建一些 c++ 程序和一个 makefile。我们将对它们执行一些操作,以便更好地理解 make 命令。

make 命令的基本用法

让我们来理解 make 命令的最基本用法,它可能会帮助你理解它的工作原理。

创建一个名为 'project' 的目录并切换到该目录。考虑以下命令:

现在创建一个名为 "Makefile" 的文件,并包含第一个程序的以下内容:

从上面的文件中,say_hello 是一个目标,它就像任何编程语言中的函数一样,而 echo 将被视为一个操作。必须记住,操作应该使用 TAB 来编写。目标和操作一起为 makefile 创建了一个规则。现在,如下执行 make 命令:

考虑下面的输出

Linux make command

从上面的输出中,我们可以看到 echo 操作本身正在显示。如果我们不想在输出中显示 echo 命令,请在 echo 前面加上 '@' 符号。要抑制 echo,请更新 makefile 的内容如下:

考虑下面的输出

Linux make command

目标可能是一个依赖于操作的二进制文件。

让我们在 makefile 中添加几个目标,例如 generate 和 list。更新 makefile 如下:

如果我们执行 make 命令,它只会执行第一个目标,因为它是 makefile 的默认目标。考虑以下输出:

Linux make command

我们可以通过在我们的 makefile 中包含以下内容来更改默认目标:

将其添加到文件第一行如下:

Linux make command

上面的 makefile 将 'generate' 作为默认目标。执行 make 命令,它将产生以下输出:

Linux make command

DEFAULT GOAL 选项将只执行一个目标,要指定多个目标,请使用 all 选项。要指定多个目标,请更新 makefile 的第一行如下:

它将执行指定的目标。考虑以下输出:

Linux make command

还有另一个选项允许我们执行所有目标。如果我们想执行 makefile 的所有目标,请按如下方式更新文件:

上面的文件将执行所有指定的目标。执行 make 命令,考虑以下输出:

Linux make command

make 命令的高级用法

让我们创建一个具有 main.cpp、function1.cpp、function2.cpp 文件和一个依赖文件 function.h 的 C++ 项目。

文件的代码如下:

main.cpp

function1.cpp

function2.cpp

functions.h

现在通过执行以下命令为上述项目创建一个可执行文件:

上面的命令将为主文件 main.cpp、function1.cpp 和 function2.cpp 创建一个可执行文件 'hello'

考虑下面的输出

Linux make command

从上面的输出中,如果成功执行,它将不会产生任何输出。

让我们使用 makefile 执行相同的任务。

创建一个名为 Makefile 的文件并将以下代码放入其中。

all 关键字用作目标,在新行上放置与上面相同的命令,并用 TAB 来指定操作。保存文件。考虑以下文件:

Linux make command

要执行,请按如下方式执行命令:

上面的命令将为指定的文件创建一个可执行文件 'hello'。考虑以下输出:

Linux make command

让我们向 Makefile 添加更多任务。添加一个名为 'compile' 的任务,如下所示:

要执行 compile 任务,请执行以下命令:

上面的命令将执行 compile 任务。考虑以下输出:

Linux make command

让我们对 makefile 执行更多任务。

按如下方式更新 Makefile:

从上面的 makefile 中,我们创建了三个对象:main.o、function1.o 和 function2.o。此外,我们为目标 main.o、function1.o 和 function2.o 分别提供了 main.cpp、function1.cpp 和 function2.cpp 作为依赖项。所有目标都将在其中执行指定的任务。我们还指定了一个 clean 目标来清理所有依赖项并删除可执行文件。

现在执行 make all 命令来执行我们的新 makefile。

考虑下面的输出

Linux make command

从上面的输出中,我们可以看到命令首先依次执行了 main.o、function1.o 和 function2.o。它将创建给定文件的可执行文件和对象文件。它不会执行 clean 目标,因为我们没有在 hello 中指定它。考虑以下文件:

Linux make command

make 命令有一个直接的工作流程。它执行 all 选项并转到 hello。在 hello 执行之后,它按指定的顺序读取目标。它搜索每个目标及其依赖项,并按顺序执行它们。

要删除对象文件和可执行文件,请执行 clean 任务。要执行 clean 任务,请按如下方式执行命令:

考虑下面的输出

Linux make command

上面的命令将删除所有对象文件和可执行文件。请参阅目录的以下快照:

Linux make command

从上图可以看出,我们已经清理了目录。

make 命令中的变量

我们可以在 makefile 中定义变量。要定义变量,请使用 '=' 运算符。例如,如果我们想创建一个变量 A 并为其分配 gcc 命令,则按如下方式分配:

在我们的 makefile 中按如下方式使用它:

它被传递到终端如下:

我们可以使用 $(A) 代替 ${A},因为脚本将两者视为相同。

makefile 中的注释

要在 makefile 中添加注释,请使用 '#' 符号。例如,要在 compile 部分添加注释,请添加 "# This will compile the program"。注释将被编译器忽略。


下一个主题GCC Linux