免费高清特黄a大片,九一h片在线免费看,a免费国产一级特黄aa大,国产精品国产主播在线观看,成人精品一区久久久久,一级特黄aa大片,俄罗斯无遮挡一级毛片

分享

Linux內(nèi)核Makefile文件

 xiaochong 2007-02-09
Linux內(nèi)核Makefile文件

--譯自Linux2.6.x Kernel Makefiles
http://bbs./htm_data/12/0510/100065.html
本文檔描述了linux內(nèi)核的makefile文件。
=== 目錄
     === 1 概述
     === 2 角色分工
     === 3 內(nèi)核編譯文件
        --- 3.1 目標(biāo)定義
        --- 3.2 內(nèi)嵌對象 - obj-y
        --- 3.3 可加載模塊 - obj-m
        --- 3.4 導(dǎo)出符號
        --- 3.5 庫文件 - lib-y
        --- 3.6 目錄遞歸
        --- 3.7 編譯標(biāo)記
        --- 3.8 命令依賴
        --- 3.9 依賴關(guān)系
        --- 3.10 特殊規(guī)則
     === 4 輔助程序
        --- 4.1 簡單輔助程序
        --- 4.2 組合輔助程序
        --- 4.3 定義共享庫
        --- 4.4 C++語言使用方法
        --- 4.5 輔助程序編譯控制選項
        --- 4.6 何時建立輔助程序
        --- 4.7 使用hostprogs-$(CONFIG_FOO)
     === 5 編譯清除機制
     === 6 體系Makefile文件
        --- 6.1 變量設(shè)置
        --- 6.2 增加預(yù)設(shè)置項
        --- 6.3 目錄表
        --- 6.4 引導(dǎo)映像
        --- 6.5 編譯非內(nèi)核目標(biāo)
        --- 6.6 編譯引導(dǎo)映像命令
        --- 6.7 定制編譯命令
        --- 6.8 預(yù)處理連接腳本
        --- 6.9 $(CC)支持功能
     === 7 Kbuild變量
     === 8 Makefile語言
     === 9 Credits
     === 10 TODO

=== 1 概述
Makefile包括五部分:
     Makefile            頂層Makefile文件
     .config                  內(nèi)核配置文件
     arch/$(ARCH)/Makefile      機器體系Makefile文件
     scripts/Makefile.*      所有內(nèi)核Makefiles共用規(guī)則
     kbuild Makefiles      其它makefile文件
通 過內(nèi)核配置操作產(chǎn)生.config文件,頂層Makefile文件讀取該文件的配置。頂層Makefile文件負(fù)責(zé)產(chǎn)生兩個主要的程序:vmlinux (內(nèi)核image)和模塊。頂層Makefile文件根據(jù)內(nèi)核配置,通過遞歸編譯內(nèi)核代碼樹子目錄建立這兩個文件。頂層Makefile文件文本一個名為 arch/$(ARCH)/Makefile的機器體系makefile文件。機器體系Makefile文件為頂層makefile文件提供與機器相關(guān)的 信息。每一個子目錄有一個makefile文件,子目錄makefile文件根據(jù)上級目錄makefile文件命令啟動編譯。這些makefile使用. config文件配置數(shù)據(jù)構(gòu)建各種文件列表,并使用這些文件列表編譯內(nèi)嵌或模塊目標(biāo)文件。scripts/Makefile.*包含了所有的定義和規(guī)則, 與makefile文件一起編譯出內(nèi)核程序。

=== 2 角色分工
人們與內(nèi)核makefile存在四種不同的關(guān)系:
*用戶* 用戶使用"make menuconfig"或"make"命令編譯內(nèi)核。他們通常不讀或編輯內(nèi)核makefile文件或其他源文件。
*普通開發(fā)者* 普通開發(fā)者維護設(shè)備驅(qū)動程序、文件系統(tǒng)和網(wǎng)絡(luò)協(xié)議代碼,他們維護相關(guān)子系統(tǒng)的makefile文件,因此他們需要內(nèi)核makefile文件整體性的一般知識和關(guān)于kbuild公共接口的詳細知識。
*體系開發(fā)者* 體系開發(fā)者關(guān)注一個整體的體系架構(gòu),比如sparc或者ia64。體系開發(fā)者既需要掌握關(guān)于體系的makefile文件,也要熟悉內(nèi)核makefile文件。
*內(nèi)核開發(fā)者* 內(nèi)核開發(fā)者關(guān)注內(nèi)核編譯系統(tǒng)本身。他們需要清楚內(nèi)核makefile文件的所有方面。
本文檔的讀者對象是普通開發(fā)者和系統(tǒng)開發(fā)者。

=== 3 內(nèi)核編譯文件
內(nèi)核中大多數(shù)makefile文件是使用kbuild基礎(chǔ)架構(gòu)的makefile文件。本章介紹kbuild的makefile中的語法。
3.1節(jié)“目標(biāo)定義”是一個快速導(dǎo)引,后面各章有詳細介紹和實例。
--- 3.1 目標(biāo)定義
     目標(biāo)定義是makefile文件的主要部分(核心)。這些目標(biāo)定義行定義了如何編譯文件,特殊的兼容選項和遞歸子目錄。
      最簡單的makefile文件只包含一行:
     Example: obj-y += foo.o
    這行告訴kbuild在該目錄下名為foo.o的目標(biāo)文件(object),foo.o通過編譯foo.c或者foo.S而得到。
    如果foo.o編譯成一個模塊,則使用obj-m變量,因此常見寫法如下:
     Example: obj-$(CONFIG_FOO) += foo.o
     $(CONFIG_FOO)可以代表y(built-in對象)或m(module對象)。
      如果CONFIG_FOO不是y或m,那么這個文件不會被編譯和鏈接。
--- 3.2 內(nèi)嵌對象 - obj-y
    makefile文件將為編譯vmlinux的目標(biāo)文件放在$(obj-y)列表中,這些列表依賴于內(nèi)核配置。
      Kbuild編譯所有的$(obj-y)文件,然后調(diào)用"$(LD) -r"合并這些文件到一個built-in.o文件中。built-in.o經(jīng)過父makefile文件鏈接到vmlinux。$(obj-y)中的文件 順序很重要。列表中文件允許重復(fù),文件第一次出現(xiàn)將被鏈接到built-in.o,后續(xù)出現(xiàn)該文件將被忽略。
      鏈接順序之所以重要是因為一些函數(shù)在內(nèi)核引導(dǎo)時將按照他們出現(xiàn)的順序被調(diào)用,如函數(shù)(module_init() / __initcall)。所以要牢記改變鏈接順序意味著也要改變SCSI控制器的檢測順序和重數(shù)磁盤。
      例如: #drivers/isdn/i4l/Makefile
     # 內(nèi)核ISDN子系統(tǒng)和設(shè)備驅(qū)動程序Makefile
     # 每個配置項是一個文件列表
     obj-$(CONFIG_ISDN)         += isdn.o
     obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
--- 3.3 可加載模塊 - obj-m
  $(obj-m)表示對象文件(object files)編譯成可加載的內(nèi)核模塊。
  一個模塊可以通過一個源文件或幾個源文件編譯而成。makefile只需簡單地它們加到$(obj-m)。
      例如:#drivers/isdn/i4l/Makefile
        obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
    注意:在這個例子中$(CONFIG_ISDN_PPP_BSDCOMP)含義是‘m‘。
      如果內(nèi)核模塊通過幾個源文件編譯而成,使用以上同樣的方法。
      Kbuild需要知道通過哪些文件編譯模塊,因此需要設(shè)置一個$(<module_name>-objs)變量。
    例如:#drivers/isdn/i4l/Makefile
     obj-$(CONFIG_ISDN) += isdn.o
     isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
     在這個例子中,模塊名isdn.o. Kbuild首先編譯$(isdn-objs)中的object文件,然后運行"$(LD) -r"將列表中文件生成isdn.o.
  Kbuild使用后綴-objs、-y識別對象文件。這種方法允許makefile使用CONFIG_符號值確定一個object文件是否是另外一個object的組成部分。
     例如: #fs/ext2/Makefile
        obj-$(CONFIG_EXT2_FS)     += ext2.o
        ext2-y := balloc.o bitmap.o
        ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
     在這個例子中,如果$(CONFIG_EXT2_FS_XATTR)表示‘y‘,則ext2.o只有xattr.o組成部分。
     注意: 當(dāng)然,當(dāng)你將對象文件編譯到內(nèi)核時,以上語法同樣有效。因此,如果CONFIG_EXT2_FS=y,Kbuild將先編譯ext2.o文件,然后鏈接到built-in.o。
--- 3.4 導(dǎo)出符號目標(biāo)
      在makefile文件中沒有特別導(dǎo)出符號的標(biāo)記。
--- 3.5 庫文件 - lib-y
      obj-*中的object文件用于模塊或built-in.o編譯。object文件也可能編譯到庫文件中--lib.a。
      所有羅列在lib-y中的object文件都將編譯到該目錄下的一個單一的庫文件中。
      包含在0bj-y中的object文件如果也列舉在lib-y中將不會包含到庫文件中,因為他們不能被訪問。但lib-m中的object文件將被編譯進lib.a庫文件。
      注意在相同的makefile中可以列舉文件到buit-in內(nèi)核中也可以作為庫文件的一個組成部分。因此在同一個目錄下既可以有built-in.o也可以有l(wèi)ib.a文件。
      例如:#arch/i386/lib/Makefile
        lib-y   := checksum.o delay.o
     這樣將基于checksum.o、delay.o創(chuàng)建一個lib.a文件。
      對于內(nèi)核編譯來說,lib.a文件被包含在libs-y中。將“6.3 目錄表”。
      lib-y通常被限制使用在lib/和arch/*/lib目錄中。
--- 3.6 目錄遞歸
     makefile文件負(fù)責(zé)編譯當(dāng)前目錄下的目標(biāo)文件,子目錄中的文件由子目錄中的makefile文件負(fù)責(zé)編譯。編譯系統(tǒng)將使用obj-y和obj-m自動遞歸編譯各個子目錄中文件。
     如果ext2是一個子目錄,fs目錄下的makefile將使用以下賦值語句是編譯系統(tǒng)編譯ext2子目錄。
     例如: #fs/Makefile
        obj-$(CONFIG_EXT2_FS) += ext2/
     如果CONFIG_EXT2_FS設(shè)置成‘y(built-in)或‘m‘(modular),則對應(yīng)的obj-變量也要設(shè)置,內(nèi)核編譯系統(tǒng)將進入ext2目錄編譯文件。
      內(nèi)核編譯系統(tǒng)只使用這些信息來決定是否需要編譯這個目錄,子目錄中makefile文件規(guī)定那些文件編譯為模塊那些是內(nèi)核內(nèi)嵌對象。
      當(dāng)指定目錄名時使用CONFIG_變量是一種良好的做法。如果CONFIG_選項不為‘y‘或‘m‘,內(nèi)核編譯系統(tǒng)就會跳過這個目錄。
--- 3.7 編譯標(biāo)記
  EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
  所有的EXTRA_變量只能使用在定義該變量后的makefile文件中。EXTRA_變量被makefile文件所有的執(zhí)行命令語句所使用。
     $(EXTRA_CFLAGS)是使用$(CC)編譯C文件的選項。
     例如: # drivers/sound/emu10k1/Makefile
           EXTRA_CFLAGS += -I$(obj)
           ifdef
            DEBUG EXTRA_CFLAGS += -DEMU10K1_DEBUG
            endif
     定義這個變量是必須的,因為頂層makefile定義了$(CFLAGS)變量并使用該變量編譯整個代碼樹。
     $(EXTRA_AFLAGS)是每個目錄編譯匯編語言源文件的選項。
     例如: #arch/x86_64/kernel/Makefile
           EXTRA_AFLAGS := -traditional
     $(EXTRA_LDFLAGS)和$(EXTRA_ARFLAGS)用于每個目錄的$(LD)和$(AR)選項。
     例如: #arch/m68k/fpsp040/Makefile
           EXTRA_LDFLAGS := -x
  CFLAGS_$@, AFLAGS_$@
     CFLAGS_$@和AFLAGS_$@只使用到當(dāng)前makefile文件的命令中。
     $(CFLAGS_$@)定義了使用$(CC)的每個文件的選項。$@部分代表該文件。
     例如: # 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
     這三行定義了aha152x.o、gdth.o和seagate.o文件的編譯選項。
     $(AFLAGS_$@)使用在匯編語言代碼文件中,具有同上相同的含義。
     例如: # arch/arm/kernel/Makefile
           AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
           AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
--- 3.9 依賴關(guān)系
     內(nèi)核編譯記錄如下依賴關(guān)系:
      1) 所有的前提文件(both *.c and *.h)
      2) CONFIG_ 選項影響到的所有文件
      3) 編譯目標(biāo)文件使用的命令行
     因此,假如改變$(CC)的一個選項,所有相關(guān)的文件都要重新編譯。
--- 3.10 特殊規(guī)則
      特殊規(guī)則使用在內(nèi)核編譯需要規(guī)則定義而沒有相應(yīng)定義的時候。典型的例子如編譯時頭文件的產(chǎn)生規(guī)則。其他例子有體系makefile編譯引導(dǎo)映像的特殊規(guī)則。特殊規(guī)則寫法同普通的Make規(guī)則。
     Kbuild(應(yīng)該是編譯程序)在makefile所在的目錄不能被執(zhí)行,因此所有的特殊規(guī)則需要提供前提文件和目標(biāo)文件的相對路徑。
     定義特殊規(guī)則時將使用到兩個變量:
  $(src): $(src)是對于makefile文件目錄的相對路徑,當(dāng)使用代碼樹中的文件時使用該變量$(src)。
  $(obj): $(obj)是目標(biāo)文件目錄的相對路徑。生成文件使用$(obj)變量。
     例如: #drivers/scsi/Makefile
     $(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
        $(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl
     這就是使用普通語法的特殊編譯規(guī)則。
     目標(biāo)文件依賴于兩個前提文件。目標(biāo)文件的前綴是$(obj), 前提文件的前綴是$(src)(因為它們不是生成文件)。

=== 4 輔助程序
    內(nèi)核編譯系統(tǒng)支持在編譯(compliation)階段編譯主機可執(zhí)行程序。為了使用主機程序需要兩個步驟:第一個步驟使用hostprogs-y變量告 訴內(nèi)核編譯系統(tǒng)有主機程序可用。第二步給主機程序添加潛在的依賴關(guān)系。有兩種方法,在規(guī)則中增加依賴關(guān)系或使用$(always)變量。具體描述如下。
--- 4.1 簡單輔助程序
     在一些情況下需要在主機上編譯和運行主機程序。下面這行告訴kbuild在主機上建立bin2hex程序。
     例如: hostprogs-y := bin2hex
     Kbuild假定使用makefile相同目錄下的單一C代碼文件bin2hex.c編譯bin2hex。
--- 4.2 組合輔助程序
     主機程序也可以由多個object文件組成。定義組合輔助程序的語法同內(nèi)核對象的定義方法。
     $(<executeable>-objs)包含了所有的用于鏈接最終可執(zhí)行程序的對象。
     例如: #scripts/lxdialog/Makefile
        hostprogs-y   := lxdialog
        lxdialog-objs := checklist.o lxdialog.o
     擴展名.o文件都編譯自對應(yīng)的.c文件。在上面的例子中checklist.c編譯成checklist.o,lxdialog.c編譯為lxdialog.o。最后兩個.o文件鏈接成可執(zhí)行文件lxdialog。
     注意:語法<executable>-y不能用于定義主機程序。
--- 4.3 定義共享庫
     擴展名為.so的對象是共享庫文件,并且是位置無關(guān)的object文件。內(nèi)核編譯系統(tǒng)提供共享庫使用支持,但使用方法有限制。在下面例子中l(wèi)ibkconfig.so庫文件被鏈接到可執(zhí)行文件conf中。
     例如: #scripts/kconfig/Makefile
           hostprogs-y   := conf
           conf-objs     := conf.o libkconfig.so
           libkconfig-objs := expr.o type.o
     共享庫文件需要對應(yīng)的-objs定義, 在上面例子中庫libkconfig由兩個對象組成:expr.o和type.o。expr.o和type.o將被編譯為位置無關(guān)代碼并被鏈接如libkconfig.so。共享庫不支持C++語言。
--- 4.4 C++語言使用方法
     內(nèi)核編譯系統(tǒng)提供了對C++主機程序的支持以用于內(nèi)核配置,但不主張其它方面使用這種方法。
     例如: #scripts/kconfig/Makefile
           hostprogs-y   := qconf
           qconf-cxxobjs := qconf.o
     在上面例子中可執(zhí)行文件由C++文件qconf.cc組成 - 通過$(qconf-cxxobjs)標(biāo)識。
     如果qconf由.c和.cc文件混合組成,附加行表示這種情況。
     例如: #scripts/kconfig/Makefile
           hostprogs-y   := qconf
           qconf-cxxobjs := qconf.o
           qconf-objs   := check.o
--- 4.5 輔助程序編譯控制選項
     當(dāng)編譯主機程序時仍然可以使用$(HOSTCFLAGS)設(shè)置編譯選項傳遞給$(HOSTCC)。這些選項將影響所有使用變量HOST_EXTRACFLAG的makefile創(chuàng)建的主機程序。
     例如: #scripts/lxdialog/Makefile
           HOST_EXTRACFLAGS += -I/usr/include/ncurses
     為單個文件設(shè)置選項使用下面方式:
     例如: #arch/ppc64/boot/Makefile
     HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)
     也可以使用附加鏈接選項:
     例如: #scripts/kconfig/Makefile
           HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
     當(dāng)鏈接qconf時將使用外部選項"-L$(QTDIR)/lib"。
--- 4.6 何時建立輔助程序
     只有當(dāng)需要時內(nèi)核編譯系統(tǒng)才會編譯主機程序。有兩種方式:
     (1) 在特殊規(guī)則中作為隱式的前提需求
     例如: #drivers/pci/Makefile
     hostprogs-y := gen-devlist
     $(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
              ( cd $(obj); ./gen-devlist ) < $<
     編譯目標(biāo)文件$(obj)/devlist.h需要先建立$(obj)/gen-devlist。注意在特殊規(guī)則中使用主機程序必須加前綴$(obj)。
     (2) 使用$(always)
     當(dāng)沒有合適的特殊規(guī)則可以使用,并且在進入makefile文件時就要建立主機程序,可以使用變量$(always)。
     例如: #scripts/lxdialog/Makefile
           hostprogs-y   := lxdialog
           always     := $(hostprogs-y)
     這樣就告訴內(nèi)核編譯系統(tǒng)即使沒有任何規(guī)則使用lxdialog也要編譯它。
--- 4.7 使用hostprogs-$(CONFIG_FOO)
     在Kbuild文件中典型模式如下:
     例如: #scripts/Makefile
           hostprogs-$(CONFIG_KALLSYMS) += kallsyms
     對Kbuild來說‘y‘用于內(nèi)嵌對象‘m‘用于模塊。
     因此如果config符號是‘m‘,編譯系統(tǒng)也將創(chuàng)建該程序。換句話說內(nèi)核編譯系統(tǒng)等同看待hostprogs-m和hostprogs-y。但如果不涉及到CONFIG符號僅建議使用hostprogs-y。

=== 5 編譯清除機制
  "make clean"命令刪除在編譯內(nèi)核生成的大部分文件,例如主機程序,列舉在 $(hostprogs-y)、$(hostprogs-m)、$(always)、$(extra-y)和$(targets)中目標(biāo)文件都將被刪除。 代碼目錄數(shù)中的"*.[oas]"、"*.ko"文件和一些由編譯系統(tǒng)產(chǎn)生的附加文件也將被刪除。
  附加文件可以使用$(clean-files)進行定義。
     例如: #drivers/pci/Makefile
           clean-files := devlist.h classlist.h
  當(dāng)執(zhí)行"make clean"命令時, "devlist.h classlist.h"兩個文件將被刪除。內(nèi)核編譯系統(tǒng)默認(rèn)這些文件與makefile具有相同的相對路徑,否則需要設(shè)置以‘/‘開頭的絕對路徑。
  刪除整個目錄使用以下方式:
  例如: #scripts/package/Makefile
     clean-dirs := $(objtree)/debian/
  這樣就將刪除包括子目錄在內(nèi)的整個debian目錄。如果不使用以‘/‘開頭的絕對路徑內(nèi)核編譯系統(tǒng)見默認(rèn)使用相對路徑。
  通常內(nèi)核編譯系統(tǒng)根據(jù)"obj-* := dir/"進入子目錄,但是在體系makefile中需要顯式使用如下方式:
     例如: #arch/i386/boot/Makefile
           subdir- := compressed/
  上面賦值語句指示編譯系統(tǒng)執(zhí)行"make clean"命令時進入compressed/目錄。
  在編譯最終的引導(dǎo)映像文件的makefile中有一個可選的目標(biāo)對象名稱是archclean。
     例如: #arch/i386/Makefile
           archclean:
              $(Q)$(MAKE) $(clean)=arch/i386/boot
  當(dāng)執(zhí)行"make clean"時編譯器進入arch/i386/boot并象通常一樣工作。arch/i386/boot中的makefile文件可以使用subdir-標(biāo)識進入更下層的目錄。
  注意1: arch/$(ARCH)/Makefile不能使用"subdir-",因為它被包含在頂層makefile文件中,在這個位置編譯機制是不起作用的。
  注意2: 所有列舉在core-y、libs-y、drivers-y和net-y中的目錄將被"make clean"命令清除。

=== 6 體系Makefile文件
  在開始進入各個目錄編譯之前,頂層makefile文件設(shè)置編譯環(huán)境和做些準(zhǔn)備工作。頂層makefile文件包含通用部分,arch/$(ARCH) /Makefile包含該體系架構(gòu)所需的設(shè)置。因此arch/$(ARCH)/Makefile會設(shè)置一些變量和少量的目標(biāo)。
  當(dāng)編譯時將按照以下大概步驟執(zhí)行:
1) 配置內(nèi)核 => 產(chǎn)生 .config文件
2) 保存內(nèi)核版本到include/linux/version.h文件中
3) 符號鏈接include/asm to include/asm-$(ARCH)
4) 更新所有目標(biāo)對象的其它前提文件
  - 附加前提文件定義在arch/$(ARCH)/Makefile文件中
5) 遞歸進入init-* core* drivers-* net-* libs-*中的所有子目錄和編譯所有的目標(biāo)對象
  - 上面變量值都引用到arch/$(ARCH)/Makefile文件。
6) 鏈接所有的object文件生成vmlinux文件,vmlinux文件放在代碼樹根目錄下。
  最開始鏈接的幾個object文件列舉在arch/$(ARCH)/Makefile文件的head-y變量中。
7) 最后體系makefile文件定義編譯后期處理規(guī)則和建立最終的引導(dǎo)映像bootimage。
  - 包括創(chuàng)建引導(dǎo)記錄
  - 準(zhǔn)備initrd映像和相關(guān)處理
--- 6.1 變量設(shè)置
  LDFLAGS      $(LD)一般選項
     選項使用于鏈接器的所有調(diào)用中。通常定義emulation就可以了。
     例如: #arch/s390/Makefile
           LDFLAGS   := -m elf_s390
      注意: EXTRA_LDFLAGS和LDFLAGS_$@可以進一步訂制使用選項,將第7章。
  LDFLAGS_MODULE       $(LD)鏈接模塊的選項
     LDFLAGS_MODULE通常設(shè)置$(LD)鏈接模塊的.ko選項。
     默認(rèn)為"-r"即可重定位輸出文件。
  LDFLAGS_vmlinux   $(LD)鏈接vmlinux選項
     LDFLAGS_vmlinux定義鏈接最終vmlinux時鏈接器的選項。
     LDFLAGS_vmlinux支持使用LDFLAGS_$@。
     例如: #arch/i386/Makefile
           LDFLAGS_vmlinux := -e stext
  OBJCOPYFLAGS      objcopy選項
     當(dāng)使用$(call if_changed,objcopy)轉(zhuǎn)化a .o文件時,OBJCOPYFLAGS中的選項將被使用。
     $(call if_changed,objcopy)經(jīng)常被用作為vmlinux產(chǎn)生原始的二進制文件。
     例如: #arch/s390/Makefile
           OBJCOPYFLAGS := -O binary
          #arch/s390/boot/Makefile
           $(obj)/image: vmlinux FORCE $(call if_changed,objcopy)
     在上面例子中$(obj)/image是vmlinux的二進制版本文件。$(call if_changed,xxx)
的使用方法見后。
  AFLAGS   $(AS)匯編選項
     默認(rèn)值見頂層Makefile文件
     針對每個體系需要另外添加和修改它。
     例如: #arch/sparc64/Makefile
           AFLAGS += -m64 -mcpu=ultrasparc
  CFLAGS      $(CC)編譯器選項
     默認(rèn)值見頂層Makefile文件
     針對每個體系需要另外添加和修改它。
     通常CFLAGS變量值取決于內(nèi)核配置。
     例如: #arch/i386/Makefile
           cflags-$(CONFIG_M386) += -march=i386
           CFLAGS += $(cflags-y)
     許多體系Makefiles文件動態(tài)啟動市場目標(biāo)機器上的C編譯器檢測支持的選項:
           #arch/i386/Makefile
           ...
           cflags-$(CONFIG_MPENTIUMII)   += $(call cc-option,\
                 -march=pentium2,-march=i686) ...
           # Disable unit-at-a-time mode ...
           CFLAGS += $(call cc-option,-fno-unit-at-a-time)
           ...
     第一個例子當(dāng)config選項是‘y‘時將被選中。
  CFLAGS_KERNEL      $(CC)編譯built-in對象的選項
     $(CFLAGS_KERNEL)包含外部C編譯器選項編譯本地內(nèi)核代碼。
  CFLAGS_MODULE      $(CC)編譯模塊選項
     $(CFLAGS_MODULE)包含外部C編譯器選項編譯可加載內(nèi)核代碼。
--- 6.2 增加預(yù)設(shè)置項
     prepare: 這個規(guī)則用于列舉開始進入子目錄編譯前需要的前提文件。通常是些包含匯編常量的頭文件。
     例如:
     #arch/s390/Makefile
     prepare: include/asm-$(ARCH)/offsets.h
     在這個例子中include/asm-$(ARCH)/offsets.h將在進入子目錄前編譯。
      詳見XXX-TODO文件描述了kbuild如何產(chǎn)生offset頭文件。
--- 6.3 目錄表
     體系makefile文件和頂層makefile文件共同定義了如何建立vmlinux文件的變量。注意沒有體系相關(guān)的模塊對象定義部分:所有的模塊對象都是體系無關(guān)的。
  head-y, init-y, core-y, libs-y, drivers-y, net-y
     $(head-y) 列舉首先鏈接到vmlinux的對象文件。
     $(libs-y) 列舉了能夠找到lib.a文件的目錄。
     其余的變量列舉了能夠找到內(nèi)嵌對象文件的目錄。
     $(init-y) 列舉的對象位于$(head-y)對象之后。
     然后是如下位置秩序:
     $(core-y), $(libs-y), $(drivers-y) 和 $(net-y)。
     頂層makefile定義了所有同用目錄,arch/$(ARCH)/Makefile文件只需增加體系相關(guān)的目錄。
     例如: #arch/sparc64/Makefile
           core-y += arch/sparc64/kernel/
           libs-y += arch/sparc64/prom/ arch/sparc64/lib/
           drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
--- 6.4 引導(dǎo)映像
     體系makefile文件定義了編譯vmlinux文件的目標(biāo)對象,將它們壓縮和封裝成引導(dǎo)代碼,并復(fù)制到合適的位置。這包括各種安裝命令。如何定義實際的目標(biāo)對象無法為所有的體系結(jié)構(gòu)提供標(biāo)準(zhǔn)化的方法。
     附加處理過程常位于arch/$(ARCH)/下的boot/目錄。
     內(nèi)核編譯系統(tǒng)無法在boot/目錄下提供一種便捷的方法創(chuàng)建目標(biāo)系統(tǒng)文件。因此arch/$(ARCH)/Makefile要調(diào)用make命令在 boot/目錄下建立目標(biāo)系統(tǒng)文件。建議使用的方法是在arch/$(ARCH)/Makefile中設(shè)置調(diào)用,并且使用完整路徑引用arch/$ (ARCH)/boot/Makefile。
     例如: #arch/i386/Makefile
           boot := arch/i386/boot
           bzImage: vmlinux
              $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
     建議使用"$(Q)$(MAKE) $(build)=<dir>"方式在子目錄中調(diào)用make命令。
     沒有定義體系目標(biāo)系統(tǒng)文件的規(guī)則,但執(zhí)行"make help"命令要列出所有目標(biāo)系統(tǒng)文件,因此必須定義$(archhelp)變量。
     例如: #arch/i386/Makefile
     define
        archhelp echo ‘* bzImage     - Image (arch/$(ARCH)/boot/bzImage)‘
      endef
     當(dāng)執(zhí)行不帶參數(shù)的make命令時,將首先編譯第一個目標(biāo)對象。在頂層makefile中第一個目標(biāo)對象是all:。
     一個體系結(jié)構(gòu)需要定義一個默認(rèn)的可引導(dǎo)映像。
     "make help"命令的默認(rèn)目標(biāo)是以*開頭的對象。
     增加新的前提文件給all目標(biāo)可以設(shè)置不同于vmlinux的默認(rèn)目標(biāo)對象。
     例如: #arch/i386/Makefile
           all: bzImage
     當(dāng)執(zhí)行不帶參數(shù)的"make"命令時,bzImage文件將被編譯。
--- 6.5 編譯非內(nèi)核目標(biāo)
  extra-y
     extra-y定義了在當(dāng)前目錄下創(chuàng)建沒有在obj-*定義的附加的目標(biāo)文件。
     在extra-y中列舉目標(biāo)是處于兩個目的:
      1) 是內(nèi)核編譯系統(tǒng)在命令行中檢查變動情況
        - 當(dāng)使用$(call if_changed,xxx)時
      2) 內(nèi)核編譯系統(tǒng)知道執(zhí)行"make clean"命令時刪除哪些文件
     例如: #arch/i386/kernel/Makefile
           extra-y := head.o init_task.o
     上面例子extra-y中的對象文件將被編譯但不會練接到built-in.o中。
--- 6.6 編譯引導(dǎo)映像命令
     Kbuild提供了一些編譯引導(dǎo)映像有用的宏。
  if_changed
     if_changed是后面命令使用的基礎(chǔ)。
     用法:
        target: source(s)
            FORCE $(call if_changed,ld/objcopy/gzip)
     當(dāng)這條規(guī)則被使用時它將檢查哪些文件需要更新,或命令行被改變。后面這種情況將迫使重新編譯編譯選項被改變的執(zhí)行文件。使用if_changed的目標(biāo)對象必須列舉在$(targets)中,否則命令行檢查將失敗,目標(biāo)一直會編譯。
     賦值給$(targets)的對象沒有$(obj)/前綴。
     if_changed也可以和定制命令配合使用,見6.7"kbuild定制命令"。
     注意: 一個常見錯誤是忘記了FORCE前導(dǎo)詞。
  ld
      鏈接目標(biāo)。常使用LDFLAGS_$@作為ld的選項。
  objcopy
      復(fù)制二進制文件。常用于arch/$(ARCH)/Makefile中和使用OBJCOPYFLAGS作為選項。
     也可以用OBJCOPYFLAGS_$@設(shè)置附加選項。
  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)
      在上面例子中有兩個可能的目標(biāo)對象,分別需要不同的鏈接選項。使用LDFLAGS_$@語法為每個目標(biāo)對象設(shè)置不同的鏈接選項。
     $(targets)包含所有的目標(biāo)對象,因此內(nèi)核編譯系統(tǒng)知道所有的目標(biāo)對象并且將:
      1) 檢查命令行的改變情況
      2) 執(zhí)行make clean命令時刪除目標(biāo)對象
     ": %: %.o"是簡寫方法,減寫setup.o和bootsect.o文件。
     注意: 常犯錯誤是忘記"target :="語句,導(dǎo)致沒有明顯的原因目標(biāo)文件被重新編譯。
--- 6.7 定制編譯命令
     當(dāng)執(zhí)行帶KBUILD_VERBOSE=0參數(shù)的編譯命令時命令的簡短信息會被顯示。要讓定制命令具有這種功能需要設(shè)置兩個變量:
     quiet_cmd_<command> - 將被顯示的內(nèi)容
      cmd_<command>      - 被執(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‘
     執(zhí)行"make KBUILD_VERBOSE=0"命令編譯$(obj)/bzImage目標(biāo)時將顯示:
     BUILD   arch/i386/boot/bzImage
--- 6.8 預(yù)處理連接腳本
     當(dāng)編譯vmlinux映像時將使用arch/$(ARCH)/kernel/vmlinux.lds鏈接腳本。
     相同目錄下的vmlinux.lds.S文件是這個腳本的預(yù)處理的變體。內(nèi)核編譯系統(tǒng)知曉.lds文件并使用規(guī)則*lds.S -> *lds。
     例如: #arch/i386/kernel/Makefile
           always := vmlinux.lds
           #Makefile
           export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
     $(always)賦值語句告訴編譯系統(tǒng)編譯目標(biāo)是vmlinux.lds。$(CPPFLAGS_vmlinux.lds)賦值語句告訴編譯系統(tǒng)編譯vmlinux.lds目標(biāo)的編譯選項。
     編譯*.lds時將使用到下面這些變量:
     CPPFLAGS      : 定義在頂層Makefile
     EXTRA_CPPFLAGS      : 可以設(shè)置在編譯的makefile文件中
     CPPFLAGS_$(@F) : 目標(biāo)編譯選項。注意要使用文件全名。
--- 6.9 $(CC)支持功能
     內(nèi)核可能會用不同版本的$(CC)進行編譯,每個版本有不同的性能和選項,內(nèi)核編譯系統(tǒng)提供基本的支持用于驗證$(CC)選項。$(CC)通常是gcc編譯器,但其它編譯器也是可以。
  cc-option cc-option 用于檢測$(CC)是否支持給定的選項,如果不支持就使用第二個可選項。
     例如: #arch/i386/Makefile
           cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
     在上面例子中如果$(CC)支持-march=pentium-mmx則cflags-y等于該值,否則等于-march-i586。如果沒有第二個可選項且第一項不支持則cflags-y沒有被賦值。
  cc-option-yn cc-option-yn用于檢測gcc是否支持給定的選項,支持返回‘y‘否則‘n‘。
     例如: #arch/ppc/Makefile
           biarch := $(call cc-option-yn, -m32)
           aflags-$(biarch) += -a32
           cflags-$(biarch) += -m32
     在上面例子中如果$(CC)支持-m32選項則$(biarch)設(shè)置為y。當(dāng)$(biarch)等于y時,變量$(aflags-y)和$(cflags-y)將分別等于-a32和-m32。
  cc-option-align gcc版本>= 3.0用于定義functions、loops等邊界對齊選項。
     gcc < 3.00
        cc-option-align = -malign
      gcc >= 3.00
        cc-option-align = -falign
     例如:
        CFLAGS += $(cc-option-align)-functions=4
     在上面例子中對于gcc >= 3.00來說-falign-functions=4,gcc < 3.00版本使用-malign-functions=4。
  cc-version cc-version返回$(CC)編譯器數(shù)字版本號。
     版本格式是<major><minor>,均為兩位數(shù)字。例如gcc 3.41將返回0341。
     當(dāng)一個特定$(CC)版本在某個方面有缺陷時cc-version是很有用的。例如-mregparm=3在一些gcc版本會失敗盡管gcc接受這個選項。
     例如: #arch/i386/Makefile
           GCC_VERSION := $(call cc-version)
           cflags-y += $(shell \
           if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
     在上面例子中-mregparm=3只使用在版本大于等于3.0的gcc中。
=== 7 Kbuild變量
  頂層Makefile文件導(dǎo)出下面這些變量:
  VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
     這幾個變量定義了當(dāng)前內(nèi)核版本號。很少體系體系Makefiles文件直接使用他們,常用$(KERNELRELEASE)代替。
     $(VERSION)、$(PATCHLEVEL)和$(SUBLEVEL)定義了三個基本部分版本號,例如"2", "4",和"0"。這三個變量一直使用數(shù)值表示。
     $(EXTRAVERSION)定義了更細的補釘號,通常是短橫跟一些非數(shù)值字符串,例如"-pre4"。
  KERNELRELEASE
     $(KERNELRELEASE)是一個單一字符如"2.4.0-pre4",適合用于構(gòu)造安裝目錄和顯示版本字符串。一些體系文件使用它用于以上目的。
  ARCH
     這個變量定義了目標(biāo)系統(tǒng)體系結(jié)構(gòu),例如"i386"、“arm"、"sparc". 一些內(nèi)核編譯文件測試$(ARCH)用于確定編譯哪個文件。默認(rèn)情況下頂層Makefile文件設(shè)置$(ARCH)為主機相同的系統(tǒng)體系。當(dāng)交叉編譯編譯 時,用戶可以使用命令行改變$(ARCH)值:
        make ARCH=m68k ...
  INSTALL_PATH
     這個變量定義了體系Makefiles文件安裝內(nèi)核映項和System.map文件的路徑。
  INSTALL_MOD_PATH, MODLIB
     $(INSTALL_MOD_PATH)定義了模塊安裝變量$(MODLIB)的前綴。這個變量通常不在Makefile文件中定義,如果需要可以由用戶添加。
     $(MODLIB)定義了模塊安裝目錄。
     頂層Makefile定義$(MODLIB)為$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用戶可以使用命令行修改這個值。
=== 8 Makefile語言
  內(nèi)核Makefiles設(shè)計目標(biāo)用于運行GNU Make程序。Makefiles僅使用GNU Make提到的特性,但使用了較多的GNU擴展部分。
  GNU Make程序支持基本的列表處理功能。內(nèi)核Makefiles文件結(jié)合"if"語句使用了簡單的列表建立和維護功能。
  GNU Make程序有兩種賦值操作符:":="和"="。 ":="執(zhí)行時立即計算右值并賦值給左值。"="類似公式定義,當(dāng)每次使用左值要被使用時計算右值并賦給它。
  一些情況中使用"="合適,而一些情況中使用":="才是正確選擇。
=== 9 Credits
  Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net> Updates
by Kai Germaschewski <
kai@tp1.ruhr-uni-bochum.de > Updates by Sam Ravnborg < sam@ravnborg.org >
=== 10 TODO
- Describe how kbuild support shipped files with _shipped.
- Generating offset header files.
- Add more variables to section 7?

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多