LINUX-I.MX6U从零开始之1.5--Makefile语法与解读

本文深入解析Makefile的使用,涵盖变量定义、赋值符号、规则应用、伪目标、判断语句及函数操作。通过实例展示批量编译、自动化变量与规则结合的应用,并详细介绍复杂工程Makefile的构建技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


先来看个模板

main: main.o
 	gcc -o main main.o 
 	
main.o: main.c
	gcc -c main.c
	
clean:
	 rm *.o
	 rm main
一,变量

写个变量variable。

#也可以这样写variable=main.o led.o led1.o
variable=main.o

main: $(variable)
 	gcc -o main $(variable)
 	
$(variable): main.c
	gcc -c main.c
	
clean:
	 rm *.o
	 rm main
二,赋值
2.1 赋值符 =

跟C的等于不太一样,用C来解释就是:
a=1;
b=a;
a=2;
这时候b=2。

2.2 赋值符 :=

借用上面的例子,最后b=1;

2.3 赋值符 ?=

a ?= 2
借用上面的例子,如果a没有赋值,a=2.

2.4 赋值符 +=

借用最上面的例子就是
variable=main.o
variable+=led.o
这时候variable=main.o led.o

三,规则

简单来说就是批量赋值编译。

3.1 %.o:%.c

代替所有的如led.o:led.c

3.2 自动化变量

在这里插入图片描述

3.3上面俩结合的例子
main.o: main.c
	gcc -c main.c
input.o: input.c
	gcc -c input.c
calcu.o: calcu.c
	gcc -c calcu.c
#变成
%.o : %.c
	gcc -c $<
四,伪目标

简单来说就是,如:clean这个清除指令,如果有个傻孩子在这个工程的目录里有个叫clean的文件,那么make clean不会清文件。这时候就需要伪目标这个东西了。

.PHONY : clean
五,判断
5.1 四种判断

条件关键字:
ifeq、ifneq #比较两个值是否相等
ifdef、ifndef #判断一个值是否为空

5.2 格式
<条件关键字>
	<条件为真时执行的语句>
endif
以及:
<条件关键字>
	<条件为真时执行的语句>
else
	<条件为假时执行的语句>
endif
六,函数
$(函数名 参数集合)   #用()或{}都行
如:$(subst zzz,ZZZ,my name is zzz)

还有六个功能函数,懒得看,用到再说吧。
1 、函数 subst
2 、函数 patsubst
3 、函数 dir
4 、函数 notdir
5 、函数 foreach
6 、函数 wildcard

七,详细分析工程的makefile
CROSS_COMPILE 	?= arm-linux-gnueabihf- #这是个变量,代替指令前面那一段
TARGET		  	?= BSP

CC 				:= $(CROSS_COMPILE)gcc
LD				:= $(CROSS_COMPILE)ld
OBJCOPY 		:= $(CROSS_COMPILE)objcopy
OBJDUMP 		:= $(CROSS_COMPILE)objdump
//.h的头文件目录
INCDIRS 		:= imx6ul \
				   BSP/clk \
				   BSP/led \
				   BSP/delay 
//.c .s的头文件目录				   			   
SRCDIRS			:= project \
				   BSP/clk \
				   BSP/led \
				   BSP/delay 
				   
//给变量 INCDIRS 添加一个“-I”		
//INCLUDE := -I imx6ul -I bsp/clk -I bsp/led -I bsp/delay   
INCLUDE			:= $(patsubst %, -I %, $(INCDIRS))

//保存所有.s,.c文件
//SFILES := project/start.S
//CFILES = project/main.c bsp/clk/bsp_clk.c bsp/led/bsp_led.c bsp/delay/bsp_delay.c
SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

//包含所有.c .s ,相比于上面两行,是去掉了路径
//SFILENDIR = start.S
//CFILENDIR = main.c bsp_clk.c bsp_led.c bsp_delay.c
SFILENDIR		:= $(notdir  $(SFILES))
CFILENDIR		:= $(notdir  $(CFILES))

//.o文件保存到obj目录
//SOBJS = obj/start.o
//COBJS = obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o
SOBJS			:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS			:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o))

//这是上面这两个变量的集合
//OBJS = obj/start.o obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o
OBJS			:= $(SOBJS) $(COBJS)

//搜索SRCDIRS目录里的.s .c
VPATH			:= $(SRCDIRS)

//伪目标
.PHONY: clean
	
$(TARGET).bin : $(OBJS)
	$(LD) -Timx6ul.lds -o $(TARGET).elf $^
	$(OBJCOPY) -O binary -S $(TARGET).elf $@
	$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis

$(SOBJS) : obj/%.o : %.S
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<

$(COBJS) : obj/%.o : %.c
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<
	
clean:
	rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值