Makefile 实用参考
在使用Ubuntu做嵌入式开发的时候,不像win环境中有各种各样的IDE帮助我们编译代码。作为一个专业的打工仔,会写Makefile是必备技能。以下是没水的货。
注:
Linux Makefile的命令好像只能用tab缩进
注释用 #
1 整个文件的大体格式
1.1 格式
目标…... : 依赖文件集合……
命令 1
命令 2
……
1.2 执行过程
- make在当前目录找到Makefile;
- 若找到文件则再读取第一个目标,并只将此目标当作整个Makefile的最终目标;
查看目标需要的依赖文件,若存在且未改动则退出,若依赖不存在则查看之后的目标是否含有此依赖,层层嵌套。依赖若均存在,执行之后的命令。
这里需要知道目标的意思:
<target> : <prerequisites>
<commands>
每个冒号都可以当做一个目标,第一个才是最终目标
2 常用赋值运算符
符 | 意义 |
---|---|
= | 是最基本的赋值 |
:= | 不使用赋值之后的定义 |
?= | 是如果没有被赋值过就赋予等号后面的值 |
+= | 给前面已经定义好的变量添加等号后面的字符串 |
3 变量
比如有很多的.c文件要编译,那就是写很多次不方便,就可以用个变量搞定它,可以当成C语言中的宏来理解
objects = aa.o bb.o cc.o # =可以换成其他赋值运算符,不同.o中间用空格隔开
之后就可以在后面使用下面这种写法来代替aa.o bb.o cc.o这三个文件了。
$(objects) #这个就是代表aa.o bb.o cc.o
4 通配符 和 %标记
通配符 | 使用说明 |
---|---|
* | 匹配0个或者是任意个字符 |
? | 匹配任意一个字符 |
[…] | 我们可以指定匹配的字符放在 “[ ]” 中 |
- %标记 和通配符 “*” 相类似,也是匹配任意个字符,"%.o" 把我们需要的所有的 “.o” 文件组合成为一个列表,从列表中挨个取出的每一个文件,"%" 表示取出来文件的文件名(不包含后缀),然后匹配文件中和 "%"名称相同的 “.c” 文件,然后执行下面的命令,直到列表中的文件全部被取出来为止。
- 当“%”出现在目标中的时候,目标中“%”所代表的值决定了依赖中的“%”值
- "*.c"代表系统该目录下中所有后缀为.c的文件都是我要找的。然后遍历路径下所有.c文件。
5 模式规则
- 如果工程里有很多个".c"需要生成".o",一个一个写规则很麻烦而且重复度太高,所以引入了模式规则。
- 模式规则中定有%
%.o : %.c
#这里写命令
6 自动化变量
- 上面模式规则中,命令里的目标和依赖都是一系列的具体文件,为了只写一种代替所有的,这里就需要自动化变量
自动化变量 | 含义 |
---|---|
$^ | 所有依赖文件的集合,使用空格分开,如果在依赖文件有重复,会去除重复的依赖文件,保留一份 |
$@ | 规则中的目标集合 |
$< | 依赖目标中的第一个目标名字,如果依赖文件是"%“定义的那么”$<"将是符合模式的一系列的文件集 |
7 伪目标
常用的clean,因为目标是会生成一个文件,但是clean不生成文件,而是清除编译好的文件以达到重新编译的功能,所以用伪目标来表示。
clean :
rm *.o $(name).bin $(name).elf # name 是变量名
8例子
例子是原子的嵌入式开发裸机点灯的Makefile。这个是我第一个没有对着写的Makefile,试验了一下,没有问题。求不喷
COMPILE_HEAD = arm-linux-gnueabihf
NAME = ledc
CC = $(COMPILE_HEAD)-gcc
LD = $(COMPILE_HEAD)-ld #将多个 .o 链接成 .elf
OBJCOPY = $(COMPILE_HEAD)-objcopy #将.elf 变成 .bin
OBJDUMP = $(COMPILE_HEAD)-objdump # 反汇编
OBJS := start.o main.o
$(NAME).bin : $(OBJS)
$(LD) -Timx6u.lds -o $(NAME).elf $^
# 上面的$^代表的事生成 .elf文件所需要的的所有的 .o 文件集合
$(OBJCOPY) -O binary -S $(NAME).elf $@
# 上面的$@ 是目标集合,也就是 .bin文件
$(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis
%.o : %.c
$(CC) -Wall -c -o $@ $<
%.o : %.s
$(CC) -Wall -c -o $@ $<
clean :
rm *.o $(NAME).bin $(NAME).elf $(NAME).dis
博主新入门嵌入式开发,以前都是用的IDE,所以内容如果有些问题,请指必改。