MakeFile详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

引用其它的Makefile-实例



有这样几个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

在大多数时候,由于源文件太多,编译生成的中间目标文 件太多,而在链接时需要明显地指出中间目标文件名,这
对于编译很不方便,所以,通常要给中间目标文件打个包,
在Windows 下这种包叫“库文件”(Library File),也就 是 .lib 文件,在UNIX 下,是Archive File,也就是 .a 文件。
定义变量和引用变量
变量的定义和应用与Linux环境变量一样,变量名 要大写,变量一旦定义后,就可以通过将变量名 用圆括号括起来,并在前面加上“$”符号来进行 引用。 变量的主要作用: 1、保存文件名列表 2、保存可执行命令名,如编译器 3、保存编译器的参数 变量一般都在makefile的头部定义。按照惯例, 所有的makefile变量都应该是大写。
者,通常是你需要告诉编译器头文件的所在位置,只要所有的语法正
确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应 该对应于一个中间目标文件(O 文件或是OBJ 文件)。
孙钦东
程序的编译和链接

链接时,主要是链接函数和全局变量。链接器并不管函数
所在的源文件,只管函数的中间目标文件(Object File)。



clean: -rm -f $(EXEC) *.elf *.gdb *.o
实例:Hello程序的MakeFile

CC 指明编译器的宏 EXEC 表示生成的执行文件名称的宏 OBJS 目标文件列表宏 LDFLAGS 连接参数宏 All: 编译主入口 Clean: 清除编译结果 Install: 将编译成功的可执行文件安装到系统目 录中,一般为/usr/local/bin目录
Makefile 是什么

GNU make是一个命令工具,是一个用来控制软件构建过程的自动 化管理工具。Make工具通过称为Makefile的文件来完成并自动维护 编译工作,由Richard Stallman 与Roland McGrath设计开发 。

Makefile是用于自动编译和链接的,一个工程有很多文件组成,每 一个文件的改变都会导致工程的重新链接,但是不是所有的文件都 需要重新编译,Makefile中记录有文件的信 息,在make时会决定 在链接的时候需要重新编译哪些文件。

make命令格式:make [-f Makefile] [option] [target]

#make target
#make
#make clean (伪目标)
Makefile 是什么

Makefile的宗旨就是:让编译器知道要编译一个文件
需要依赖其他的哪些文件。当那些依赖文件有了改变,
编译器会自动的发现最终的生成文件已经过时,而重
不要用“GNUmakefile”,这个文件是GNU的make识别的。有另外
一些make只对全小写的“makefile”文件名敏感,但是基本上来说, 大多数的make都支持“makefile”和“Makefile”这两种默认文件名。

当然,你可以使用别的文件名来书写Makefile,比如:
“Make.Linux”,“Make.Solaris”,“Make.AIX”等,如果要指定 特定的Makefile,你可以使用make的“-f”和“--file”参数,如: make -f Make.Linux或make --file Make.AIX。
实例:Hello程序的MakeFile



TOPDIR = ../ include $(TOPDIR)Rules.mak EXTRA_LIBS += EXEC = $(INSTALL_DIR)/hello OBJS = hello.o all: $(EXEC) $(EXEC): $(OBJS) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRA_LIBS) install: $(EXP_INSTALL) $(EXEC) $(INSTALL_DIR)
新编译相应的模块。

makefile带来的好处就是—“自动化编译”,一旦写
好,只需要一个make命令,整个工程完全自动编译,
极大的提高了软件开发的效率。
Makefile的文件名

默认的情况下,make命令会在当前目录下按顺序找寻文件名为 “GNUmakefile”、“makefile”、“Makefile”的文件,找到了解 释这个文件。在这三个文件名中,最好使用“Makefile”这个文件名, 因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好
其他预定义变量



AR 归档维护程序的名称,默认值为 ar。 ARFLAGS 归档维护程序的选项。 AS 汇编程序的名称,默认值为 as。 ASFLAGS 汇编程序的选项。 CC C 编译器的名称,默认值为 cc。 CFLAGS C 编译器的选项。 CPP C 预编译器的名称,默认值为 $(CC) -E。 CPPFLAGS C 预编译的选项。 CXX C++ 编译器的名称,默认值为 g++。 CXXFLAGS C++ 编译器的选项。 FC FORTRAN 编译器的名称,默认值为 f77。 FFLAGS FORTRAN 编译器的选项。
如:VPATH = src : ../headers
上面的的定义指定两个目录,“src”和“../headers”,make 会按照这个顺序进行搜 索。目录由“冒号”分隔。(当前目录是最高优先搜索的地方)

也可以使用指令vpath,与VPATH在使用上的区别是:vpath可以给不同类文件指定不
同的搜索目录。如: vpath %.c /src vpath %.h ../headers vpath %.c 表示清除所有vpath对%.c设置的搜索目录(后面不带路径)

3、变量的定义。在Makefile中我们要定义一系列的变量,变量一 般都是字符串,这个有点像C语言中的宏,当Makefile被执行时,
其中的变量都会被扩展到相应的引用位置上。
如:H: =foo.c

gcc -o foo.o $(H) (赋值可以用: =也可以直接用 =)
4、文件指示。其包括了三个部分,一个是在一个Makefile中引用 另一个Makefile,就像C语言中的include一样;另一个是指根据某 些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样; 还有就是定义一个多行的命令。
3个常用的预定义变量
1. $@ 2. $^ 3. $< 表示要生成的目标 表示全部的依赖文件 表示第一个依赖文件 bin/cn_work : obj/main.o obj/cn_work.o obj/fun.o gcc $^ -o $@ (命令一定要用以Tab开头) obj/cn_work.o : sources/cn_work.c gcc -I headers -c obj/main.o : obj/fun.o : clean: rm -f bin/cn_work file_o/*.o gcc -I headers -c gcc -I headers -c $< $< $< -o $@ -o $@ -o $@ gcc 的3个参数: 1. -o 指定目标文件 gcc sources/main.c -o bin/main 2. -c 编译的时候只生产目标文件不链接 gcc -c sources/main.c -o obj/main.o 3. -I 主要指定头文件的搜索路径 gcc -I headers -c main.c -o main.o sources/main.c sources/fun.c
孙钦东
gcc 参数

GCC –c 编译成把源文件目标代码,不做连接的动作。 –d 在执行过程中打印出所有的调试信息 –S 把源文件编译成汇编代码,不做汇编和连接的动作。 –E 只把源文件进行预处理之后的结果输出来。不做编译, 汇编,连接的动作。 –o file 指明输出文件名是file。 –g 把调试开关打开,让编译的目标文件有调试信息。 -O1 –O2 –O3 –O0,这些开关分别控制优化的强度,-O3 最强。
Makefile里有什么?

Makefile里主要包含了五个东西:显式规则、隐含规则、变量定义、
文件指示和注释。

1、显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由 Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
如: foo.o : foo.c defs.h
Makefile里有什么?

5、注释。Makefile中只有行注释,和UNIX的 Shell脚本一样,其注释是用“#”字符,这个就 像C/C++,Java中的“//”一样。

在Makefile中的命令,必须要以[Tab]键开始。
设置makefile中文件的搜索路径

在makefile中,可以通过给VPATH赋值来设置规则中目标文件和依赖文件的搜索目录。 Make首先搜索当前目录,如果未找到依赖的文件,make将按照VPATH中给的目录依 次搜索VPATH对makefile中所有文件都有效。
依赖关系
gcc -o foo.o foo.c 生成目标的方法(方式)

2、隐含规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让 我们比较粗糙地简略地书写Makefile,这是由make所支持的。 如: foo.o : foo.c (.o文件自己推导出同名的依赖文件.c.)
Makefile里有什么?




程序的编译和链接

要得到最后可执行的程序,首先要把源文件编译成中间代码文件,在 Windows 下也就是 .obj 文件,UNIX\Linux 下是 .o 文件,即 Object File,编译(compile)。再把大量的Object File 合成执行文件,链 接(link)。

编译时,编译器需要的是语法正确,函数与变量的声明正确。对于后
MakeFile解读
GCC编译的四个步骤

预处理-----> 编译 ----> 汇编 ----> 链接 1.预处理(Pre-processing),生成预编译文件(.i文件): gcc –E hello.c –o hello.i 2.编译(Compiling),生成汇编代码(.s文件): gcc –S hello.i –o hello.s 3.汇编(Assembling),生成目标文件(.o文件): gcc –c hello.s –o hello.o 4.链接(Link),生成可执行文件: gcc hello.o –o hello 整个过程如果想一步到位: gcc hello.c -o he

$* 不包括扩展名的目标文件名称 $+ 所有的依赖文件,以空格分开,并以出现 的先后为序,可能包含重复的依赖文件 $< 第一个依赖文件的名称 $? 所有的依赖文件,以空格分开,这些依赖 文件的修改日期比目标的创建日期晚 $@ 目标的完整名称 $^ 所有的依赖文件,以空格分开,不包含重 复的依赖文件 $% 如果目标是归档成员,则该变量表示目标 的归档成员名称
引用其它的Makefile

在Makefile使用include关键字可以把别的Makefile包含进来,这很像C语言的 #include,被包含的文件会原模原样的放在当前文件的包含位置。include的 语法是:

include <filename> filename可以是当前操作系统Shell的文件模式(可以保含路径和通配符) 在include前面可以有一些空字符,但是绝不能是[Tab]键开始。include和 <filename>可以用一个或多个空格隔开。
相关文档
最新文档