make指令執行時,需要一個 Makefile 檔案,以告訴make指令需要怎麼樣的去編譯和連結程式。
一、使用條件判斷
下面的例子,判斷$(CC)變量是否“gcc”,如果是的話,則使用GNU函數編譯目标。
libs_for_gcc = -lgnu
normal_libs =
foo: $(objects)
ifeq ($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
可見,在上面示例的這個規則中,目标“foo”可以根據變量“$(CC)”值來選取不同的函數庫來編譯程式。
我們可以從上面的示例中看到三個關鍵字:ifeq、else和endif。ifeq的意思表示條件語句的開始,并指定一個條件表達式,表達式包含兩個參數,以逗号分隔,表達式以圓括号括起。else表示條件表達式為假的情況。endif表示一個條件語句的結束,任何一個條件表達式都應該以endif結束。
libs_for_gcc = -lgnu
normal_libs =
ifeq ($(CC),gcc)
libs=$(libs_for_gcc)
else
libs=$(normal_libs)
endif
foo: $(objects)
$(CC) -o foo $(objects) $(libs)
下面是關于一段arm驅動程式的分析
obj-m :=hello.o
KERNELDIR :=/home/ZP1015/Desktop/linux-2.6.32.2
all:
make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.o *.ko *.mod.o *.mod.c *.symvers modul*
ifneq ($(KERNELRELEASE),)
obj-m :=hello.o
else
KERNELDIR :=/home/ZP1015/Desktop/linux-2.6.32.2
all:
make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.o *.ko *.mod.o *.mod.c *.symvers modul*
endif
1、ifeq”文法是ifeq (<arg1>;, <arg2>;),功能是比較參數“arg1”和“arg2”的值是否相同。ifneq剛好相反,比較兩者的值是否不同其中有一些是我們常見或是見過的,第一個ifneq ($(KERNELRELEASE),)目前,有用處,它的由來是指在Linux源碼根目錄下的Makefile編譯核心時,KERNELRELEASE宏會被定義,那麼如果是從源碼根目錄開始的make則會将hello.o子產品編譯進核心。
KERNELDIR :=/home/ZP1015/Desktop/linux-2.6.32.2 這句是對KERNELDIR進行指派,這個變量是後面我們用到的指代核心源碼目錄用的。
2、make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
這句是Makefile的規則:這裡的$(MAKE)就相當于make,-C 選項的作用是指将目前工作目錄轉移到你所指定的位置。“M=”選項的作用是,當使用者需要以某個核心為基礎編譯一個外部子產品的話,需要在make modules 指令中加入“M=dir”,程式會自動到你所指定的dir目錄中查找子產品源碼,将其編譯,生成KO檔案。M不是makefile的選項,是核心根目錄下的Makefile中使用的變量
3、具體編譯過程
KERNELRELEASE:由Kernel頂層Makefile中定義。
判斷變量KERNELRELEASE與空字元是否相同,即判斷變量KERNELRELEASE的值是否為空,為空的話就進入else
第一次運作中,KERNELRELEASE沒有被定義,是以進入else
$(MAKE) -C $(KERNELDIR) M=$(PWD)
此處讀取KERNELDIR中的頂層Makefile。讀取後又傳回本目錄。繼續執行本目錄Makefile。
則此時KERNELRELEASE被定義。進入if.
if和else之間的為kbuild文法的語句.
4、兩段makefile對比分析
如何核心源碼路徑設定正确,其實兩段makefile沒有什麼差別,作用完全一緻。但是有用ifneq之後,可以確定是從核心構造系統調用的。如果核心源碼路徑設定錯誤,KERNELRELEASE沒有定義,make就沒有對象。是以建議用後面那段makefile