本系列教程翻译参考自tutorialspoint, 感谢!

首先来说说什么是Makefile。Makefile是一个运在Unix,Linux平台的程序构建工具,并且遵循Unix和Linux风格。它有助于简化构建可能需要各种各样的模块的可执行程序。为了确定如何将模块编译或重新编译,make(make是一个构建自动化工具,它可以读取名为makefile的文件自动构建可执行程序和库,这些文件指定了如何导出目标程序)工具需要用户定义makefiles。那么这篇教程的目的就是让你对makefile有更多的了解与认识,出发喽!

致读者

Makefile在make工具编译和链接程序模块时给予指导。如果你想使用make工具编译你的程序,或者想要了解更多关于Makefile的知识,那就阅读这篇教程吧,相信你一定能获得你想要的。

预备知识

这个教程并不是零基础的,需要你对编程有一个好的认识,比如C或C++(因为make工具就是用来编译C或C++写的程序)。希望读者具备链接、加载的概念以及如何在Unix/Linux环境下编译可执行程序。

为什么我们需要Makefile?

因为编译源代码文件可能会很麻烦,特别是当项目必须包含多个(可能达上千甚至上万个)源文件,每次编译时都需要输入很长很长的编译命令,那会非常地累,可能等你输入完以后就没有力气按下“Enter”键了。而Makefile的功用就是简化这个任务。

Makefile是一种特殊的文件格式,它可以自动构建和管理项目。例如,假设我们有以下文件。

  • main.cpp
  • hello.cpp
  • factorial.cpp
  • functions.h

main.cpp

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

using namespace std;

int main()
{
print_hello();
cout << endl;
cout << "The factorial of 5 is" << factorial(5) << endl;
return 0;
}

hello.cpp

1
2
3
4
5
6
7
8
9
10
#include <iostream>

using namespace std;

#include "functions.h"

void print_hello()
{
cout << "leoay is so cool!";
}

factorial.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "functions.h"

int factorial(int n)
{
if(n!= 1)
{
return(n * factorial(n-1));
}
else
{
return 1;
}
}

functions.h

1
2
void print_hello();
int factorial(int n);

编译文件并获得可执行文件的简单方法是运行以下命令。

1
gcc main.cpp hello.cpp factorial.cpp -o hello

这条命令将会生成一个 hello 二进制文件(可执行文件,类似于Windows下的exe文件)在这个例子中,我们只有4个文件,并且我们知道函数的调用顺序。因此输入上述命令并准备最终的二进制文件是可行的。然而,对于一个有上千源文件的大型项目来说,要维护二进制构建变得非常困难。

make命令允许我们管理大型程序或程序组。当我们开始编译大型程序时,我们注意到重新编译大型程序需要的时间比重新编译短程序时间更长。此外,我们注意到,make命令通常只在程序的一小部分工作(比如某个函数),而其他大部分程序都是不变的。

在这个