学习笔记——makefile(示例)
先建立一个文件夹sample,用来存放工程文件。在其中建立一个main.cpp 作为工程的主程序,建立一个heads.h在其中声明一个函数,以及一个heads.cpp实现该函数,最后在main.cpp中调用这个函数。整个工程目录如图所示。
main.cpp的内容如下:
/**
* Makefile demo main.cpp
* */
#include <iostream>
#include "heads.h"
using namespace std;
int main()
{
cout << "sum = " << add(36, 24) << endl;
return 0;
}
heads.h的内容:
#ifndef __HEADS_H_
#define __HEADS_H_
int add(int a, int b);
#endif
heads.cpp的内容:
#include "heads.h"
int add(int a, int b)
{
return a + b;
}
期望的输出是
sum = 60
本例选用clang作为编译器,在终端输入
clang++ -std=c++11 heads.cpp main.cpp -o hello
查看工程目录,会发现多了一个名为hello的可执行文件
运行hello,发现程序的输出是
接下来在目录中新建一个名为“Makefile”的文件(注意大小写,建议如此命名,没有后缀)。把上文的编译命令copy进去,得到的Makefile内容如下:
all:
clang++ -std=c++11 heads.cpp main.cpp -o hell
进入终端,cd到sample目录下,删除之前的hello文件,输入make,结果相同。
目标文件hello是由main.cpp和heads.cpp组成的,而mian.cpp和heads.cpp又都依赖于heads.h头文件,理清了这个关系之后可以发现这个prerequisites就是生成该目标所需要的目标文件、源文件、头文件等。根据这一点Makefile就可以改写成如下的形式:
hello : main.o heads.o
clang++ -std=c++11 heads.o main.o -o hello
main.o : main.cpp heads.h
clang++ -std=c++11 -c main.cpp
heads.o : heads.cpp heads.h
clang++ -std=c++11 -c heads.cpp
这个脚本的逻辑用自然语言来描述就是,需要将main.o和heads.o链接生成可执行文件hello,而main.o和heads.o是根据它们的源代码文件(.cpp)和heads.h通过命令
此时在终端输入make
命令执行的顺序和上文描述的逻辑是一样的,此时会发现目录下会多出两个文件分别叫main.o和heads.o,这两个目标文件就是前两条命令生成的。
接下来需要做的就是利用makefile的各种便利功能来简化脚本,削减工作量。首先用到的就是变量,makefile中的变量可以理解为一种等价代换,将经常用到的命令、文件、目标等等归拢到一个变量中,方便复用也方便修改。那么这个工程的Makefile可以改写为如下的形式:
objects = main.o heads.o
CPP = clang++
CPPFLAGS = -std=c++11
hello : $(objects)
$(CPP) $(CPPFLAGS) $(objects) -o hello
main.o : main.cpp heads.h
$(CPP) $(CPPFLAGS) -c main.cpp
heads.o : heads.cpp heads.h
$(CPP) $(CPPFLAGS) -c heads.cpp
这里把目标文件、编译器、编译器选项都分别赋值给了一个变量在下面调用。接下来利用到的就是makefile强大的自动推导功能了,举例来说,想要生成main.o肯定要利用到main.cpp,脚本中main.cpp就是多余的,而且生成.o文件的也只有这一条命令,所以这条命令也是多余的,不用你强调,makefile自己也知道该如何做。那么我们就可以把该省略的都省略,最后添加一个清除不要的.o文件的命令,整个Makefile就算大功告成了。
![](/qrcode.jpg)
objects = main.o heads.o
CPP = clang++
CPPFLAGS = -std=c++11
hello : $(objects)
$(CPP) $(CPPFLAGS) $(objects) -o hello
main.o : heads.h
heads.o : heads.h
#清除.o文件
.PHONY : clean
clean :
-rm $(objects)