make和makedile简单讲解
文章参考《LinuxC编程实战》
make的作用
我刚开始学习make时我也搞不懂它的作用是什么,我个人比较喜欢把一个东西的作用高清楚了后在学习它,这样比较快。下面我们来看看make的作用吧!
当我们写一个比较复杂,比较庞大的文件时,我们需要把它们分别写成几个自己定义的 .h库 和 .c文件 例如:
def1.h
void func_one();
def2.h
void func_two();
f1.c
#include "stdio.h"
#include"def1.h"
void func_one()
{
printf("This is func_one(),it is in f1.c!\n");
}
f2.c
#include "stdio.h"
#include"def2.h"
void func_two()
{
printf("This is func_two(),it is in f2.c!\n");
}
main.c
#include"stdio.h"
#include"def1.h"
#include"def2.h"
int main()
{
printf("main() is runing!\n");
func_one(); //f1.c中函数
func_two(); //f2.c中函数
return 1;
}
在main.c文件中使用f1.c 和 f2.c中的函数,当我们想要直接
gcc main.c
./a.out
时gcc main.c会出错,因为f1.c 和 f2.c这两个文件并没有被编译,所以我们可以使用下面方法:
gcc f1.c f2.c main.c -o main
./main
但是如果需要用到的文件数很多,或者我修改了其中的一个文件中的内容就需要重新gcc一次,那就会带来很大的不便,因此我们可以使用make来解决,你可以理解为make执行makefile中的内容创建了一个可执行文件main。
抽象理解
makefile将一系列命令写入文件,用make来将他们一一执行,而如果要修改,也只是像修改宏定义一样修改一个地方而不需要全篇修改。
make的使用
make的使用主要是makefile文件的创建,makefile文件只是一个称呼,你可以将该文件的文件名创建为makefile或者Makefile,也可以是其他任意名称,只是后面有一点不一样,下面会介绍。
makefile文件
我先给出上面例子中的makefile文件吧!
makefile(文件名)
main:main.o f1.o f2.o
gcc main.o f1.o f2.o -o main #最前方是一个tab,下同
main.o:main.c def1.h def2.h
gcc -c main.c
f1.o:f1.c def1.h
gcc -c f1.c
f2.o:f2.c def2.h
gcc -c f2.c
makefile文件创建好后,在shell下执行
shell$: make //输入make然后enter
cc -c -o main.o main.c
cc -c -o f1.o f1.c
cc -c -o f2.o f2.c
gcc main.o f1.o f2.o -o main
shell$: ./main //输入./main然后enter
main() is runing!
This is func_one(),it is in f1.c!
This is func_two(),it is in f2.c!
执行make时生成了一个可执行文件main,和main.o , f1.o , f2.o。
makefile文件创建
我们见过了makefile文件后,就来学学如何创建一个makefile文件。创建makefile文件需要学习一些make规则,规则的组成如下:
目标文件列表及我们想要生成的文件,例如上面的main,main.o , f1.o , f2.o;分隔符一般使用 : (冒号)依赖文件列表则是生成目标文件所需要的文件,例如生成文件main需要文件main.o , f1.o , f2.o;[ ]中需要的是生成目标文件需要的命令,该命令可以跟在依赖文件后面,也可以另起一行,如果要跟在后面则需要先加上 ; (分号)如果要另起一行则需要以一个tab开头;如果你要在makefile中写注释需要以#开头。
我们来分析一下下面的makefile文件:
main:main.o f1.o f2.o #main为目标文件,:为分隔符,main.o f1.o f2.o为依赖文件
gcc main.o f1.o f2.o -o main #命令行,前面有一个tab,该命令生成一个可执行文件main
main.o:main.c def1.h def2.h #main.o为目标文件,:为分隔符,main.c def1.h def2.h为依赖文件
gcc -c main.c #命令行,前面有一个tab,该命令生成main.o文件,该文件是生成main文件的依赖文件
f1.o:f1.c def1.h #f1.o为目标文件,:为分隔符,f1.c和def1.h为依赖文件
gcc -c f1.c #命令行,前面有一个tab,该命令生成f1.o文件,该文件是生成main文件的依赖文件
f2.o:f2.c def2.h #f2.o为目标文件,:为分隔符,f2.c和def2.h为依赖文件
gcc -c f2.c #命令行,前面有一个tab,该命令生成f2.o文件,该文件是生成main文件的依赖文件
这就是一个简单的makefile文件,当然makefile文件可不只这么简单,它还有很多其他的功能和规则;下面我们来解释一下make执行makefile文件的过程:
make执行makefile中的内容时先从前到后进行一次,然后再从后向前进行一次,以例子为例:make先先找第一行中main文件,发现没有就继续找main.o等依赖文件,发现也没有就跳过第二行的命令,找到下一行的main.o文件,发现没有,便找main.c , def1.h , def2.h依赖文件,找到后执行命令行生成main.o文件,继续向下找到f1.o文件,没有便找f1.c和def1.h依赖文件,找到后执行命令行生f1.o文件,继续向下找f2.o,没有便找f2.h和def2.h文件,找到后执行命令行生成f2.o文件,接下来回溯到第一行,这时依赖文件已经生成,执行命令行生成main文件; 结束;
若你make生成一个main文件后又修改了某个文件,那就再make一次;如果是最新的main文件则显示:
make: “main”已是最新。
如果你创建的makefile文件名为其他文件名:
其他说明:命令行之间可以插入一些空行,空行也要一tab开头,如果某一行太长可以以\隔开;
前面说过make还有很多规则,这里只简单讲解了一下,下面是《LinuxC编程实战》中的部分讲解,你如果想更深入学习make可以看看这本书。