ldd3中文版第29頁hello.c的Makefile檔案解析

首先看書上第29頁的Makefile檔案:

ldd3中文版第29頁hello.c的Makefile檔案解析

當使用指令make -C ~/linux-2。6。10 M=`pwd` modules編譯時過程如下圖:

ldd3中文版第29頁hello.c的Makefile檔案解析

我們解釋下這個指令中各個引數的含義:

1。 -C ~/linux-2。6。10,這個引數在“man make”中有解釋,就是Change Directory的意思,make命令看到這個引數,就會先轉到指定的目錄,然後再去這個指定的目錄中找Makefile檔案開始執行,這裡就是linux原始碼根目錄中的Makefile檔案了。

ldd3中文版第29頁hello.c的Makefile檔案解析

2。 M=`pwd`,這個引數不是make命令的Option,在“man make”中是找不到的,這個引數會直接傳進Makefile檔案中,我們可以在linux原始碼根目錄的Makefile檔案中找到相關說明,意思是這個引數指定了要編譯的外部模組的目錄,有了這個引數,linux編譯系統就不會編譯linux原始碼中的程式碼了,而是直接編譯外部模組的程式碼。

ldd3中文版第29頁hello.c的Makefile檔案解析

3。 modules,這個引數也是直接傳給linux根目錄中的Makefile檔案,意思是編譯模組。不加M引數的話,就是編譯linux原始碼中的模組,加M引數的話,就是編譯外部模組。這個引數的含義在linux原始碼的根目錄中執行“make help”可以看到說明。

ldd3中文版第29頁hello.c的Makefile檔案解析

當直接用指令make不加引數編譯時過程如下圖:

ldd3中文版第29頁hello.c的Makefile檔案解析

可以看到編譯過程增加了一句指令,這句指令就是上邊我們用make加引數編譯時的那句指令。我們現在來分析make不加引數編譯時我們的Makefile檔案執行的順序。

1。 首先make不加引數會直接找到當前目錄中的Makefile檔案,按順序執行第2行,看有沒有$(KERNELRELEASE)這個變數,這時我們還沒有這個變數。

2。 執行第6行、第7行定義兩個變數,分別作為-C和M的引數值。

3。 執行第10行,就是我們make加引數編譯時的那句指令,這句指令首先改變目錄到linux原始碼根目錄中,然後找到linux原始碼根目錄中的Makefile檔案,並執行這個Makefile檔案。Makefile檔案會定義$(KERNELRELEASE)變數,然後看到modules就知道了是要編譯模組,根據M引數找到外部模組中的Makefile檔案,並執行這個Makefile檔案。

4。 再次執行到我們Makefile檔案的第2行,看有沒有$(KERNELRELEASE)這個變數,這個時候有了。

5。 執行到第3行,根據這一行找到hello。c去編譯出hello。o。

6。 然後返回到linux原始碼中的Makefile檔案,執行一些其它的操作,比如把hello。o變成hello。ko。

書上也說我們的Makefile檔案是執行了兩次的,第一次是直接make指令找當前目錄中的Makefile檔案,第二次是linux原始碼根目錄中的Makefile檔案根據M引數找外部模組的Makefile檔案。

另外注意,其實/lib/modules/$(shell uname -r)/build是一個軟連結,指向了真正的linux原始碼的根目錄。

ldd3中文版第29頁hello.c的Makefile檔案解析