本文主要是介绍GNU中的make和makefile,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
说来惭愧呀,调试驱动代码的时候每天都在使用make命令,却不知道make命令究竟是用来做什么的,上周有个师弟问我make和makefile究竟是用来做什么的,我只是根据自己的理解给他说了一下,回头想想自己说的也不对呀,所以才回过头来好好再学习一下make命令和makefile.这部分的内容主要参考了《Linux程序设计第四版》和http://hi.baidu.com/tvbljlqlfkaejwr/item/75de403d5ea908f2e6bb7a3c这位高手的博客
人们都是喜欢怀旧的,人也是有感情的,所以人们对于自己的第一次经历的东西,往往刻骨铭心。,比如说我们的初恋,还有我们的.......,比如说我的第一首能用吉他结结巴巴弹出来的歌。比如说我用gcc编译的第一个程序,gcc -o test test.c
但是对于我这种没有亲自编写过大项目的“大水”来说,一个gcc -o基本上就可以把所有的程序给编译出来,但是对于一些大的项目来说,通常有很多的源文件,不可能一条条的来用gcc来编译,这时候我们就可以使用make工具来自动完成编译任务。
其实这里面还有一个好处就是:当我们只修改了其中的某几个头文件的源文件的时候,很多其他的源文件都没有修改,这时候我们并不需要把所有的源文件再重新编译一下,因为其中很多的源文件跟我们修改过的源文件并没有依赖关系,这时候使用这种自动编译可以大大的简化开发工作,避免不必要的重新编译。(如果这里看不明白的话,可以参考Linux程序设计第四版317页上面的例子,简单明了)
Make基础知识:
首先来说一下make吧:
Make有很多的选项(这个是大牛说的),常用的主要有下面3个:
-k:make命令在发现错误的时候仍然继续执行,而不是在检测到一个错误的时候就停下来。
-n:这个就是告诉make输出将要执行的操作不走,而不是真正的去执行,
-f:这个家伙比较厉害,用来告诉make命令哪个文件来作为makefile,不过一般人都这么干,我是一般人,所以也不这么干。
补充其他的如下:
命令行选项 含义
-C DIR 在读取 makefile 之前改变到指定的目录 DIR。
-f FILE 以指定的 FILE 文件作为 makefile。
-h 显示所有的 make 选项。
-i 忽略所有的命令执行错误。
-I DIR 当包含其他 makefile 文件时,可利用该选项指定搜索目录。
-n 只打印要执行的命令,但不执行这些命令。
-p 显示 make 变量数据库和隐含规则。
-s 在执行命令时不显示命令。
-w 在处理 makefile 之前和之后,显示工作目录。
-W FILE 假定文件 FILE 已经被修改。
通常情况下,我们使用make工具的时候,我们通常通过一个称为makefile的文件来完成并自动维护编译工作。当然这个makefile中的语法是按照某种语法规则来写的。主要说明了如何编译各个源文件并将之链接成为一个可执行的文件。同时定义了各个源文件之间的依赖关系,如果其他的源文件依赖于该文件的话,那么也需要重新编译所有依赖于这个文件的源文件。
这里我们说的make工具是GUN make工具,这个强大的工具(据说很强大哦,我还没有深刻体会到)会在当前的目录下按照下面的顺序来寻寻觅觅makefile
GNUmakefile
Makefile
Makefile
当然也可以指定其他名字的文件;来作为makefile,一般人都不这么做,我是一般人,所以也不会这么做。
Makefile中的基础知识和一些基本概念:
Makefile中一般包含下面的内容:
*需要make来创建的项目,通常是目标文件和可执行文件,通常使用“target”来表示要创建的项目
*要创建的项目需要依赖哪些文件
*创建每个项目的时需要运行的命令
通常情况下,一个makefile文件中可以有多个目标,利用make target命令可以指定要编译的目标。举个例子来说就是:
test: test.o related.o
test1: test1.o related.o
...
我们可以使用make test和make test1来分别编译不同的目标,如果没有指定的话,通常情况下,则是使用的第一个目标。
通常情况下,一个makefile通常由一系列的规则组成,而在一条规则中通常由一个目标,条件,和命令组成
下面举个规则的例子来看一下:
main: main.o stack.o maze.o
gcc main.o stack.o maze.o -o main
在这个东东中,main是这个规则的目标,main.o stack.o maze.o是这个规则的条件。目标和条件的关系是:欲更新目标,必须先更新它所有的条件,下面这行就是传说中的命令了,需要特别注意的是命令列表中每个命令必须以一个tab来开头,而不能使用几个空格代替,(这是什么破规定呀)
通常情况下,makefile中会有一个clean规则,这个通常情况下是用来清理一些东西的,通常是编译过程中产生的二进制文件,而保留源文件。这个东西我们经常在编译驱动的时候用到的。
Clean规则和前面介绍的规则不同,clean目标不依赖于任何条件,并且执行它的命令不会生成clean这个文件。
其实吧clean在makefile中是一个约定俗成的名字,还有其他的名字
all:执行主要的编译工作,这个是一个伪代码,它可以一次用来创建多个文件。
Install:执行编译后的安装工作,把可执行文件配置文件问道分别cp到不同的安装目录
Clean:删除
Makefile中的注释:
Makefile中的注释一般以#开头,一直延续到这一行的结尾,说道井了我就邪恶的想起了big笑工坊中一期中论名字的重要性了。
在这里再提一下自己想到的makefile中的其他的一些符号以及它们的含义:
$:这个符号表示的是引用变量
-:嗯?一个减号,这是啥玩意,这个是告诉make命令你忽略所有的的错误,做你自己的事情就可以了,我们通常在使用rm和mkdir命令的时候前面会添加-符号
@:这个用来告诉make,你在执行这条命令的视乎不要将命令显示在标准输出上面,不要显示命令本身,只要显示它的结果就可以了。要低调行事。
Makefile文件中的变量和宏
说到宏,心底油然升起一种亲切感,就像在成都呆了两年之后发现了一家正宗的河南烩面馆一样。这样我想起了上次去都江堰的时候的坑爹经历,那次看见一件小饭馆上面有烩面,我就忍住内心的激动点了一份,我去,等上来之后我就晕了,老板,你以前吃过面没?面条和面片你都分不清呀。亲切归亲切,还是有区别的,这里的宏定义和C中是不一样 。各位看官请看下面定义:
# Define macros for name of compiler
CC = gcc
# Define a macr o for the CC flags
CCFLAGS = -D_DEBUG -g -m486
# A rule for building a object file
test.o: test.c test.h
$(CC) -c $(CCFLAGS) test.c
在上面的例子中,CC 和 CCFLAGS 就是 make 的变量,关于变量和宏,这个就和我们C语言中的概念不太一样了,在GUN的make中把这部分称为宏,在其他的Unix中就称为变量。实际上两者是同一个东东,在makefile中引用变量的时候通常前面需要添加$符号
Makefile中的主要预定义变量:(这部分内容是我直接从高手的博客中复制出来的)
预定义变量 含义
$* 不包含扩展名的目标文件名称。
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
$< 第一个依赖文件的名称。
$? 所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。
$@ 目标的完整名称。
$^ 所有的依赖文件,以空格分开,不包含重复的依赖文件。
$% 如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称
为 mytarget.so(image.o),则 $@ 为 mytarget.so,而 $% 为 image.o。
AR 归档维护程序的名称,默认值为 ar。
ARFLAGS 归档维护程序的选项。
AS 汇编程序的名称,默认值为 as。
ASFLAGS 汇编程序的选项。
CC C 编译器的名称,默认值为 cc。
CCFLAGS C 编译器的选项。
CPP C 预编译器的名称,默认值为 $(CC) -E。
CPPFLAGS C 预编译的选项。
CXX C++ 编译器的名称,默认值为 g++。
CXXFLAGS C++ 编译器的选项。
FC FORTRAN 编译器的名称,默认值为 f77。
FFLAGS FORTRAN 编译器的选项。
如何在Makefile中定义宏进行条件编译-- “-D”
在源代码里面如果这样是定义的:
#ifdef MACRONAME
//可选代码
#endif
那在makefile里面
gcc -DMACRONAME=MACRODEF
或者
gcc -DMACRONAME
这样就定义了预处理宏,编译的时候可选代码就会被编译进去了。
举例说明:
-Dmacro=string,等价于在头文件中定义:#define macro string。
-DTRUE=true,等价于在头文件中定义:#define TRUE true
-Dmacro,等价于在头文件中定义:#define macro 1,实际上也达到了定义:#define macro的目的。
-DLINUX,等价于:#define LINUX 1(与#define LINUX作用类似)。
--define-macro macro=string与-Dmacro=string作用相同。
这篇关于GNU中的make和makefile的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!