
一、必備知識
1.1. Makefile基礎語法
如果還不熟悉Makefile語法,建議先系統的學習一下,特別是以下幾點:
(1) Makefile哪些部分包含的是shell語句:
編譯規則中的指令部分
${shell XX},var != XX中的XX部分
$(if …, XX, XX)中的XX部分
(2) 變量展開:
=(延遲賦值)、:=(立即賦值)、!=(值為shell命令)、?=(條件賦值)、+=(追加)
(3) include:將指定的其它Makefile內容,展開到當前Makefile
-f/-C:嵌套執行指定(目錄中的)Makefile
執行一個Makefile,并不是從第一行開始執行,而是從指定或默認的編譯目標開始執行(位置目標編譯規則之前的賦值語句,只在相應變量需要被使用時才會執行),其中,Makefile(包括include內容)中的第一個目標,為默認目標,如果make命令行中沒有指定編譯目標,則執行默認目標。
(4) 自動推導依賴文件
(5) 根據文件時間戳、中間文件(.d、.cmd),判斷依賴更新,決定是否需要重新編譯
(6) 重要的內置函數:
$(wildcard pattern)
$(patsubst pattern, replacement, text)
$(strip string)
$(filter pattern, text)
$(filter-out pattern, text)
$(call func, args..)
…
(7) 自動推導變量:
$@:編譯目標
$<:依賴列表中的第一個依賴對象
$^:依賴列表中的所有對象
$?:依賴文件列表中所有有更新的文件
Makefile教程可以參考以下這2個:
深入解析Makefile系列:https://zhuanlan.zhihu.com/p/362640343(簡約,直指核心)
跟我一起寫makefile(陳皓):https://blog.csdn.net/whitefish520/article/details/103968609(精典,超級詳細)
1.2. Kbuild內置函數
Linux內核源碼包含一套Makefile程序,本文基于Linux-5.2.5內核源碼分析,其中包括top Makefile,scripts/目錄下的Makefile、Makefile.build、Makefile.lib、Kbuild.include、Makefile.modpost、kconfig/Makefile等,以及其它目錄下的很多子Makefile,統稱為Kbuild。Kbuild是按照框架設計思路實現的,使得內核自身包含或外部提供的大量驅動模塊,只需要按照Kbuild框架的約定,各自提供一個簡單的Makefile即可編譯。
所以,理解內核或驅動文件的編譯過程,其實就是要理解Kbuild這套Makefile程序的實現邏輯,既然是程序,就免不了會定義一些函數,由于很多關鍵的流程,都使用了$(build)和$(if_changed),所以以下先單獨介紹(本文分析的Makefile內容,來自Linux-5.2.5內核源碼):
1.2.1. $(build)
◆使用形式:$(Q)$(MAKE) $(build)=xx目錄 [編譯目標]

◆build內部過程

◆build作用概括
以下是$(build)的使用形式,以及每個部分的作用:

1.2.2. $(if_changed)
◆使用形式:$(call if_changed, xx)

◆if_changed內部過程

◆if_changed作用概括
以下是$(if_changed)的使用形式,及其參數的含義:

二、編譯外部模塊
2.1. 涉及Makefile內容

2.2. 概要流程

2.3. 詳細流程

三、make menuconfig
3.1. 涉及Makefile內容

3.2. 概要流程

3.3. 詳細流程

四、Make [all/_all/modules]
4.1. 涉及Makefile內容
make命令行指定all/_all/modules目標,或者不指定目標時,是為了生成vmlinux文件,而vmlinux目標間接依賴prepare目標,且prepare目標編譯規則展開內容比較多,所以以下分開介紹:
◆vmlinux目標

◆prepare目標

4.2. 概要流程
◆vmlinux目標

◆prepare目標

4.3. 詳細流程
◆vmlinux目標

◆vmlinuz目標

◆prepare目標

看雪學苑
LemonSec
安全圈
一顆小胡椒
CNCERT國家工程研究中心
LemonSec
系統安全運維
LemonSec
安全圈
黑客技術和網絡安全
雷石安全實驗室
FuzzWiki