Makefile笔记整理
2016-01-04 19:08
232 查看
GCC常用选项
-DMACRO选项-DOS_LINUX将宏定义OS_LINUX
-Idir
添加头文件搜索目录dir
-Ldir
添加链接库搜索目录dir。gcc优先使用共享程序库
-static
仅选用静态程序库进行链接,如果一个目录中静态库和动态库都存在,则仅选用静态库
-g
包括调试信息
-On
优化程序,n代表优化级别,n常为2
-Wall
打开警告信息
Makefile规则基本格式
[code]TARGET...: DEPENDEDS... COMMAND ... ...
TARGET:规则定义的目标
DEPENDEDS:执行规则锁必须依赖的条件(DEPENDEDS也可以是某个TARGET,形成嵌套)
COMMAND:规则所执行的命令
Makefile中常用变量及含义
变量名 | 含义 | 默认值 |
---|---|---|
AR | 生成静态库文件的程序名称 | ar |
AS | 汇编编译器的名称 | as |
CC | C语言编译器的名称 | cc |
CPP | C语言预编译器的名称 | $(CC) -E |
CXX | C++语言编译器的名称 | g++ |
FC | FORTRAN语言编译器的名称 | f77 |
RM | 删除文件程序的名称 | rm -f |
ARFLAGS | 生成静态库库文件程序的选项 | \ |
ASFLAGS | 汇编语言编译器的编译选项 | \ |
CFLAGS | C语言编译器的编译选项 | \ |
CPPFLAGS | C语言预编译的编译选项 | \ |
CXXFLAGS | C++语言编译器的编译选项 | \ |
FFLAGS | FORTRAN语言编译器的编译选项 | \ |
Makefile中的自动变量
变量 | 含义 |
---|---|
$* | 表示目标文件的名称,不包含目标文件的扩展名(GUN make特有,其他make不一定支持) |
$+ | 所有依赖项的集合,不会去除重复的依赖项 |
$< | 表示依赖项中第一个依赖文件的名称 |
$? | 依赖项中,所有目标文件时间戳晚的依赖文件,以来稳健之间以空格分开 |
$@ | 目标项中目标文件的名称 |
$< | 依赖项中,所有不重复的依赖文件,这些文件之间以空格分开 |
Makefile中的VPATH变量
使用方法:[code]VPATH=add:sub(加入add和sub搜索路径)
VPATH 只控制.c/.cpp的查找路径(将.c/.cpp文件所在文件夹添加到VPATH后只用写文件名gcc即可查找到文件),对于.h文件,需要使用-I./header。
Makefile中的= := ?= +=赋值运算符
= 是最基本的赋值:= 是覆盖之前的值
?= 是如果没有被赋值过就赋予等号后面的值
+= 是添加等号后面的值
1“=”
make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:
x = foo
y = $(x) bar
x = xyz
在上例中,y的值将会是 xyz bar ,而不是 foo bar 。
2“:=”
“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。
x := foo
y := $(x) bar
x := xyz
在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。
Makefile中的.PHONY
[code].PHONY:romfs # .PHONY修饰romfs只有规则,没有依赖 romfs
[code]all:main1 main2 clean main1: main1.c @gcc main1.c -o main1 main2: main2.o @gcc main2.o -o main2 main2.o: main2.c @gcc -c main2.c clean: @rm -f main2.o
但是当我们make之后main2.o仍然存在,怎么回事呢makefile中的all和.PHONY的作用
原来这里的目标clean没有任何依赖,make执行时认为这已经到“根上”了(就是认为磁盘上有clean,就像main2.c),将其忽略(尽管它有规则)。
关键字.PHONY可以解决这问题,告诉make该目标是“假的”(磁盘上其实没有clean),这时make为生成这个目标就会将其规则执行一次。.PHONY修饰的目标就是只有规则没有依赖。
加上一句.PHONY:clean即可:
[code]all:main1 main2 clean main1: main1.c @gcc main1.c -o main1 main2: main2.o @gcc main2.o -o main2 main2.o: main2.c @gcc -c main2.c .PHONY:clean clean: @rm -f main2.o
Makefile中的@
makefile中@是不打印命令本身的意思 ,以下Makefile执行make clean时终端不会打印rm -f main2.o的信息。[code]clean: @rm -f main2.o
递归make
递归调用的方式make可以递归调用每个子目录中的Makefile。我们可以用如下方式编译add中的文件:
[code]add: cd add && $(MAKE)
等价于:
[code]add: $(MAKE) -C add
上面两个例子都是先进入子目录下add中,然后执行make命令。
总控Makefile
调用“$(MAKE) -C”的Makefile叫做总控Makefile。如果总控Makefile中的一些变量需要传递给下层的Makefile,可以使用export命令,如:
[code]export OBJSDIR=./objs
Makefile中的函数
获取匹配模式的文件名wildcard这个函数功能是查找当前目录下所有符合迷失PATTERN的文件名,其返回值是以空格分割的、当前目录下的所有符合模式PATTERN的文件名列表。原型如下:
[code]$(wildcard PATTERN)
例如,如下模式返回当前目录下所有扩展名为.c的文件列表
[code]$(wildcard *.c)
模式替换函数patsubst
这个函数的功能是查找字符串text中按照空格分开的单词,将符合模式pattern的字符串替换成replacement。pattern中的模式可以使用通配符,%代表0到n个字符,当pattern和replacement中都有%时,符合条件的字符将被replacement中的替换。函数的返回值是替换后的新字符串。原型如下:
[code]$(patsubst pattern,replacement,text)
返回值:例如需要将.c文件替换成.o文件可以使用如下模式
[code]$(patsubst %.c,%.o,$(wildcard *.c))
输出的字符串将当前扩展名为.c的文件替换成扩展名为.o的文件列表
循环函数foreach
函数原型:
[code]$(foreach VAR,LIST,TEXT)
foreach将LIST字符串中的一个人空格分隔符的单词,先传给临时变量VAR,然后执行TEXT表达式,TEXT表达式处理结束后输出。其返回值是空格分割表达式TEXT的计算结果。
例如,对于存在add和sub的两个目录,设置DIRS为“add sub ./”包含目录add、sub和当前目录。表达式
$(wildcard$(dir)/*.c),可以去除目录add和sub及当前目录中的所有扩展名为.c的文件。
[code]DIRS = sub add ./ #查找所有目录下的扩展名为.c的文件,复制给变量FILES FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
相关文章推荐
- [漫画]程序员的日常生活 58
- 记录遇到的各种rails报错
- mysql不能使用localhost登录
- 通信服务器编程中的一个大坑
- poj1797
- python setup.py install 和python setup.py develop的区别
- [漫画]程序员的日常生活 57
- [漫画]程序员的日常生活 56
- 常用表格
- jQuery $.extend() 和 $.fn.extend() 用法
- 3个步骤,让你的手机上网速度飙升--转载
- Linux 1
- HTML DOM 对象_HTML 对象_JavaScript 对象_Browser 对象
- angular路由
- Linux环境下C程序开发
- 命令模式【Command Pattern 】
- (实训第一天)Linux系统常用命令以及基本概念
- 这货把360安全路由P1、极路由3、全新小米路由器都干翻了
- 七牛对用户使用webp图片格式的使用建议
- .NET学习(十二)页面跳转