一.欢迎来到我的酒馆
在本章节介绍make工具。
目录
- 一.欢迎来到我的酒馆
- 二.什么是make
- 三.make与Makefile
- 四.如何写Makefile
二.什么是make
你可能会遇到一些名词:GNU,Linux,make。它们是什么,又有什么样的联系?
在1970年,最早的UNIX系统被开发出来。在UNIX刚开发出来的时候,为了促进UNIX系统的发展,AT&T公司将UNIX源码许可证授权给一些学术机构,许多机构在UNIX源码的基础上开发,开发出了很多类UNIX系统,UNIX系统在这一时期得到非常快速的发展。但是后来,AT&T公司将UNIX商业化并且闭源了,不在将UNIX源码的许可证授权给一些学术机构。为了避免版权纠纷,一个叫Richard M. Stallman的大叔发起了GNU计划,在类UNIX系统上从新开发出一个开源的操作系统。GNU是一个名字递归的缩写(GNU’s Not Unix!)。GNU是一个计划,它的目标是创建一套完全自由的操作系统。Rechard M.Stallman大叔为GNU计划开发著名的GCC和Emacs编辑器,并起草了GNU通用公共许可协议(GNU General Public License,GNU GPL),创造了copyleft的授权方式。所有的GNU程序遵循 "copyleft"原则,既可以拷贝、修改、出售,但源代码必须对每个用户公开,所有用户都可以获得修改后的源码。Rechard M. Stallman设立了自由软件基金会(Free Sofeware Fundation Inc. ,简称FSF)。
有了GNU计划,大家开始着手开发,开发出了很多项目,比如著名的GCC,GLIBC,还有Rechard M. Sstallman大叔开发的Emacs编辑器,基本上实现了GNU计划,但GNU计划还缺少一个操作系统内核。GNU项目从1990年开始开发GNU HURD,这个GNU HURD项目一直不能完成。这时候,一个叫Linus的同学在Minix的启发下开发了Linux,Linux只是一个系统内核,刚好这正是GNU计划的一部分,于是两者一拍即合,一起发布了GNU Linux。Linux系统启动之后,运行的是gcc,bash,emacs等软件。
make也是GNU计划的一个项目。GNU make是一个项目构建工具,由Rechard M. Stallman大叔和Roland McGrath开发。
三.make与Makefile
在准备使用make工具之前,你需要写一个文件名为Makefile,顾名思义,Makefile文件就是一个项目的配置文件信息,由make程序执行。在一个程序中,可执行文件一般需要从object文件(.o文件)更新。一旦你写好了Makefile文件,你就可以在shell里使用make:
make
make工具使用Makefile里面的数据为基础,并且决定哪些文件需要被更新,每个文件的执行过程都记录在Makefile文件里面。Makefile文件告诉make程序如何编译和连接一个程序。
四.如何写Makefile
一个简单的makefile包含了一个规则,如下面描述的那样:
target : prerequisites recipe 1recipe 2recipe 3......
- target。目标。通常是一个程序生成的文件名,target一般是可执行文件或object文件(.o文件)。target同样可以是一个执行名称,例如:clean.
- prerequisite 。依赖条件。它是一个文件,用作输入来创建一个target。一个target通常依赖多个文件。
- recipe。配方。一个配方可以理解成一个shell命令,在写每个个配方之前,必须敲一个tab键。
接下来,我们开始写一个Makefile。这里我准备通过用一个项目介绍Makefile,cJSON是c语言编写的JSON解码器,代码非常简洁,只有750行代码。先将cJSON项目下载下来,点击这里下载cJSON源代码,解压之后的文件:
有用的文件:
cJSON.c:写好的函数
cJSON.h :头文件
test.c:测试文件
接下来开始为这个项目创建Makefile文件,使用vim将下面内容粘贴到一个文件中,并命名为Makefile,如下:
all: testtest: test.c cJSON.o cJSON.hgcc -W -Wall -o test test.c cJSON.o -lm cJSON.o: cJSON.cgcc -W -Wall -c -o cJSON.o cJSON.cclean:rm -rf *.o test
来看一下这个Makefile文件是怎么写的,测试文件test.c用于生成一个可执行文件,它会用到cJSON.h里面的函数,而cJSON.h的函数实现写在cJSON.c中,所以,生成可执行文件的时候需要链接cJSON.o文件,cJSON.c文件编译之后就是一个.o文件了。
下面是对编译参数的介绍:
-W:关闭所有警告信息。
-Wall:打开警告信息。
-o:输出目标文件
-lm:链接库math。
-c:编译目标文件,但不链接。
在当前文件打开命令行,输入命令:make就可以构建整个cJSON项目了。下面来看一些Makefile的执行流程:
①:target为all,all需要依赖条件test,test文件存在吗 ?执行空命令 :执行②;
②:target为test,test需要依赖条件cJSON.o,cJSON.o文件存在吗 ?执行⑦⑧ :执行④;
④:target为cJSON.o,cJSON.o需要先决条件cJSON.c,cJSON.c文件存在吗 ?执行⑥ : 报错make: *** No rule to make target `cJSON.c’,
⑥:是一条熟悉的gcc命令,写gcc命令之前需要敲一个tab键,执行完⑥后回到④的步骤,此时步骤④的依赖条件都满足了,执行下面的gcc命令⑨,编译test.c文件并且链接cJSON.o文件,生成可执行文件test。
⑩:target为clean,clean没有需要的先决条件,所以默认不会执行,除非指定参数才会执行。
make的执行流程不知道我讲清除没有,有点印象的话,我们赶紧生成一个程序,跑一下cJSON项目。在Makefile的同级目录下打开命令行,输入命令:
make
如果你按照上面的流程写,不出意外的话,将会得到下面的输出:
gcc -W -Wall -c -o cJSON.o cJSON.c
gcc -W -Wall -o test test.c cJSON.o -lm
......
上面的两条gcc命令看到之后,是不是觉得很熟悉!这和我们在shell里写的编译命令是一样的!
如果要删除编译的文件,可以执行命令:(这和上面讲到的make执行流程第⑩是一样的指定一个参数执行,就会执行11)
make clean