LCD實驗學習筆記(一):Makefile
主Makefile總領全域性的就這句——
lcd.bin: $(objs)
要生成lcd.bin,依賴於objs列舉的一堆檔案:head.o init.o nand.o interrupt.o serial.o lcddrv.o framebuffer.o lcdlib.o main.o lib/libc.a
所以要先找到這些檔案,幾個.o,還有一個.a
.o目標檔案怎麼生成?
%.o:%.c和%.o:%.S是生成規則,就是依賴於.c或.S檔案,使用交叉編譯命令生成。
.a是庫檔案,到lib子目錄裡去找,在子目錄裡用make命令生成
下面逐行解讀:
CC = arm-linux-gcc
LD = arm-linux-ld //聯結器。定義LD變數,為了簡化書寫
AR = arm-linux-ar //庫管理器。將多個可重定位的目標模組歸檔為一個函式庫檔案。這個變數在lib/makefile檔案中使用了
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump
INCLUDEDIR := $(shell pwd)/include //定義標頭檔案目錄變數 $(shell pwd)為獲取當前工作路徑
CFLAGS := -Wall -O2 //GCC的編譯引數 -Wall顯示所有編譯錯誤或警告 -O2優化選項,編譯時使用2級優化
CPPFLAGS := -nostdinc -I$(INCLUDEDIR)
備註:‘=’與‘:=’的區別:
“=”:make會將整個makefile展開後,再決定變數的值。也就是說,變數的值將會是整個makefile中最後被指定的值。看例子:
x = foo
y = $(x) bar
x = xyz
在上例中,y的值將會是 xyz bar ,而不是 foo bar 。
“:=”表示變數的值決定於它在makefile中的位置,而不是整個makefile展開後的最終值。
x := foo
y := $(x) bar
x := xyz
在上例中,y的值將會是 foo bar ,而不是 xyz bar 了。
export CC LD AR OBJCOPY OBJDUMP INCLUDEDIR CFLAGS CPPFLAGS //這些變數將傳遞到下級Makefile,本檔案中指的是生成lib/libc.a庫檔案時的Makefile
objs := head.o init.o nand.o interrupt.o serial.o lcddrv.o framebuffer.o lcdlib.o main.o lib/libc.a //定義變數objs,包含了生成目標檔案所需的檔案
lcd.bin: $(objs) //定義生成目標lcd.bin,依賴於objs物件。執行這條命令時,先生成所有依賴檔案,然後依次執行下面三條命令
${LD} -Tlcd.lds -o lcd_elf $^ //執行shell命令,LD變數前面定義”LD = arm-linux-ld“,即進行連線,使用lcd.lds為連線指令碼,輸出目標為lcd_elf,$^表示全部依賴檔案
${OBJCOPY} -O binary -S lcd_elf [email protected] //執行shell命令,將lcd_elf檔案轉換成二進位制檔案,-O表示輸出格式,-S表示不從原始檔中複製重定位資訊和符號資訊到目標檔案中
${OBJDUMP} -D -m arm lcd_elf > lcd.dis //反彙編lcd_elf檔案為lcd.dis檔案
.PHONY : lib/libc.a //.PHONY表示偽目標,不要管lib/libc.a檔案是否存在
lib/libc.a: //當生成依賴檔案lib/libc.a檔案時,用下面的命令段,即cd lib; make; cd ..
cd lib; make; cd .. //進入lib目錄,然後執行make命令,最後返回到當前目錄。在lib子目錄執行make命令時將使用子目錄的Makefile,但於由前面export命令,本檔案定義的一些變數將傳遞過去
%.o:%.c //%萬用字元。生成xxx.o檔案先要找到xxx.c檔案
${CC} $(CPPFLAGS) $(CFLAGS) -c -o [email protected] $< //-c編譯不連線。[email protected]表示目標檔案 $<表示第一個依賴檔案
%.o:%.S
${CC} $(CPPFLAGS) $(CFLAGS) -c -o [email protected] $<
clean: //這個clean目標沒有依賴物件,肯定是生成不了clean檔案的,但會執行下面的命令。前面寫明.PHONY : clean就更清楚了
make clean -C lib
rm -f lcd.bin lcd_elf lcd.dis *.o