Makefile基本语法
1.make工程管理器
- make是一个工程管理器,类似于kile、iar等,只不过make没有图形界面,也不提供代码编辑功能。
- Make工程管理器也就是个“自动编译管理器”,它能够根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件的内容来执行大量的编译工作。
Make将只编译改动的代码文件,而不用完全编译
makefile
Makefile是Make读入的唯一配置文件
makefile基本结构
- 由make工具创建的目标体(target) ,通常是目标文件或可执行文件
- 要创建的目标体所依赖的文件(dependency file)
- 创建每个目标体时需要运行的命令(command)
注意:命令行前面必须是一个” TAB键”,否则编译错误为:*** missing
separator. Stop.
makefile语法示例1:
1 | # Makefile格式 |
makefile语法示例2:
1 | test: f1.o f2.o # make从第一行开始执行 |
1.make不带参数默认从makefile的第一行开始执行语句,make发现需要生成test的目标,而生成test需要的依赖三个文件f1.o、f2.o和main.o,所以make需要先得到这三个依赖文件,会去先执行生成这三个目标文件的语句,最后通过f1.o、f2和main.o依赖文件生成test这个目标文件。
2.make带参数,例如:make clean、make f1.o则跳过其它目标生成直接执行clean这个目标。
3.伪目标:为防止目标名字和文件名字重名。
make执行步骤:
自动编译原则:当依赖文件比目标文件的时间戳新,或者只有依赖文件没有目标文件,就需要通过依赖文件(重新)生成目标文件。
检查makefile是否有语法错误:
只打印要执行的命令,但不执行这些命令:make -n
make识别的文件名字:makefile、Makefile、MAKEFILE不区分字母大小写
2.makefile语法中的变量
- 创建变量的目的 : 用来代替一个文本字符串,减少语法出错率,增加可读性
1.系列文件的名字
2.传递给编译器的参数
3.需要运行的程序
4.需要查找源代码的目录
5.你需要输出信息的目录
6.你想做的其它事情。
- 变量定义的两种方式
1.递归展开方式:VAR=var
2.简单方式:VAR: =var
- 变量使用
$(VAR)
makefile中的变量类似与C语言的宏,起简单的替换作用,用$$表示使用$变量
- 使用变量的makefile示例:
1 | OBJS = f1.o f2.o # 定义一个变量后面就可以通过$(OBJS)来代替f1.o f2.o |
- 递归展开的变量VAR=var:变量可以先使用再定义
例子:
1 | foo= S(bar) |
优点: 它可以先使用后定义。
缺点: 不能对该变量进行任何扩展。例如:
CFLAGS = $(CFLAGS) -O 会造成死循环
- 简单方式定义变量VAR: = var :更接近C语言中的变量
例子:
1 | m:=mm |
简单定义变量的方式更适合在大的编程项目中使用,因为它更像我们一般的编程语言
- 用?=定义变量:
makefile中需要使用别人写的makfile时会用到,不知道一个变量是否被别的makefile已经定义了。
1 | dir:= /foo/bar |
不使用?=上面代码等价代码:
1 | ifeq ($(origin FOO), undefined) |
- makefile的变量类似于C语言的字符串:可以对一个变量追加内容
1 | # 为变量添加值 |
- make管理器预定义变量:自己也可以重新定义这些变量的值
变量带默认值:
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 编译器的选项,无默认值。
- 自动变量:在某个特定的语句中变量自动代表相应的内容
$* 不包含扩展名的目标文件名称
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
$< 第一个依赖文件的名称
$? 所有时间戳比目标文件晚的的依赖文件,并以空格分开
$@ 目标文件的完整名称
$^ 所有不重复的目标依赖文件,以空格分开
$% 如果目标是归档成员,则该变量表示目标的归档成员名称
带自动变量、预定义变量、自定义变量的示例:
1 | OBJS= f1.o f2.o # OBJS是自定义变量 |
- makefile中的环境变量:
1.make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量。
2.如果用户在Makefile中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量。
- make命令的选项参数
-C dir读入指定目录下的Makefile,此时不再makefile所在目录,例如:make -C /dir/test_dir
-f file读入当前目录下的file文件作为Makefile,任意文件名的文件当做make的配置文件,例如:make -f makefile-debug
-i 执行make过程中如果出现错误,忽略本条错误继续执行makefile后面的不受本条错误影响的其它命令,例如:make -i
-I dir指定被包含的Makefile所在目录(重要),例如:make -I /dir/include
-n 只打印要执行的命令,但不执行这些命令,例如:make -n
-p 显示make变量数据库和隐含规则,例如:make -p
-s 在执行命令时不显示命令(不推荐)
-w 如果make在执行过程中改变目录,打印当前目录名,例如:make -w
-L 来指定库文件所在的目录,例如:- L /usr/lib
-l 来指定库文件的名称(不带后缀),例如:-lpthraed
1 | CFLAGS= -c -Wall -I include_dir # 告诉make在编译找不到头文件时,可以去include_dir文件夹找头文件 |
include关键字从其他文件读内容到makefile:
交叉编译时候会用到,比如跟开发板硬件相关的配置信息可以单独用一个config.mk文件书写,在makefile中include文件config.mk

- 本文作者: 龙兄嵌入式
- 本文链接: https://hexo.880755.xyz/1970/01/01/zblog/download/56.Makefile基本语法/
