您的位置:首页 > 编程语言 > C语言/C++

MakeFile的学习

2013-04-16 14:31 162 查看
因为在使用C/C++的时候,会产生很多的.c/.cpp和.h文件,通常我们在使用platform进行编程时会通过预编译的命令将他们连接起来,但是有时对大型的工程项目,这样的方式并不灵活,也不利于维护,所以考虑使用MakeFile来进行文件的连接工作。

MakeFile学习:

一个小例子来说名MakeFile的构成和执行方式:

1. # makefile
2. # this is a example of make file
3. all:a1 a2
4. @echo this is all!
5. a1:
6. @echo this is a1!
7. a2:
8. @echo this is a2!
上面MakeFile的运行结果是:
this is a1!

this is a2!

this is all!

代码详解:

第1 2行是注释部分。在MakeFile中用#作为注释,但是注意#不能用在其他语句之后,否则会出错。

第3行就是规则开始的部分。
all: a1     a2一行中all是规则的名字,通常是目标明(target)。

一条规则可以有不止一个名字,像上面的这行,也可以把它写成all  all2:a1   a2。这时,规则就有了两个名称—all和all2。当然,还可以有更多,都看自己。第5 7两行也是规则的开始部分。

在“:”之后的,就是依赖项。在这一行里,依赖项有两个,分别是a1和a2。这些依赖项可以是其它的规则名(目标名),也可以是文件名。依赖和目标之间的关系就是“依赖关系”。一条规则中,可以有零个(像后面的两条规则)、一个或多个依赖。

第4行的@echo  this   is   all!是命令行。它是执行all规则时要执行的命令。要注意的是,一条规则内的命令要以tab为一行的起始,以表示命令是属于一个规则。一条规则也可以有多条命令,每条命令占一行(要以tab开头)。至于可以使用哪些命令,这完全取决于使用的OS和SHELL。
当执行make时,它会找到第一条规则。然后,make就会检查依赖和目标之间的关系。如果目标比依赖旧,就执行规则,以更新目标。执行完规则就结束。

如何判定目标和依赖的新旧呢?

1 如果目标(文件)不存在,目标的时间就为0;

2 如果目标(文件存在),目标的时间就为文件的修改时间。如果依赖项是一条规则,就执行依赖的规则(这里是一个递归),然后依赖的时间就是当前最新时间;

3 如果是一个存在的文件,就为文件的修改时间,否则就报错。

4
有一点特殊的是,在没有依赖项时,依赖的时间为1。

之后,就可以比较目标和依赖之间的关系。
在这个例子中,make先找到规则“all”,发现目标不存在,所以目标的时间为0;然后再查找依赖“a1”,结果“a1”不存在,所以它的时间为0;于是,执行规则“a1”,而“a1”没有依赖,它的依赖时间为1;1>0,所以,执行规则“a1”。然后返回规则“all”,再检查依赖“a2”。“a2”执行过程同“a1”。这时,“all”的目标时间为0,依赖时间为最新时间。于是,执行规则“all”的命令。
当然,也可以指定一条规则让make执行,比如:make  a1这个命令就是告诉make程序不去找第一条规则,而是规则“a1”来执行。并且还可以一次执行多条规则,比如:执行make   a1  a2就会连续执行“a1”、“a2”两条规则。

==============================================
依赖的基本写法如下:

Target:Dependence

Command

==============================================

Target可以是文件名。Dependence可以是其它的target名或文件名。Command就是操作系统所运行的命令行。
变量
一个make规则文件有这些内容就已经基本可以工作了。可是,当在编译一个程序时,如果有些内容要反复用到,每次都要写一长串的话,是很麻烦的。于是,make就引入了宏这个概念(其实也可以看成简单的脚本语言)。
宏变量的定义如下:

var1   =   this   is   a   macro   demo!

var1就是变量名,它的值就是“this   is   a   macro  demo!”
如果我们要使用这个变量的值,那只有通过$这个运算符才行—$(var1)代表的就是“this   is   a  macro   demo!”。
如下makefile

1.   var1   =   this   is   a   macro  demo!

2.   all:

3.       @echo   $(var1)
结果输出:

this   is   a   macro   demo!
用户在执行命令行时也可以定义宏变量。其形式如下:

make   all   var1=”this   is   a  test”
执行结果为:

this   is   a   test
不仅可以使用自定义变量,还可以通过这种方式使用系统环境变量。这样可以大大方便使用。如下makefile

1.   all:

2.       @echo   $(WINDIR)
执行结果为:

C:\WINDOWS
(注意:makefile中的变量是大小写敏感的)

下面介绍makefile文件的一些内置变量:

==========================================

$@代表规则中的目标名(也就是规则名)。

$<代表规则中的依赖项目。注意,它只代表规则所有依赖项目中的第一项!

其它还有:

$^代表规则中所有的依赖项目。

$?代表规则中时间新于目标的依赖项目。

不仅如此,还可以给这些特殊的变量加一些限制。

如:

在规则

debug/out.exe :  out.obj中,$@代表debug/out.exe,而$(@D)代表目录名debug,$(@F)代表文件名out.exe。其它如$(<D)、$(<F)、$(^D)、$(^F)、$(?D)、$(?F)与此类似。

=============================================

举个例子说明,下面是原始makefile文件内容:

==============================================

myprog : foo.o bar.o

gcc foo.o bar.o -o myprog

foo.o : foo.c foo.h bar.h

gcc -c foo.c -o foo.o

bar.o : bar.c bar.h

gcc -c bar.c -o bar.o

==============================================

用变量代替后的文件内容:

==============================================

OBJS = foo.o bar.o

CC = gcc

CFLAGS = -Wall -O -g

myprog : $(OBJS)

$(CC) $^ -o $@

foo.o : foo.c foo.h bar.h

$(CC) $(CFLAGS) -c $<-o $@

bar.o : bar.c bar.h

$(CC) $(CFLAGS) -c $<-o $@
CFLAGS用于自编译
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Makefile 灵活使用 C++ C