原创 Makedile之三 Makefile 总述

2009-6-26 11:17 2408 8 8 分类: MCU/ 嵌入式

#Makefile 总述

一. Makefile里有什么?
    Makefile里主要包含了五个东西: 显式规则, 隐晦规则, 变量定义, 文件指示和注释.
    
    1. 显式规则. 显式规则说明如何生成一个或多个的目标文件.这是由Makefile的书写者明显
指出要生成的文件, 文件的依赖文件, 生成的命令.
    2. 隐晦规则. 由于make有自动推导的功能,所以隐晦规则可以让我们比较粗糙地简略地书写
Makefile, 这是由make所支持的.
    3. 变量的定义. 在Makefile中我们要定义一系列的变量, 变量一般都是字符串,这个有点象
C语言中的宏, 当Makefile被执行时, 其中的变量都会被扩展到相应的引用位置上.
    4. 文件指示. 其包括了三个部分: 一个是在一个Makefile中引用另一个Makefile, 就像C语
言中的include一样; 另一个是指根据某些情况指定Makefile中的有效部分, 就像C语言中的预编
译#if一样; 还有就是定义一个多行的命令.
    5. 注释. Makefile中只有行注释, 和UNIX的Shell脚本一样, 其注释是用#字符, 这个就像C
中的 "//" 一样. 如果你要在你的Makefile中使用#字符, 可以用反斜框进行转义, 如: "\#" .
    最后, 值得一提的是, 在Makefile中的命令, 必须要以Tab键开始.

二. Makefile的文件名
    默认的情况下, make命令会在当前目录下按顺序找寻文件名为GNUmakefile, makefile,
Makefile的文件, 找到了解释这个文件. 在这三个文件名中, 最好使用Makefile这个文件名, 因
为, 这个文件名第一个字符为大写, 这样有一种显目的感觉. 最好不要用GNUmakefile,这个文件
是GNU的make识别的. 有另外一些make只对全小写的makefile文件名敏感, 但基本上来说,大多数
的make都支持makefile和Makefile这两种默认文件名.
    当然, 你可以使用别的文件名来书写Makefile, 比如: Make.Linux, Make.Solaris等, 如果
要指定特定的Makefile, 你可以使用make的- f和 "--file" 参数, 如:
    make -f Make.Linux 或 make --file Make.AIX

三. 引用其它的Makefile
    在Makefile使用include关键字可以把别的Makefile包含进来, 这很像C语言的#include, 被
包含的文件会原模原样的放在当前文件的包含位置. include的语法是:
include <filename>
    filename可以是当前操作系统Shell的文件模式(可以保含路径和通配符), 在include前面可
以有一些空字符, 但是绝不能是Tab键开始. include和<filename>可以用一个或多个空格隔开.
举个例子, 你有这样几个Makefile: a.mk, b.mk, c.mk, 还有一个文件叫foo.make, 以及一个变
量$(bar), 其包含了e.mk和f.mk, 那么, 下面的语句:

include foo.make *.mk $(bar)

等价于:

include foo.make a.mk b.mk c.mk e.mk f.mk

make命令开始时, 会把找寻include所指出的其它Makefile, 并把其内容安置在当前的位置.就好
像C的#include指令一样. 如果文件都没有指定绝对路径或是相对路径的话,make会在当前目录下
首先寻找, 如果当前目录下没有找到, 那么, make还会在下面的几个目录下找:
1. 如果make执行时, 有 "-I" 或 "--include-dir" 参数, 那么make就会在这个参数所指定的目
录下去寻找.
2. 如果目录<prefix>/include(一般是: /usr/local/bin或/usr/include)存在的话,make也会去
找.
3. 如果有文件没有找到的话, make会生成一条警告信息, 但不会马上出现致命错误.它会继续载
入其它的文件, 一旦完成makefile的读取, make会再重试这些没有找到, 或是不能读取的文件,
如果还是不行, make才会出现一条致命信息. 如果你想让make不理那些无法读取的文件, 而继续
执行, 你可以在include前加一个减号 "-" . 如:

-include <filename>

其表示, 无论include过程中出现什么错误, 都不要报错继续执行.和其它版本make兼容的相关命
令是sinclude, 其作用和这一个是一样的.


四. 环境变量MAKEFILES
    如果你的当前环境中定义了环境变量MAKEFILES, 那么,make会把这个变量中的值做一个类似
于include的动作. 这个变量中的值是其它的Makefile, 用空格分隔. 它和include不同的是, 从
这个环境变中引入的Makefile的 "目标" 不会起作用,如果环境变量中定义的文件发现错误,make
也会不理.
    建议不使用这个环境变量, 因为该变量一被定义, 那么当你使用make时, 所有的Makefile都
会受到它的影响!

五. make的工作方式
    GNU的make工作时的执行步骤入下:
    1. 读入所有的Makefile
    2. 读入被include的其它Makefile
    3. 初始化文件中的变量
    4. 推导隐晦规则, 并分析所有规则
    5. 为所有的目标文件创建依赖关系链
    
    6. 根据依赖关系, 决定哪些目标要重新生成
    7. 执行生成命令
    其中, 1~5 步为第一个阶段, 6~7 为第二个阶段.
    第一个阶段中, 如果定义的变量被使用了, make会把其展开在使用的位置. 但make并不会完
全马上展开, 只有该变量在依赖关系规则中使用时才会在其内部展开.


【2006-12-23】

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /3 下一条