`

linux make工具使用 Makefile编写

阅读更多

在Linux环境下使用GNU的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。

不过这需要我们投入一些时间去完成一个或者多个称之为Makefile 文件的编写。此文件正是 make 正常工作的基础。

make是一个命令工具,它解释Makefile中的指令(应该说是规则)。在 Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。

准备知识:编译,链接,静态库,共享库

编译:把高级语言所书写的代码转换成机器可识别的指令,此时还不能够被执行。编译器通过检查高级语言的语法,函数和变量的声明是否正确!如果正确则产生中间目标文件(目标文件在Liunx中默认后缀为“.o”)

链接:将多.o 文件,或者.o 文件和库文件链接成为可被操作系统执行的可执行程序

静态库:又称为文档文件(Archive File)。它是多个.o文件的集合。Linux中静态库文件的后缀为“.a”

共享库(动态库):也是多个.o 文件的集合,但是这些.o 文件是由编译器按照一种特殊的方式生成(共享库已经具备了可执行条件)

 

在执行make之前,需要一个命名为Makefile的特殊文件来告诉 make 需要做什么,该怎么做。

当使用make工具进行编译时,工程中以下几种文件在执行make时将会被编译(重新编译): 

1.所有的源文件没有被编译过,则对各个C源文件进行编译并进行链接,生成最后的可执行程序。

2.所有在上次执行make之后修改过的C源代码文件在本次执行make时将会被重新编译。

3.头文件在上一次执行make之后被修改。则所有包含此头文件的C源文件在本次执make时将会被重新编译。

 

Makefile规则介绍 

一个简单的Makefile描述规则组成: 

       TARGET... : PREREQUISITES... 

            COMMAND 

            ... 

            ... 

target:规则的目标。通常是最后需要生成的文件名或者为了实现这个目的而必需的中间过程文件名。可以是.o文件、也可以是最后的可执行程序的文件名等。

另外,目标也可以是一个make执行的动作的名称,如目标“clean”(目标“clean”不是一个文件,它仅仅代表执行一个动作的标识。),我们称这样的目标是“伪目标”

prerequisites:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。 

command:规则的命令行。是规则所要执行的动作(任意的shell命令或者是可在shell下执行的程序)。它限定了make执行这条规则时所需要的动作。 

一个规则可以有多个命令行,每一条命令占一行。注意:每一个命令行必须以[Tab] 字符开始,[Tab]字符告诉 make 此行是一个命令行。make按照命令完成相应的动作。 

这也是书写 Makefile中容易产生,而且比较隐蔽的错误。 

命令就是在任何一个目标的依赖文件发生变化后重建目标的动作描述。

一个目标可以没有依赖而只有动作(指定的命令)。比如Makefile 中的目标“clean”,此目标没有依赖,只有命令。它所定义的命令用来删除 make 过程产生的中间文件(进行清理工作)。

在Makefile中“规则”就是描述在什么情况下、如何重建规则的目标文件,通常规则中包括了目标的依赖关系(目标的依赖文件)和重建目标的命令。

make执行重建目标的命令,来创建或者重建规则的目标(此目标文件也可以是触发这个规则的上一个规则中的依赖文件)。规则包含了文件之间的依赖关系和更新此规则目标所需要的命令。 

一个 Makefile 文件中通常还包含了除规则以外的很多东西(后续我们会一步一步的展开)。

一个最简单的Makefile 可能只包含规则。规则在有些 Makefile 中可能看起来非常复杂,但是无论规则的书写是多么的复杂,它都符合规则的基本格式。 

make 程序根据规则的依赖关系,决定是否执行规则所定义的命令的过程我们称之为执行规则。 

 

简单的示例 

一个简单的Makefile,来描述如何创建最终的可执行文件"edit",此可执行文件依赖于8个C源文件和3个头文件。Makefile文件的内容如下: 

       #sample Makefile 

        edit : main.o kbd.o command.o display.o \ 

              insert.o search.o files.o utils.o 

             cc -o edit main.o kbd.o command.o display.o \ 

                   insert.o search.o files.o utils.o 

       main.o : main.c defs.h

             cc -c main.c 

       kbd.o : kbd.c defs.h command.h 

             cc -c kbd.c 

       command.o : command.c defs.h command.h 

             cc -c command.c 

       display.o : display.c defs.h buffer.h 

             cc -c display.c 

       insert.o : insert.c defs.h buffer.h 

             cc -c insert.c 

       search.o : search.c defs.h buffer.h 

             cc -c search.c 

       files.o : files.c defs.h buffer.h command.h 

             cc -c files.c 

       utils.o : utils.c defs.h 

             cc -c utils.c 

       clean : 

            rm edit main.o kbd.o command.o display.o \ 

                   insert.o search.o files.o utils.o 

 

首先书写时,可以将一个较长行使用反斜线(\ )来分解为多行。但需要注意:反斜线之后不能有空格(这也是大家最容易犯的错误,错误比较隐蔽)。

在完成了这个Makefile以后,需要创建可执行程序"edit",所要做的就是在包含此Makefile的目录(当然也在代码所在的目录)下输入命令“make”。

删除已经此目录下之前使用“make”生成的文件(包括那些中间过程的.o文件),也只需要输入命令“make clean”就可以了。 

 

make如何工作

默认的情况下,make执行的是Makefile中的第一个规则,此规则的第一个目标称之为“最终目的”或者“终极目标”(就是一个Makefile最终需要更新或者创建的目标)。 

上例的 Makefile,目标"edit"在 Makefile 中是第一个目标,因此它就是make的“终极目标”。当修改了任何C源文件或者头文件后,执行make将会重建终极目标"edit"。 

 

当在shell提示符下输入“make”命令以后,make 读取当前目录下的Makefile文件,并将Makefile文件中的第一个目标作为其执行的“终极目标”,开始处理第一个规则(终极目标所在的规则)。

在上例中,第一个规则就是目标"edit"所在的规则。规则描述了"edit"的依赖关系,并定义了链接.o文件生成目标"edit"的命令; 

make在执行这个规则所定义的命令之前,首先处理目标"edit"的所有的依赖文件(例子中的那些.o 文件)的更新规则(以这些.o 文件为目标的规则)。

对这些.o 文件为目标的规则处理有下列三种情况: 

1.  目标.o 文件不存在,使用其描述规则创建它; 

2.  目标.o 文件存在,目标.o 文件所依赖的.c 源文件、.h 文件在上一次 make 之后被修改,则根据规则重新编译生成它; 

3.  目标.o 文件存在,目标.o 文件所依赖的.c 源文件、.h 文件在上一次make 之后没有被修改,则什么也不做。 

这些.o文件所在的规则之所以会被执行,是因为这些.o 文件出现在“终极目标”的依赖列表中。

在Makefile中一个规则的目标如果不是“终极目标”所依赖的(或者“终极目标”的依赖文件所依赖的),那么这个规则将不会被执行,

除非明确指定执行这个规则(可以通过 make 的命令行指定重建目标,那么这个目标所在的规则就会被执行,例如“make clean”)。

在编译或者重新编译生成一个.o 文件时,make 同样会去寻找它的依赖文件的重建规则,在这里就是.c 和.h 文件的重建规则。

在上例的 Makefile 中没有哪个规则的目标是.c或者.h 文件,所以没有重建.c 和.h 文件的规则 

完成了对.o 文件的创建(第一次编译)或者更新之后,make 程序将处理终极目标"edit"所在的规则,分为以下三种情况: 

1.  目标文件"edit"不存在,则执行规则以创建目标"edit"。 

2.  目标文件"edit"存在,其依赖文件中只要有一个文件比它新,则根据规则重新链接生成"edit"。 

3.  目标文件"edit"存在,它比它的任何一个依赖文件都新,则什么也不做。 

上例中,如果更改了源文件“insert.c”后执行make,“insert.o”将被更新,之后终极目标"edit"将会被重生成。

如果我们修改了头文件“command.h”之后运行“make”,那么“kbd.o”、“command.o”和“files.o”将会被重新编译,之后同样终极目标"edit"也将被重新生成。

 

指定变量

"objects"作为一个变量,它代表所有的.o文件的列表。在定义了此变量后,我们就可以在需要使用这些.o文件列表的地方使用"$(objects)"来表示它,而不需要罗列所有的.o文件列表。

 

make如何解析makefile文件 

对于一个存在的规则(明确规则和隐含规则)首先,make程序将比较目标文件和所有的依赖文件的时间戳。如果目标的时间戳比所有依赖文件的时间戳还新(依赖文件在上一次执行make之后没有被修改),那么什么也不做。

否则(依赖文件中所有在上一次执行make后被修改过),规则所定义的重建目标的命令将会被执行。这就是make工作的基础,也是其执行规制所定义命令的依据。 

 

使用自动工具autoscan、autoconf和automake来自动生成Makefile文件。其实这三个自动工具不但可以生成Makefile文件,还可用来发布软件。

熟悉Linux的用户可能知道,在Linux下安装一个应用程序时,一般先运行脚本configure,然后用make来编译源程序,再运行make install,最后运行make clean删除一些临时文件。

使用上述三个自动工具,就可以生成configure脚本

运行configure脚本,就可以生成Makefile文件,然后就可以运行make、make install和make clean。

 

利用configure所产生的Makefile文件有几个预设的目标可供使用,其中几个重要的简述如下:

make all:产生我们设定的目标,即此范例中的可执行文件。只打make也可以,此时会开始编译原始码,然后连结,并且产生可执行文件。

make clean:清除编译产生的可执行文件及目标文件(object file,*.o)。

make distclean:除了清除可执行文件和目标文件外,把configure所产生的Makefile也清除掉。

make install:将程序安装至系统中。如果原始码编译无误,且执行结果正确,便可以把程序安装至系统预设的可执行文件存放路径。如果用bin_PROGRAMS宏的话,程序会被安装至/usr/local/bin这个目录。

make dist:将程序和相关的档案包装成一个压缩文件以供发布。

执行完在目录下会产生一个以PACKAGE-VERSION.tar.gz为名称的文件。PACKAGE和VERSION这两个变数是根据configure.in文件中AM_INIT_AUTOMAKE(PACKAGE,VERSION)的定义。

在此范例中会产生test-1.0.tar.gz的档案。

make distcheck:和make dist类似,但是加入检查包装后的压缩文件是否正常。这个目标除了把程序和相关文件包装成tar.gz文件外,还会自动把这个压缩文件解开,执行configure,并且进行make all 的动作,确认编译无误后,会显示这个tar.gz文件可供发布了。

这个检查非常有用,检查过关的包,基本上可以给任何一个具备GNU开发环境-的人去重新编译。

 

分享到:
评论

相关推荐

    Makefile的编写与使用

    makefile工具的编写和使用,可以在linux系统中编写相应的C++文件

    linux编程基础-makefile的使用-作业1.docx

    关于makefile的实验报告

    make 中文手册(内含makefile的语法)

    作为一个Linux程序员,make工具的使用以及编写Makefile是必需的。系统、详细讲述make的中文资料比较少,出于对广大中文Linuxer的支持,本人在工作之余,花了18 个多月时间完成对“info make”的翻译整理,完成这个...

    GNU MAKE 中文手册 makefile中文手册

    GNU make中文手册,编写Makefile参考资料,makefile编写规则,makefile菜鸟教程,Linux Makefile,Window Makefile,嵌入式Makefile规则, Makefile如何运行,makefile手册

    autotools使用--Linux Makefile的自动生成工具

    autotools作为linux开发人员应该不陌生的,它可以说是linux程序release时必备的工具了,可以省很多的麻烦事(至少免去了编写makefile的繁重工作),试试吧。

    Linux通过Makefile模型

    通过该Makefile模型,可以自己修改源文件和头文件的路径后,执行make和make clean即可,通用、快速完成makefile的编写

    Linux环境下makefile脚本的编写

    针对Linux环境下的开发,makefile脚本文件的操作显得尤其重要,特别是程序文件个数比较多,需要编译的源文件数目较多时,其效率是可见的,本文当详细介绍了makefile脚本的各种详细编写语法和步骤,相信会对喜欢...

    西南科技大学+Linux实验报告+Linux环境下C语言编程

    3.掌握自动编译工具make的使用和Makefile的编写方法 二、实验设计 1.GCC使用方法 2.调试器GDB使用方法(选做) 3.编译配置工具Make工具使用 4.Linuxer编译配置 四、实验思考或体会 思考题: 任务一:编译器GCC...

    8_Makefile的使用和编写.pdf

    1. linux Makefile文档,可使用与新手学习如何写Makefile 2. 文档中包含了Makefile的详细讲解

    linux系统的Makefile教程

    作为一个Linux程序员,make工具的使用以及编写Makefile是必需的。系统、详细讲述make的中文资料比较少,出于对广大中文Linuxer的支持,本人在工作之余,花了18个多月时间完成对“info make”的翻译整理,完成这个...

    一个通用Makefile的编写

    我们在Linux环境下开发程序,少不了要自己编写Makefile,一个稍微大一些的工程下面都会包含很多.c的源文件。如果我们用gcc去一个一个编译每一个源文件的话,效率会低很多,但是如果我们可以写一个Makefile,那么只...

    LinuxUnix环境下的Make和Makefile详解.pdf

    不错的makefile编写文档,相比gnumake手册,要生动的多,作者从自己的亲身体会出发讲解makefile的编写方法和规则,让你学的同时领会make工具创作者的目的!

    GNU make 和 makefile

    对Linux下的Make使用及 makefile文件的编写作了清楚的介绍

    makefile实验报告和代码.rar

    The final product is an executable file named sinewave, which is created by linking together two other compiled files, sinewave.o and intarray.o. The two compiled files were created by compiling sine...

    Linux makefile 文件的使用例子,用Makefile编译多个文件

    Linux makefile 文件的使用例子,用Makefile编译多个文件。 一个简单的Makefile的编写,适合初学者.

    Tmake 很好用的Makefile生成工具

    Linux下编译工具,很好用的Makefile生成工具,可以自动生成Makefile非常方便,只要用progen生成.pro文件,或者自己手动编写一个.pro文件,就可以轻松生成适合目标系统的Makefile,因此也适用于交叉编译使用

    Linux下的Makefile源码(仅适用于C语言单目标)

    此为本人自己编写的,在Linux下的Makefile源码,仅适用于C语言单目标,且所有依赖的.c和.h文件要在同...使用方法:将Makefile文件复制到工程所在的.c和.h文件目录中,然后在linux终端,打开此文件所在的目录,执行make指令即可

    GNU Makefile 文件编写

    linux下Makefile 文件的制作,讲解很详细

    GNU makefile

    作为一个Linux程序员,make工具的使用以及编写Makefile是必需的。系统、详细讲述make的中文资料比较少,出于对广大中文Linuxer的支持,本人在工作之余,花了18个多月时间完成对“info make”的翻译整理,完成这个...

    linux中tcp实例+makefile

    在ubuntu12.04中编写TCP通信实例,并自己写makefile文件,编译、链接命令为make,清除命令为make clean。服务器端输入q为与客户端断开链接,客户端退出,服务器端输入s则服务器端退出。关于退出方式大家可以根据自己...

Global site tag (gtag.js) - Google Analytics