LINUX-I.MX6U從零開始之1.5--Makefile語法與解讀


先來看個模板

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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章