📅  最后修改于: 2020-12-08 03:08:40             🧑  作者: Mango
Linux make命令用于从源代码构建和维护程序和文件组。在Linux中,它是开发人员最常用的命令之一。它帮助开发人员从终端安装和编译许多实用程序。此外,它还处理大型项目的编译过程。这样可以节省编译时间。
make命令的主要目的是将一个大型程序分成几部分,并检查是否需要重新编译。同样,它发出必要的命令以重新编译它们。
在本节中,我们将使用C++程序,因为C++编程语言是一种面向对象的语言,但是您可以使用计算机上安装的任何语言。它不仅限于程序;我们也可以用它来描述其他任务。
make命令将目标作为参数。这些参数在“ Makefile”中指定。生成文件包含目标以及与这些目标有关的关联操作。
当我们执行make命令时,它将搜索makefile并对其进行扫描以找到目标并访问其依赖项。如果未指定依赖关系,它将搜索并建立依赖关系。建立依赖关系后,它将构建主要目标。
例如,如果我们只想更改一个源文件,然后执行make命令;因此,这只会编译与该源文件连接的目标文件。这将在项目的最终编译中节省大量时间。
make命令调用makefile的执行。这是一个特殊文件,其中包含我们为维护项目而创建的Shell命令。生成文件包含执行的目标和命令。不允许创建多个makefile。建议为其创建一个单独的目录。
它跟踪最近的文件,因此仅更新所需的那些文件。如果我们有一个包含许多源文件的大型程序,则必须重新编译所有从属文件。因此,这可能是一个非常耗时的过程。
生成文件具有标准列表。这些标准有助于系统了解我们要执行的命令。这些标准分为两部分,并用新行分隔。第一行是相关性行,随后的行被视为动作或命令。这些命令用新行中的选项卡分隔。
依赖关系指定每个文件与源文件的关系。目标是一个可执行文件,它是在执行make命令之后创建的。
make命令提供了各种选项,以使其更加具体。一些重要的选项如下:
让我们了解一下make命令的一些示例。我们将了解makefile的基本用法,此外,我们将创建一些C++程序和一个makefile。我们将对它们执行一些操作以更好地理解make命令。
让我们了解一下make命令的最基本用法,它可以帮助您了解它的工作原理。
创建目录“项目”并更改目录。考虑以下命令:
mkdir project
cd project
现在,为第一个程序创建一个具有以下内容的“ Makefile”:
say_hello:
echo "Hello World!"
在上面的文件中,say_hello是一个目标,其行为类似于任何编程语言中的函数,并且echo将被视为一项操作。必须记住,应该使用TAB来编写动作。目标和操作共同为makefile创建规则。现在,执行make命令,如下所示:
考虑以下输出:
从上面的输出中,我们可以看到echo操作本身正在显示。如果我们不想在输出上显示echo命令,请执行以'@'符号开头的echo 。要抑制echo,请如下更新makefile的内容:
say_hello:
@echo "Hello World!"
考虑以下输出:
目标可能是取决于操作的二进制文件。
让我们再添加一些目标,例如makefile中的generate和list。更新makefile,如下所示:
say_hello:
@echo "Hello World!"
generate:
@echo "Creating files"
touch file-{1..5}.txt
list:
@echo "Listing files"
ls
如果执行make命令,则它仅执行第一个目标,因为它是makefile的默认目标。考虑以下输出:
我们可以通过在makefile中包含以下内容来更改默认目标:
.DEFAULT_GOAL := generate
如下所示将其添加到文件的第一行:
上面的makefile将把'generate'作为默认目标。执行make命令,它将给出如下输出:
DEFAULT GOAL选项将仅执行一个目标以指定多个目标来使用所有选项。要指定多个目标,请如下更新makefile的第一行:
all: say_hello generate
它将执行指定的目标。考虑以下输出:
还有另一个选项可以让我们执行所有目标。如果我们要执行makefile的所有目标,请如下更新文件:
.PHONY: all say_hello generate list
say_hello:
@echo "Hello World!"
generate:
@echo "Creating files"
touch file-{1..5}.txt
list:
@echo "Listing files"
ls
上面的文件将执行所有指定的目标。执行make命令,考虑以下输出:
让我们创建一个包含文件main.cpp,function1.cpp,function2.cpp和一个依赖文件函数.h的C++项目。
文件的代码如下:
main.cpp:
#include
#include "functions.h"
int main()
{
print_hello();
std::cout<< std::endl;
std::cout<< "The factorial of 5 is" << factorial(5) << std:: endl;
return 0;
}
function1.cpp:
#include "functions.h"
int factorial(int n)
{
if(n!=1)
{
return (n * factorial(n-1));
}
else return 1;
}
function2.cpp:
#include
#include "functions.h"
void print_hello()
{
std::cout << "Hello World";
}
functions.h:
void print_hello();
int factorial (int n);
现在,通过执行以下命令来创建上述项目的可执行文件:
g++ main.cpp function1.cpp function2.cpp -o hello
上面的命令将创建文件main.cpp,function1.cpp和function2.cpp的可执行文件“ hello”。
考虑以下输出:
从上面的输出中,如果成功执行,将不会提供任何输出。
让我们通过使用makefile执行相同的任务。
创建一个文件作为Makefile并将以下代码放入其中。
all:
g++ main.cpp function1.cpp function2.cpp -o hello
all关键字用于目标,在换行符中,使用与上述TAB相同的命令来指定操作。保存文件。考虑以下文件:
要进行操作,请执行以下命令:
make
上面的命令将创建指定文件的可执行文件“ hello”。考虑以下输出:
让我们向Makefile添加更多任务。添加任务“编译” ,如下所示:
all:
compile:
g++ main.cpp function1.cpp function2.cpp -o hello
要执行任务编译,请执行以下命令:
make compile
上面的命令将执行编译任务。考虑以下输出:
让我们对makefile执行更多任务。
更新Makefile,如下所示:
all: hello
hello: main.o function1.o function2.o
g++ main.o function1.o function2.o -o hello
main.o: main.cpp
g++ -c main.cpp
function1.o: function1.cpp
g++ -c function1.cpp
function2.o: function2.cpp
g++ -c function2.cpp
clean:
rm -rf *o hello
从上面的makefile文件中,我们创建了三个对象,分别是main.o,function1.o和function2.o。此外,我们分别提供了目标main.o,function1.o和function2.o的依赖关系,分别为main.cpp,function1.cpp和function2.cpp。所有目标将在其中执行指定的任务。我们还指定了一个清理目标来清理所有依赖项并删除可执行文件。
现在执行make all命令以执行我们的新makefile。
make all
考虑以下输出:
从上面的输出中,我们可以看到该命令首先分别执行了main.o,function1.o和function2.o。它将创建给定文件的可执行文件和对象文件。它不会执行清理目标,因为我们尚未在hello中指定它。考虑以下文件:
make命令具有直接的工作过程。它执行了all选项并打招呼。执行hello后,它将按指定顺序读取目标。它搜索每个目标及其依赖性,并按顺序执行它们。
要删除对象和可执行文件,请执行清理任务。要执行清理任务,请执行以下命令:
make clean
考虑以下输出:
上面的命令将删除所有对象和可执行文件。请参见下面的目录快照:
从上图可以看到我们已经清理了目录。
我们可以在makefile中定义变量。要定义变量,请使用'=“运算符。例如,如果要创建变量A并为其分配命令gcc,请将其分配为:
A=g++
在我们的makefile中按以下方式使用它:
hello: hello.cpp
${A} hello.cpp -o hello
它通过以下方式传递到终端:
g++ hello.cpp -o hello
我们可以使用$(A)代替$ {A},因为脚本对两者的处理相同。
要将注释添加到makefile中,请使用“#”符号。例如,要在编译部分添加注释,请将其添加为“#这将编译程序” 。注释将被编译器忽略。