亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問板塊 發(fā)新帖
查看: 611 | 回復(fù): 0
打印 上一主題 下一主題

kernel2.6.x Makefile詳解 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2008-06-06 18:10 |只看該作者 |倒序?yàn)g覽
linux2.6內(nèi)核Makefile的許多特性和2.4內(nèi)核差別很大,在內(nèi)核目錄的documention/kbuild/makefiles.txt中有詳細(xì)的說(shuō)明,以下為中文版的翻譯。
=== 目錄
    === 1 概述
    === 2 用戶與作用
    === 3 Kbuild文件
       --- 3.1 目標(biāo)定義
       --- 3.2 編譯進(jìn)內(nèi)核 - obj-y
       --- 3.3 編譯可裝載模塊 - obj-m
       --- 3.4 輸出的符號(hào)
       --- 3.5 目標(biāo)庫(kù)文件 - lib-y
       --- 3.6 遞歸躺下訪問目錄
       --- 3.7 編輯標(biāo)志
       --- 3.8 命令行的依賴關(guān)系(原文中沒有寫:-))
       --- 3.9 跟蹤依賴
       --- 3.10 特殊規(guī)則
       --- 3.11 $(CC) 支持的函數(shù)
    === 4 本機(jī)程序支持
       --- 4.1 簡(jiǎn)單的本機(jī)程序
       --- 4.2 復(fù)合的本機(jī)程序
       --- 4.3 定義共享庫(kù)
       --- 4.4 使用用C++編寫的本機(jī)程序
       --- 4.5 控制本機(jī)程序的編譯選項(xiàng)
       --- 4.6 編譯主機(jī)程序時(shí)
       --- 4.7 使用 hostprogs-$(CONFIG_FOO)
   
    === 5 Kbuild清理
    === 6 架構(gòu)Makefile
       --- 6.1 調(diào)整針對(duì)某一具體架構(gòu)生成的鏡像
       --- 6.2 將所需文件加到 archprepare 中
       --- 6.3 遞歸下向時(shí)要訪問的目錄列表
       --- 6.4 具體架構(gòu)的啟動(dòng)鏡像
       --- 6.5 構(gòu)造非Kbuild目標(biāo)
       --- 6.6 構(gòu)建啟動(dòng)鏡像的命令
       --- 6.7 Kbuild自定義命令
       --- 6.8 聯(lián)接器預(yù)處理腳本
    === 7 Kbuild 變量
    === 8 Makefile語(yǔ)言
    === 9 關(guān)于作者
    === 10 TODO
=== 1 概述
Linux內(nèi)核的Makefile分為5個(gè)部分:
         
     Makefile                 頂層Makefile
     .config                  內(nèi)核配置文件
     arch/$(ARCH)/Makefile    具體架構(gòu)的Makefile
     scripts/Makefile.*       通用的規(guī)則等。面向所有的Kbuild Makefiles。
     kbuild Makefiles         內(nèi)核源代碼中大約有500個(gè)這樣的文件
頂層Makefile閱讀的.config文件,而該文件是由內(nèi)核配置程序生成的。
頂層Makefile負(fù)責(zé)制作:vmlinux(內(nèi)核文件)與模塊(任何模塊文件)。制作的過程主要是通過遞歸向下訪問子目錄的形式完成。并根據(jù)內(nèi)核配置文件確定訪問哪些子目錄。頂層Makefile要原封不動(dòng)的包含一具體架構(gòu)的Makefile,其名字類似于 arch/$(ARCH)/Makefile。該架構(gòu)Makefile向頂層Makefile提供其架構(gòu)的特別信息。
每一個(gè)子目錄都有一個(gè)Kbuild Makefile文件,用來(lái)執(zhí)行從其上層目錄傳遞下來(lái)的命令。Kbuild Makefile從.config文件中提取信息,生成Kbuild完成內(nèi)核編譯所需的文件列表。
scripts/Makefile.*包含了所有的定義、規(guī)則等信息。這些文件被用來(lái)編譯基于kbuild Makefile的內(nèi)核。(**有點(diǎn)不通**)
=== 2 用戶與作用
可以將人們與內(nèi)核Makefile的關(guān)系分成4類。
*使用者* 編譯內(nèi)核的人。他們只是鍵入"make menuconfig"或"make"這樣的命令。一般情況下是不會(huì)讀或編輯任何內(nèi)核Makefile(或者任何的源文件)。
*普通開發(fā)人員* 這是一群工作在內(nèi)核某一功能上的人,比如:驅(qū)動(dòng)開發(fā),文件系統(tǒng)或網(wǎng)絡(luò)協(xié)議。他們所需要維護(hù)的只是他們所工作的子系統(tǒng)的Kbuild Makefile。為了提高工作的效率,他們也需要對(duì)內(nèi)核Makefile有一個(gè)全面的認(rèn)識(shí),并且要熟悉Kbuild的接口。
*架構(gòu)開發(fā)人員* 這是一些工作在具體架構(gòu),比如sparc 或者ia64,上面的人。架構(gòu)開發(fā)者需要在熟悉kbuild Makefile的同時(shí),也要熟悉他所工作架構(gòu)的Makefile。
*Kbuild開發(fā)者* 維護(hù)Kbuild系統(tǒng)的人。他們需要知曉內(nèi)核Makefile的方方面面。該文件是為普通開發(fā)人員與架構(gòu)開發(fā)人員所寫。
=== 3 Kbuild文件
大部分內(nèi)核中的Makefile都是使用Kbuild組織結(jié)構(gòu)的Kbuild Makefile。這章介紹了Kbuild Makefile的語(yǔ)法。Kbuild文件傾向于"Makefile"這個(gè)名字,"Kbuild"也是可以用的。但如果"Makefile""Kbuild"同時(shí)出現(xiàn)的話,使用的將會(huì)是"Kbuild"文件。
3.1節(jié) 目標(biāo)定義是一個(gè)快速介紹,以后的幾章會(huì)提供更詳細(xì)的內(nèi)容以及實(shí)例。
--- 3.1 目標(biāo)定義
        目標(biāo)定義是Kbuild Makefile的主要部分,也是核心部分。主要是定義了要編譯的文件,所有的選項(xiàng),以及到哪些子目錄去執(zhí)行遞歸操作。
        最簡(jiǎn)單的Kbuild makefile 只包含一行:
        例子:
          obj-y += foo.o
        該例子告訴Kbuild在這目錄里,有一個(gè)名為foo.o的目標(biāo)文件。foo.o將從foo.c或foo.S文件編譯得到。
        如果foo.o要編譯成一模塊,那就要用obj-m了。所采用的形式如下:
        例子:
          obj-$(CONFIG_FOO) += foo.o
        $(CONFIG_FOO)可以為y(編譯進(jìn)內(nèi)核) 或m(編譯成模塊)。如果CONFIG_FOO不是y和m,那么該文件就不會(huì)被編譯聯(lián)接了。
--- 3.2 編譯進(jìn)內(nèi)核 - obj-y
        Kbuild Makefile 規(guī)定所有編譯進(jìn)內(nèi)核的目標(biāo)文件都存在$(obj-y)列表中。而這些列表依賴內(nèi)核的配置。
        Kbuild編譯所有的$(obj-y)文件。然后,調(diào)用"$(LD) -r"將它們合并到一個(gè)build-in.o文件中。稍后,該build-in.o會(huì)被其父Makefile聯(lián)接進(jìn)vmlinux中。
        $(obj-y)中的文件是有順序的。列表中有重復(fù)項(xiàng)是可以的:當(dāng)?shù)谝粋(gè)文件被聯(lián)接到built-in.o中后,其余文件就被忽略了。
        聯(lián)接也是有順序的,那是因?yàn)橛行┖瘮?shù)(module_init()/__initcall)將會(huì)在啟動(dòng)時(shí)按照他們出現(xiàn)的順序進(jìn)行調(diào)用。所以,記住改變聯(lián)接的順序可能改變你SCSI控制器的檢測(cè)順序,從而導(dǎo)致你的硬盤數(shù)據(jù)損害。
        例子:
          #drivers/isdn/i4l/Makefile
          # Makefile for the kernel ISDN subsystem and device drivers.
          # Each configuration option enables a list of files.
          obj-$(CONFIG_ISDN)        += isdn.o
          obj-$(CONFIG_ISDN_PPP_BSDCOMP)    += isdn_bsdcomp.o
--- 3.3 編譯可裝載模塊 - obj-m
        $(obj-m) 列舉出了哪些文件要編譯成可裝載模塊。
        一個(gè)模塊可以由一個(gè)文件或多個(gè)文件編譯而成。如果是一個(gè)源文件,Kbuild Makefile只需簡(jiǎn)單的將其加到$(obj-m)中去就可以了。
        例子:
          #drivers/isdn/i4l/Makefile
          obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
        注意:此例中 $(CONFIG_ISDN_PPP_BSDCOMP) 的值為'm'
        如果內(nèi)核模塊是由多個(gè)源文件編譯而成,那你就要采用上面那個(gè)例子一樣的方法去聲明你所要編譯的模塊。
        Kbuild需要知道你所編譯的模塊是基于哪些文件,所以你需要通過變量
    $(-objs)來(lái)告訴它。
        例子:
          #drivers/isdn/i4l/Makefile
          obj-$(CONFIG_ISDN) += isdn.o
          isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
        在這個(gè)例子中,模塊名將是isdn.o,Kbuild將編譯在$(isdn-objs)中列出的所有文件,然后使用"$(LD) -r"生成isdn.o。
        Kbuild能夠識(shí)別用于組成目標(biāo)文件的后綴-objs和后綴-y。這就讓Kbuild Makefile可以通過使用 CONFIG_ 符號(hào)來(lái)判斷該對(duì)象是否是用來(lái)組合對(duì)象的。
        例子:
          #fs/ext2/Makefile
          obj-$(CONFIG_EXT2_FS)        += ext2.o
          ext2-y                 := balloc.o bitmap.o
          ext2-$(CONFIG_EXT2_FS_XATTR)    += xattr.o
        在這個(gè)例子中,如果 $(CONFIG_EXT2_FS_XATTR) 是 'y',xattr.o將是復(fù)合對(duì)象 ext2.o的一部分。
        注意:當(dāng)然,當(dāng)你要將其編譯進(jìn)內(nèi)核時(shí),上面的語(yǔ)法同樣適用。所以,如果你的 CONFIG_EXT2_FS=y,那Kbuild會(huì)按你所期望的那樣,生成 ext2.o文件
    ,然后將其聯(lián)接到 built-in.o中。
--- 3.4 輸出的符號(hào)

        在Makefile中,沒有對(duì)模塊輸出的符號(hào)有特殊要求。
--- 3.5 目標(biāo)庫(kù)文件 - lib-y
        在 obj-* 中所列文件是用來(lái)編譯模塊或者是聯(lián)接到特定目錄中的 built-in.o。同樣,也可以列出一些將被包含在lib.a庫(kù)中的文件。在 lib-y 中所列出的文件用來(lái)組成該目錄下的一個(gè)庫(kù)文件。
        在 obj-y 與 lib-y 中同時(shí)列出的文件,因?yàn)槎际强梢栽L問的,所以該文件是不會(huì)被包含在庫(kù)文件中的。同樣的情況, lib-m 中的文件就要包含在 lib.a 庫(kù)文件中。
        注意,一個(gè)Kbuild makefile可以同時(shí)列出要編譯進(jìn)內(nèi)核的文件與要編譯成庫(kù)的文件。所以,在一個(gè)目錄里可以同時(shí)存在 built-in.o 與 lib.a 兩個(gè)文件。
        例子:
          #arch/i386/lib/Makefile
          lib-y    := chechsum.o delay.o
        這將由 checksum.o 和delay.o 兩個(gè)文件創(chuàng)建一個(gè)庫(kù)文件 lib.a。為了讓Kbuild 真正認(rèn)識(shí)到這里要有一個(gè)庫(kù)文件 lib.a 要?jiǎng)?chuàng)建,其所在的目錄要加到 libs-y 列表中。還可參考"6.3 遞歸下向時(shí)要訪問的目錄列表"lib-y 使用一般限制在 lib/ 和 arch/*/lib 中。
--- 3.6 遞歸向下訪問目錄
        一個(gè)Makefile只對(duì)編譯所在目錄的對(duì)象負(fù)責(zé)。在子目錄中的文件的編譯要由其所在的子目錄的Makefile來(lái)管理。只要你讓Kbuild知道它應(yīng)該遞歸操作,那么該系統(tǒng)就會(huì)在其子目錄中自動(dòng)的調(diào)用 make 遞歸操作。
   
        這就是 obj-y 和 obj-m 的作用。ext2 被放的一個(gè)單獨(dú)的目錄下,在fs目錄下的Makefile會(huì)告訴Kbuild使用下面的賦值進(jìn)行向下遞歸操作。
        例子:
          #fs/Makefile
          obj-$(CONFIG_EXT2_FS) += ext2/
        如果 CONFIG_EXT2_FS 被設(shè)置為 'y'(編譯進(jìn)內(nèi)核)或是'm'(編譯成模塊),相應(yīng)的 obj- 變量就會(huì)被設(shè)置,并且Kbuild就會(huì)遞歸向下訪問 ext2 目錄。Kbuild只是用這些信息來(lái)決定它是否需要訪問該目錄,而具體怎么編譯由該目錄中的Makefile來(lái)決定。
    將 CONFIG_ 變量設(shè)置成目錄名是一個(gè)好的編程習(xí)慣。這讓Kbuild在完全忽略那些相應(yīng)的 CONFIG_ 值不是'y'和'm'的目錄。
--- 3.7 編輯標(biāo)志
    EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
    所有的 EXTRA_ 變量只在所定義的Kbuild Makefile中起作用。EXTRA_ 變量可以在Kbuild Makefile中所有命令中使用。
    $(EXTRA_CFLAGS) 是用 $(CC) 編譯C源文件時(shí)的選項(xiàng)。
    例子:
          # drivers/sound/emu10kl/Makefile
          EXTRA_CFLAGS += -I$(obj)
          ifdef DEBUG
              EXTRA_CFLAGS += -DEMU10KL_DEBUG
          endif
    該變量是必須的,因?yàn)轫攲覯akefile擁有變量 $(CFLAGS) 并用來(lái)作為整個(gè)源代碼樹的編譯選項(xiàng)。
    $(EXTRA_AFLAGS) 也是一個(gè)針對(duì)每個(gè)目錄的選項(xiàng),只不過它是用來(lái)編譯匯編源代碼的。
    例子:
        #arch/x86_64/kernel/Makefile
        EXTRA_AFLAGS := -traditional
    $(EXTRA_LDFLAGS) 和 $(EXTRA_ARFLAGS)分別與 $(LD)和 $(AR)類似,只不過,他們是針對(duì)每個(gè)目錄的。
    例子:
        #arch/m68k/fpsp040/Makefile
        EXTRA_LDFLAGS := -x
    CFLAGS_$@, AFLSGA_$@
    CFLAGS_$@ 和 AFLAGS_$@ 只能在當(dāng)前Kbuild Makefile中的命令中使用。
    $(CFLAGS_$@) 是 $(CC) 針對(duì)每個(gè)文件的選項(xiàng)。$@ 表明了具體操作的文件。
    例子:
        # drivers/scsi/Makefile
        CFLAGS_aha152x.o =  -DAHA152X_STAT -DAUTOCONF
        CFLAGS_gdth.o    =  # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
                      -DGDTH_STATISTICS
        CFLAGS_seagate.o =  -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
    以上三行分別設(shè)置了aha152x.o,gdth.o 和 seagate.o的編輯選項(xiàng)。
    $(AFLAGS_$@) 也類似,只不是是針對(duì)匯編語(yǔ)言的。
    例子:
        # arch/arm/kernel/Makefile
        AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
        AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
--- 3.9 跟蹤依賴
    Kbuild 跟蹤在以下方面依賴:
    1) 所有要參與編譯的文件(所有的.c 和.h文件)
    2) 在參與編譯文件中所要使用的 CONFIG_ 選項(xiàng)
    3) 用于編譯目標(biāo)的命令行
    因此,如果你改變了 $(CC) 的選項(xiàng),所有受影響的文件都要重新編譯。
--- 3.10 特殊規(guī)則
    特殊規(guī)則就是那Kbuild架構(gòu)不能提供所要求的支持時(shí),所使用的規(guī)則。一個(gè)典型的例子就是在構(gòu)建過程中生成的頭文件。另一個(gè)例子就是那些需要采用特殊規(guī)則來(lái)準(zhǔn)備啟動(dòng)鏡像。
    特殊規(guī)則的寫法與普通Make規(guī)則一樣。
    Kbuild并不在Makefile所在的目錄執(zhí)行,所以所有的特殊規(guī)則都要提供參與編譯的文件和目標(biāo)文件的相對(duì)路徑。
    在定義特殊規(guī)則時(shí),要使用以下兩個(gè)變量:
    $(src)
    $(src) 表明Makefile所在目錄的相對(duì)路徑。經(jīng)常在定位源代碼樹中的文件時(shí),使用該變量。
    $(obj)
    $(obj) 表明目標(biāo)文件所要存儲(chǔ)目錄的相對(duì)路徑。經(jīng)常在定位所生成的文件時(shí),使用該變量。
    例子:
        #drivers/scsi/Makefile
        $(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
            $(CPP) -DCHIP=810 - = 3.00
        cc-option-align = -falign
    例子:
        CFLAGS += $(cc-option-align)-functions=4
    在上面的例子中,選項(xiàng) -falign-funcions=4 被用在gcc >= 3.00的時(shí)候。對(duì)于小于3.00時(shí), 使用 -malign-funcions=4 。
    cc-version
    cc-version以數(shù)學(xué)形式返回 $(CC) 編譯器的版本號(hào)。
    其格式是:,二者都是數(shù)學(xué)。比如,gcc 3.41 會(huì)返回 0341。
    當(dāng)某版本的 $(CC) 在某方面有缺陷時(shí),cc-version就會(huì)很有用。比如,選項(xiàng)-mregparm=3 雖然會(huì)被gcc接受,但其實(shí)現(xiàn)是有問題的。
    例子:
        #arch/i386/Makefile
        cflags-y += $(shell \
        if [ $(call cc-version) -ge 0300 ] ; then \
            echo "-meregparm=3"; fi ;)
    在上面的例子中,-mregparm=3只會(huì)在gcc的版本號(hào)大于等于3.0的時(shí)候使用。
    cc-ifversion
    cc-ifversion測(cè)試 $(CC) 的版本號(hào),如果版本表達(dá)式為真,就賦值為最后的參數(shù)。
    例子:
        #fs/reiserfs/Makefile
        EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1)
    在這個(gè)例子中,如果 $(CC) 的版本小于4.2,EXTRA_CFLAGS就被賦值 -O1。
    cc-ifversion 可使用所有的shell 操作符:-eq,-ne,-lt,-le,-gt,和-ge。
    第三個(gè)參數(shù)可以像上面例子一樣是個(gè)文本,但也可以是個(gè)擴(kuò)展的變量或宏。
/*這段翻譯的不好*/
=== 4 本機(jī)程序支持
Kbuild 支持編譯那些將在編譯階段使用的可執(zhí)行文件。
為了使用該可執(zhí)行文件,要將編譯分成二個(gè)階段。
第一階段是告訴Kbuild存在哪些可執(zhí)行文件。這是通過變量 hostprogs-y來(lái)完成的。
第二階段是添加一個(gè)對(duì)可執(zhí)行文件的顯性依賴。有兩種方法:增加依賴關(guān)系到一個(gè)規(guī)規(guī)中,或是利用變量 $(always)。
以下是詳細(xì)敘述.
--- 4.1 簡(jiǎn)單的本機(jī)程序
    在編譯內(nèi)核時(shí),有時(shí)會(huì)需要編譯并運(yùn)行一個(gè)程序。
    下面這行就告訴了kbuild,程序bin2hex應(yīng)該在本機(jī)上編譯。
    例子:
        hostprogs-y := bin2hex
    在上面的例子中,Kbuild假設(shè)bin2hex是由一個(gè)與其在同一目錄下,名為
    bin2hex.c 的C語(yǔ)言源文件編譯而成的。
--- 4.2 復(fù)合的本機(jī)程序
    本機(jī)程序可以由多個(gè)文件編譯而成。
    所使用的語(yǔ)法與內(nèi)核的相應(yīng)語(yǔ)法很相似。
    $(-objs) 列出了聯(lián)接成最后的可執(zhí)行文件所需的所有目標(biāo)文件。
    例子:
        #scripts/lxdialog/Makefile
        hostprogs-y    := lxdialog
        lxdialog-objs    := checklist.o lxdialog.o
    擴(kuò)展名為.o的文件是從相應(yīng)的.c文件編譯而來(lái)的。在上面的例子中,
    checklist.c 編譯成了checklist.o,lxdialog.c編譯成了lxdialog.o。
    最后,兩個(gè).o文件聯(lián)接成了一可執(zhí)行文件,lxdialog。
    注意:語(yǔ)法 -y不是只能用來(lái)生成本機(jī)程序。
--- 4.3 定義共享庫(kù)
    擴(kuò)展名為so的文件稱為共享庫(kù),被編譯成位置無(wú)關(guān)對(duì)象。
    Kbuild也支持共享庫(kù),但共享庫(kù)的使用很有限。
    在下面的例子中,libconfig.so共享庫(kù)用來(lái)聯(lián)接到可執(zhí)行文件 conf中。
    例子:
        #scripts/kconfig/Makefile
        hostprogs-y    := conf
        conf-objs    := conf.o libkconfig.so
        libkcofig-objs    := expr.o type.o
    共享庫(kù)文件經(jīng)常要求一個(gè)相應(yīng)的 -objs,在上面的例子中,共享庫(kù)libkconfig
    是由 expr.o 和 type.o兩個(gè)文件組成的。
    expr.o 和 type.o 將被編譯成位置無(wú)關(guān)碼,然后聯(lián)接成共享庫(kù)文件
    libkconfig.so。C++并不支持共享庫(kù)。
--- 4.4 使用用C++編寫的本機(jī)程序
    kbuild也支持用C++編寫的本機(jī)程序。在此專門介紹是為了支持kconfig,并且
    在一般情況下不推薦使用。
    例子:
        #scripts/kconfig/Makefile
        hostprogs-y    := qconf
        qconf-cxxobjs    := qconf.o
    在上面的例子中,可執(zhí)行文件是由C++文件 qconf.cc編譯而成的,由
    $(qconf-cxxobjs)來(lái)標(biāo)識(shí)。
    如果qconf是由.c和.cc一起編譯的,那么就需要專門來(lái)標(biāo)識(shí)這些文件了。
    例子:
        #scripts/kconfig/Makefile
        hostprogs-y    := qconf
        qconf-cxxobjs    := qconf.o
        qconf-objs    := check.o
--- 4.5 控制本機(jī)程序的編譯選項(xiàng)
    當(dāng)編譯本機(jī)程序時(shí),有可能使用到特殊選項(xiàng)。程序經(jīng)常是利用$(HOSTCC)編譯
    ,其選項(xiàng)在 $(HOSTCFLAGS)變量中。
    可通過使用變量 HOST_EXTRACFLAGS,影響所有在Makefile文件中要?jiǎng)?chuàng)建的
    主機(jī)程序。
    例子:
        #scripts/lxdialog/Makefile
        HOST_EXTRACFLAGS += -I/usr/include/ncurses
    為一單個(gè)文件設(shè)置選項(xiàng),可按形式進(jìn)行:
    例子:
        #arch/ppc64/boot/Makefile
        HOSTCFLAGS_pinggyback.o    := -DKERNELBASE=$(KERNELBASE)
    同樣也可以給聯(lián)接器聲明一特殊選項(xiàng)。
    例子:
        #scripts/kconfig/Makefile
        HOSTLOADLIBES_qconf    := -L$(QTDIR)/lib
    當(dāng)聯(lián)接qconf時(shí),將會(huì)向聯(lián)接器傳遞附加選項(xiàng) "-L$(QTDIR)/lib"。
--- 4.6 編譯主機(jī)程序時(shí)
    Kbuild只在需要時(shí)編譯主機(jī)程序。
    有兩種方法:
    (1) 在一具體的規(guī)則中顯性列出所需要的文件
    例子:
        #drivers/pci/Makefile
        hostprogs-y := gen-devlist
        $(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
            ( cd $(obj); ./gen-devlist ) " 。
    并沒有對(duì)架構(gòu)特殊目標(biāo)的命名規(guī)則,但用命令 "make help" 可以列出所有的
    相關(guān)目標(biāo)。
    為了支持 "make help",$(archhelp) 必須被定義。
    例子:
        #arch/i386/Makefile
        define archhelp
          echo  '* bzImage    - Image (arch/$(ARCH)/boot/bzImage)'
        endef
    當(dāng)make 沒帶參數(shù)執(zhí)行時(shí),所遇到的第一個(gè)目標(biāo)將被執(zhí)行。在頂層,第一個(gè)目標(biāo)
    就是 all:。
    每個(gè)架構(gòu)Makefile都要默認(rèn)構(gòu)造一可啟動(dòng)的鏡像文件。
    在 "make help"中,默認(rèn)目標(biāo)就是被加亮的'*'。
    添加一新的前提文件到 all:,就可以構(gòu)造出一不同的vmlinux。
    例子:
        #arch/i386/Makefile
        all: bzImage
    當(dāng) make 沒有參數(shù)時(shí),bzImage將被構(gòu)造。
--- 6.5 構(gòu)造非Kbuild目標(biāo)
    extra-y
    extra-y 列出了在當(dāng)前目錄下,所要?jiǎng)?chuàng)建的附加文件,不包含任何已包含在
    obj-* 中的文件。
    用 extra-y 列目標(biāo),主要是兩個(gè)目的:
    1) 可以使Kbuild檢查命令行是否發(fā)生變化
       - 使用 $(call if_changed,xxx) 的時(shí)候
    2) 讓Kbuild知道哪些文件要在 "make clean" 時(shí)刪除
    例子:
        #arch/i386/kernel/Makefile
        extra-y := head.o init_task.o
    在此例子中,extra-y用來(lái)列出所有只編譯,但不聯(lián)接到 built-in.o的目標(biāo)
    文件。
--- 6.6 構(gòu)建啟動(dòng)鏡像的命令
    Kbuild 提供了幾個(gè)用在構(gòu)建啟動(dòng)鏡像時(shí)的宏。
    if_changed
    if_changed 為下列命令的基礎(chǔ)。
    使用方法:
        target: source(s) FORCE
            $(call if_changed,ld/objcopy/gzip)
    當(dāng)執(zhí)行該規(guī)則時(shí),就檢查是否有文件需要更新,或者在上次調(diào)用以后,命令行
    發(fā)生了改變。如果有選項(xiàng)發(fā)生了改變,后者會(huì)導(dǎo)致重新構(gòu)造。
    只有在 $(targets)列出的的目標(biāo)文件,才能使用 if_changed,否則命令行的
    檢查會(huì)失敗,并且目標(biāo)總會(huì)被重建。
    給 $(targets)的賦值沒有前綴 $(obj)/ 。 if_changed 可用來(lái)聯(lián)接自定義的
    Kbuild命令,關(guān)于Kbuild自定義命令請(qǐng)看 6.7節(jié)。
    注意:忘記 FORCE 是一種典型的錯(cuò)誤。還有一種普遍的錯(cuò)誤是,空格有的時(shí)候
    是有意義的;比如。下面的命令就會(huì)錯(cuò)誤(注意在逗號(hào)后面的那個(gè)多余的空格):
        target: source(s) FORCE
    #WRONG!#    $(call if_changed, ld/objcopy/gzip)
    ld
        聯(lián)接目標(biāo)。經(jīng)常是使用LDFLAGS_$@來(lái)設(shè)置ld的特殊選項(xiàng)。
    objcopy
        拷貝二進(jìn)制代碼。一般是在 arch/$(ARCH)/Makefile 中使用 OBJCOPYFLAGS。
    OBJCOPYFLAGS_$@ 可以用來(lái)設(shè)置附加選項(xiàng)。
    gzip
        壓縮目標(biāo)文件。盡可能的壓縮目標(biāo)文件。
    例子:
        #arch/i386/boot/Makefile
        LDFLAGS_bootsect  := -Ttext 0x0 -s --oformat binary
        LDFLAGS_setup      := -Ttext 0x0 -s --oformat binary -e begtext
        targets += setup setup.o bootsect bootsect.o
        $(obj)/setup $(obj)/bootsect: %: %.o FORCE
            $(call if_changed,ld)
    在這個(gè)例子中,有兩個(gè)可能的目標(biāo)文件,分別要求不同的聯(lián)接選項(xiàng)。定義聯(lián)接
    器的選項(xiàng)使用的是 LDFLAGS_$@ 語(yǔ)法,每個(gè)潛在的目標(biāo)一個(gè)。
    $(targets) 被分配給所有的潛在目標(biāo),因此知道目標(biāo)是哪些,并且還會(huì):
        1) 檢查命令行是否改變
        2) 在 "make clean" 時(shí),刪除目標(biāo)文件
    前提部分中的 ": %: %.o" 部分使我們不必在列出文件 setup.o 和
    bootsect.o 。
    注意:一個(gè)普遍的錯(cuò)誤是忘記了給 "target"賦值,導(dǎo)致在target中的文件總是
          無(wú)緣無(wú)故的被重新編譯。
--- 6.7 Kbuild自定義命令
    當(dāng)Kbuild的變量 KBUILD_VERBOSE 為0時(shí),只會(huì)顯示命令的簡(jiǎn)寫。
    如果要為自定義命令使用這一功能,需要設(shè)置2個(gè)變量:
    quiet_cmd_    - 要顯示的命令
          cmd_    - 要執(zhí)行的命令
    例子:
        #
        quiet_cmd_image = BUILD   $@
              cmd_image = $(obj)/tools/build $(BUILDFLAGS) \
                               $(obj)/vmlinux.bin > $@
        targets += bzImage
        $(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE
            $(call if_changed,image)
            @echo 'Kernel: $@ is ready'
    當(dāng)用"make KBUILD_VERBOSE=0"更新 $(obj)/bzImage 目標(biāo)時(shí)顯示:
    BUILD    arch/i386/boot/bzImage
--- 6.8 聯(lián)接器預(yù)處理腳本
    當(dāng)構(gòu)造 vmlinux 鏡像時(shí),使用聯(lián)接器腳本:
    arch/$(ARCH)/kernel/vmlinux.lds。
    該腳本是由在同一目錄下的 vmlinux.lds.S 生成的。
    Kbuild認(rèn)識(shí).lds文件,并包含由*.lds.S文件生成*.lds文件的規(guī)則。
    例子:
        #arch/i386/kernel/Makefile
        always := vmlinux.lds
        #Makefile
        export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
    $(always)的值是用來(lái)告訴Kbuild,構(gòu)造目標(biāo) vmlinux.lds。
    $(CPPFLAGS_vmlinux.lds),Kbuild在構(gòu)造目標(biāo)vmlinux.lds時(shí)所用到的特殊
    選項(xiàng)。
    當(dāng)構(gòu)造 *.lds 目標(biāo)時(shí),Kbuild要用到下列變量:
    CPPFLAGS    : 在頂層目錄中設(shè)置
    EXTRA_CPPFLAGS    : 可以在Kbuild Makefile中設(shè)置
    CPPFLAGS_$(@F)    : 目標(biāo)特別選項(xiàng)
              注意,此處的賦值用的完整的文件名。
    針對(duì)*.lds文件的Kbuild構(gòu)架還被用在許多具體架構(gòu)的文件中。(***不通***)
=== 7 Kbuild 變量
頂層Makefile輸出以下變量:
    VERSION,PATCHLEVEL,SUBLEVEL,EXTRAVERSION
    這些變量定義了當(dāng)前內(nèi)核的版本號(hào)。只有很少一部分Makefile會(huì)直接用到這些
    變量;可使用 $(KERNELRELEASE)代替。
    $(VERSION),$(PATCHLEVEL),和$(SUBLEVEL) 定義了最初使用的三個(gè)數(shù)字的版本
    號(hào),比如"2""4"和"0"。這三個(gè)值一般是數(shù)字。
    $(EXTRAVERSION) 為了補(bǔ)丁定義了更小的版本號(hào)。一般是非數(shù)字的字符串,比如
    "-pre4" ,或就空著。
    KERNELRELEASE
    $(KERNELRELEASE) 是一個(gè)字符串,類似"2.4.0-pre4",用于安裝目錄的命名或
       顯示當(dāng)前的版本號(hào)。一部分架構(gòu)Makefile使用該變量。
    ARCH
    該變量定義了目標(biāo)架構(gòu),比如"i386","arm" 或"sparc"。有些Kbuild Makefile
    根據(jù) $(ARCH) 決定編譯哪些文件。
    默認(rèn)情況下,頂層Makefile將其設(shè)置為本機(jī)架構(gòu)。如果是跨平臺(tái)編譯,用戶可以
    用下面的命令覆蓋該值:
        make ARCH=m68k ...
    INSTALL_PATH
    該變量為架構(gòu)Makefile定義了安裝內(nèi)核鏡像與 System.map 文件的目錄。
    主要用來(lái)指明架構(gòu)特殊的安裝路徑。
    INSTALL_MOD_PATH,MODLIB
    $(INSTALL_MOD_PATH) 為了安裝模塊,給 $(MODLIB) 聲明了前綴。該變量不能
    在Makefile中定義,但可以由用戶傳給Makefile。
    $(MODLIB) 具體的模塊安裝的路徑。頂層Makefile將$(MODLIB)定義為
    $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用戶可以通過命令行
    參數(shù)的形式將其覆蓋。
    INSTALL_MOD_STRIP
        
    如果該變量有定義,模塊在安裝之前,會(huì)被剝出符號(hào)表。如果
    INSTALL_MOD_STRIP 為 "1",就使用默認(rèn)選項(xiàng) --strip-debug。否則,
    INSTALL_MOD_STRIP 將作為命令 strip 的選項(xiàng)使用。
=== 8 Makefile語(yǔ)言
內(nèi)核的Makefile使用的是GNU Make。該Makefile只使用GNU Make已注明的功能,并使用
了許多GNU 的擴(kuò)展功能。
GNU Make支持基本的顯示處理過程的函數(shù)。內(nèi)核Makefile 使用了一種類似小說(shuō)的方式
,顯示"if"語(yǔ)句的構(gòu)造、處理過程。
GNU Make 有2個(gè)賦值操作符,":="和"="。":=",將對(duì)右邊的表達(dá)式求值,并將所求的值
賦給左邊。"="更像是一個(gè)公式定義,只是將右邊的值簡(jiǎn)單的賦值給左邊,當(dāng)左邊的表達(dá)
式被使用時(shí),才求值。
有時(shí)使用"="是正確的。但是,一般情況下,推薦使用":="。
=== 9 關(guān)于作者
第一版由 Michael Elizabeth Chastain,
修改:kai Germaschewski
      Sam Ravnborg
=== 10 TODO
- 描述Kbuild是如何用 _shipped 來(lái)支持 shipped 文件的。
- 生成分支頭文件
- 在第7節(jié)加入更多的變量


本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/27691/showart_728526.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP