makefile文件概述
2009-09-10 17:13
183 查看
GNUmake的主要工作是读一个描述文件,通过该文件描述的目标文件与源文件之间的依赖关系,从项目源代码中生成最终可执行文件和其他非源代码文件。编写makefile文件就是描述这种关系,执行make时,如果目标文件的日期至少比它的一个依赖文件日期早,make就会执行相应的命令,更新目标文件。Make命令本身可带有四种参数:标志,宏定义,描述文件名和目标文件名。其标准形式为:Make [flags] [macro definitions] [targets]-f file:指定file文件为描述文件,如果没有这个参数,则系统默认当前目录名下为makefile或Makefile的文件为描述文件。在Linux中,GNUmake工具在当前工作目录中按照GNUmakefile,makfile,Makefile的顺序搜索描述文件。一个makefile主要含有一系列的规则,如下: target ... : requisites ...
command
...
...第一行称为规则,第二行是执行规则的命令,必须要以TAB键开始。target是一个目标文件,可以是Object File,也可以是执行文件;requisites是生成这个target的所有依赖文件;command是完成这个操作的shell命令。
target也可以当作伪目标,此时command为空,用于一个项目中要生成多个相互独立的目标文件。这些需要生成的独立的目标文件全部当作target伪目标的依赖文件,却没有实际生成它的命令,但make依然会试图更新所有依赖文件,这样就达到了预期的目的。target还可以是一个标签,当其作为标签时,冒号后面不写依赖文件。所以这时它不是一个文件,只不过是一个动作的名字,像C语言中的lable一样,make不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。利用这个特性,可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,备份,删除中间文件等等,需要完成这些操作时,执行一下“make (lable)”就可以了。
宏定义宏定义的作用是为了简化makefile文件,也使得其更容易理解。定义一个宏,任起一行,格式:“宏名=设定宏的值”,引用时用$(宏名)或${宏名},其作用与C语言的define是一样的,就是符号替换。几个常用的内部变量:$@:当前规则的目标文件$<:当前规则依赖文件列表中的第一个依赖文件$?:所有的修改日期比当前规则的目标文件的创建日期更晚的依赖文件,只有显式规则时才会被使用。$*:当前规则中目标文件和依赖文件共享的文件名,不含扩展名。$^:整个依赖文件的列表。如果一条语句过长,将符号"\"放在右边界,将下一行的内容作为这句的续行;宏定义中符号"+="的意思是在原来的基础上添加新的内容。
隐含规则隐含规则这个东西看了一段时间,比较费解。简单来说,就是makefile里没有写出生成目标的规则,make自己会去库中寻找生成它的规则。这些规则写在库中,一般为“后缀规则”,类似"filename.o是由filename.c生成的"。比如: main : main.o operate.o
gcc –o main main.o operate.o这个makefile中并没有写出如何生成main.o和operate.o这两个目标的规则和命令。系统会寻找main.c和operate.c按照规则生成这两个目标,如果找不到就会报错。(这里简化了隐含规则,当然还有其他生成.o文件的规则,例如.p生成.o)还有其他比较深入的东西,暂时还没有遇到,所以不说了,从网上下载了《GNUmake中文手册》,感觉挺不错,留个记号,这个会是以后需要深入学习的地方。
用最简单的程序,小试牛刀一番,本来想试下流水灯的,无奈Linux下汇编不会,所以还是那个Hello World,把它拆成几个程序文件来写,用make来编译它。
/*operate.h*/
#ifndef _operate_h
#define _operate_hvoid operate();#endif
/* main.c */
#i nclude "operate.h"
int main()
{
operate();return 0;
}
/*operate.c*/
#i nclude <stdio.h>
void operate()
{
printf("Hello World!\n");
}
/* maikfile1 */main : main.o operate.o
gcc -o main main.o operate.o
main.o : main.c operate.h
gcc -c main.c operate.h
operate.o : operate.c
gcc -c operate.c
clean :
rm main main.o operate.o
/* maikfile2*/main : main.o operate.o
gcc -o main main.o operate.o
clean :
rm main main.o operate.o
用makefile1编译,屏幕依次显示上面的三条编译指令,然后生成可执行文件main,./main可以看到输出"Hello World!",执行make clean删除编译过程中生成的文件。
用makefile2编译,用到了隐含规则,同样可以达到相同的效果,屏幕显示
CC -c -o main.o main.c
CC -c -o operate.o operate.c <--可见隐含的命令是这样的
接下来,就练习编译一下uclinux的内核,makefile先接受这么多吧! 转载处 http://blog.21ic.com/user1/5930/archives/2008/62172.html
command
...
...第一行称为规则,第二行是执行规则的命令,必须要以TAB键开始。target是一个目标文件,可以是Object File,也可以是执行文件;requisites是生成这个target的所有依赖文件;command是完成这个操作的shell命令。
target也可以当作伪目标,此时command为空,用于一个项目中要生成多个相互独立的目标文件。这些需要生成的独立的目标文件全部当作target伪目标的依赖文件,却没有实际生成它的命令,但make依然会试图更新所有依赖文件,这样就达到了预期的目的。target还可以是一个标签,当其作为标签时,冒号后面不写依赖文件。所以这时它不是一个文件,只不过是一个动作的名字,像C语言中的lable一样,make不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。利用这个特性,可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,备份,删除中间文件等等,需要完成这些操作时,执行一下“make (lable)”就可以了。
宏定义宏定义的作用是为了简化makefile文件,也使得其更容易理解。定义一个宏,任起一行,格式:“宏名=设定宏的值”,引用时用$(宏名)或${宏名},其作用与C语言的define是一样的,就是符号替换。几个常用的内部变量:$@:当前规则的目标文件$<:当前规则依赖文件列表中的第一个依赖文件$?:所有的修改日期比当前规则的目标文件的创建日期更晚的依赖文件,只有显式规则时才会被使用。$*:当前规则中目标文件和依赖文件共享的文件名,不含扩展名。$^:整个依赖文件的列表。如果一条语句过长,将符号"\"放在右边界,将下一行的内容作为这句的续行;宏定义中符号"+="的意思是在原来的基础上添加新的内容。
隐含规则隐含规则这个东西看了一段时间,比较费解。简单来说,就是makefile里没有写出生成目标的规则,make自己会去库中寻找生成它的规则。这些规则写在库中,一般为“后缀规则”,类似"filename.o是由filename.c生成的"。比如: main : main.o operate.o
gcc –o main main.o operate.o这个makefile中并没有写出如何生成main.o和operate.o这两个目标的规则和命令。系统会寻找main.c和operate.c按照规则生成这两个目标,如果找不到就会报错。(这里简化了隐含规则,当然还有其他生成.o文件的规则,例如.p生成.o)还有其他比较深入的东西,暂时还没有遇到,所以不说了,从网上下载了《GNUmake中文手册》,感觉挺不错,留个记号,这个会是以后需要深入学习的地方。
用最简单的程序,小试牛刀一番,本来想试下流水灯的,无奈Linux下汇编不会,所以还是那个Hello World,把它拆成几个程序文件来写,用make来编译它。
/*operate.h*/
#ifndef _operate_h
#define _operate_hvoid operate();#endif
/* main.c */
#i nclude "operate.h"
int main()
{
operate();return 0;
}
/*operate.c*/
#i nclude <stdio.h>
void operate()
{
printf("Hello World!\n");
}
/* maikfile1 */main : main.o operate.o
gcc -o main main.o operate.o
main.o : main.c operate.h
gcc -c main.c operate.h
operate.o : operate.c
gcc -c operate.c
clean :
rm main main.o operate.o
/* maikfile2*/main : main.o operate.o
gcc -o main main.o operate.o
clean :
rm main main.o operate.o
用makefile1编译,屏幕依次显示上面的三条编译指令,然后生成可执行文件main,./main可以看到输出"Hello World!",执行make clean删除编译过程中生成的文件。
用makefile2编译,用到了隐含规则,同样可以达到相同的效果,屏幕显示
CC -c -o main.o main.c
CC -c -o operate.o operate.c <--可见隐含的命令是这样的
接下来,就练习编译一下uclinux的内核,makefile先接受这么多吧! 转载处 http://blog.21ic.com/user1/5930/archives/2008/62172.html
相关文章推荐
- Android.mk文件语法详述 1. 概述 Android.mk文件是用来描述build system(编译系统)的,更准确的说:该文件是一个微型的GNU Makefile片段,将
- Kconfig和Makefile文件语法概述
- makefile文件详解二--概述
- makefile文件详解一--概述
- Fortran含Module情况下Makefile文件书写
- Configure,Makefile.am, Makefile.in, Makefile文件之间关系
- Linux文件---标准IO概述
- 小何讲Linux: Linux中文件及文件描述符概述
- AMR音频编码器概述及文件格式分析
- 在VC里如何用Makefile文件编译?
- [转]Linux学习笔记——例说makefile 头文件查找路径
- android编译系统的makefile文件Android.mk写法如下
- 电子书makefile文件分析之all的用法
- 一个makefile调用多个makefile 文件示例
- Symbian OS中项目定义文件(mmp)概述
- 例解 autoconf 和 automake 生成 Makefile 文件
- make工具与Makefile文件
- 对elf文件连接的理解(一)-重定位概述
- MakeFile文件的书写规范
- makefile编译一个目录下的文件