快速读懂 makefile
转载自 怎么看懂和编写makefile
转载自 跟我一起写Makefile
Makefile最基本的组成
target: dependencies |
target
可以是object文件,也可以是可执行文件,也可以是target关键字。
可以一次写多个文件作为同一批次的target。dependencies
有的是源文件,有的是链接文件,如果没有的话可以不写;
想要编target必须先准备好dependencies。clean
是一个特殊的target,一般要做的是rm清理工作;make
命令在执行的时候会检查目标文件是否存在, 并比较target文件和dependencies文件的修改日期,
如果存在更新的dependencies文件,那么对应的command就会执行,否则的话就不执行,还使用已存在target文件。command
必须要以TAB
来对齐, 一般会是gcc/g++的编译命令;- 细化到模块一般会有若干个分支target,形成层级的target依赖关系。
举个例子:
# 编译和链接一起做了, 看不到中间的.o目标文件 |
隐形规则和变量
为了使得makefile的内容尽量少一些废话,GNU为makefile加入了一些约定的规则。
- 如果
target
文件的名称是aa.o
,那么make会主动的把同名的源代码文件(如aa.c
,aa.cpp
)加入到依赖中去。 target
和dependencies
处: 用%
通配任意的非空字符串command
处:$@
目标文件,$<
依赖1,$^
所有的依赖文件,$?
比目标文件新的依赖. 这三个叫自动变量.- 变量在定义或被赋值时不加$(),在使用其值时要加
$()
- 常用
$(CC)
来代替具体的编译器,比如CC=g++
- 常用
$(CFLAGS)
来代替C语言编译选项,比如CFLAGS=-c -Wall
还会指定头文件include路径,比如CFLAGS+=-I/usr/include
- 常用
$(LDFLAGS)
来指定库文件lib路径,比如LDFLAGS+=-L/usr/lib
- 常用
$(LDLIBS)
来指定要链接的库名称,比如LDLIBS+=-llibname
修改上面的例子:
# 先使用通配符 % 及自动变量 |
伪目标
.PHONY
经常被用来作为伪目标。 它的使用目的是这样的:
因为当类似clean这样的target关键字作为target并且没有依赖文件时,
假如目录下有一个文件也叫clean时,make clean命令则会以为我想编clean这个目标文件,
恰好clean文件又不会比依赖文件更旧,所以下面的command就不会被执行。
现在我们用.PHONY作为target,clean作为依赖。
这就是告诉make,clean它是一个target,而不是一个普通的文件。
加入 clean 的例子:
hello: hello.o a.o # 执行文件hello, 依赖于.o文件 |
文件引用和条件判断
- 如果makefile中引入其他makefile, 使用
include
即可 - 条件语句的基本结构一般由
ifeq
else
endif
三个关键字组成
include another.mk # 调用 another.mk |
使用函数
函数调用,很像变量的使用,也是以“$”来标识的,有两种语法, 如下:
$(<function> <arguments>) |
还是来看一个示例:
comma := , |
$(bar)
调用了函数一个函数.- 函数 :
$(subst <from>,<to>,<text>)
, 相当于c语言的subst(from, to, text)
- 参数from:
$(comma)
的值是一个逗号 - 参数to :
$(space)
使用了$(empty)
定义了一个空格 - 参数text:
$(foo)
的值是 “a b c”
- 函数 :
- 这个函数是把$(foo)中的空格替换成逗号,所以$(bar)的值是“a,b,c”。
- 这是一个替换函数
- 第一个参数是被替换字串
- 第二个参数是替换字串
- 第三个参数是替换操作作用的字串
Makefile 支持的函数有限, 详情可参考 跟我一起写Makefile:使用函数
转载自 怎么看懂和编写makefile
转载自 跟我一起写Makefile