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

分享

Linux Kernel Makefile

 womking 2007-06-29


Linux Kernel Makefile

1、概述
Makefile 由五個(gè)部分組成:

Makefile:頂層 Makefile。
.config:內(nèi)核配置文件。
arch/*/Makefile:體系結(jié)構(gòu) Makefiles。
子目錄 Makefile:大約三百個(gè)。
Rules.make:為所有子目錄 Makefile 提供通用規(guī)則。
頂層 Makefile 讀入在內(nèi)核配置過程中生成的 .config 文件。

頂層 Makefile 負(fù)責(zé)兩個(gè)主要產(chǎn)品的創(chuàng)建:vminux (常駐內(nèi)核映象) 和模塊 (任何模塊文件)。它通過遞歸下降到內(nèi)核源代碼樹以創(chuàng)建這些目標(biāo)。需要進(jìn)入的子目錄由內(nèi)核配置確定。

頂層 Makefile 引入一個(gè)名為 arch/$(ARCH)/Makefile 的體系結(jié)構(gòu) Makefile。體系結(jié)構(gòu) Makefile 為頂層 Makefile 提供體系結(jié)構(gòu)特定的信息。

每一子目錄都有一個(gè) Makefile 以完成從上層傳遞來的命令。子目錄 Makefile 使用來自 .config 文件的信息以構(gòu)造各種文件列表,而后引入 Rules.make 中的通用規(guī)則。

Rules.make 定義了所有子目錄 Makefile 的通用規(guī)則。它的一個(gè)變量列表組成了它的公共界面。而后它根據(jù)這些列表聲明規(guī)則。

2、誰需要什么
人們跟內(nèi)核的 Makefile 有四種不同的關(guān)系。

用戶是創(chuàng)建內(nèi)核的人。這些人輸入諸如“make menuconfig”或 “make bzImage”之類的命令。他們通常并不閱讀或編輯內(nèi)核 Makefile (或任何其它源代碼)。

普 通開發(fā)者是開發(fā)諸如設(shè)備驅(qū)動程序、文件系統(tǒng)或網(wǎng)絡(luò)協(xié)議的人。這些人需要為他們開發(fā)的子系統(tǒng)維護(hù)用于該子系統(tǒng)的子目錄 Makefile。為了有效地完成這一維護(hù)任務(wù),他們需要一些關(guān)于內(nèi)核 Makefile 的全局性的知識,以及一些關(guān)于 Rules.make 公共界面的細(xì)節(jié)。

體系結(jié)構(gòu)開發(fā)者是開發(fā)整個(gè)體系結(jié)構(gòu) (例如 spare 或 ia64) 的人。體系結(jié)構(gòu)開發(fā)者需要理解體系結(jié)構(gòu) Makefile 以及子目錄 Makefile。

Kbuild 開發(fā)者是開發(fā)內(nèi)核創(chuàng)建系統(tǒng)本身的人。這些人需要知道內(nèi)核 Makefile 的所有方面。

本文檔是面向普通開發(fā)者和體系結(jié)構(gòu)開發(fā)者的。

3、Makefile 語言
內(nèi)核 Makefile 被設(shè)計(jì)為使用 GNU Make。這些 Makefiles 只使用 GNU Make 文檔說明了的功能,但它們使用了很多 GNU 擴(kuò)展。

GNU Make 支持基本列表處理函數(shù)。內(nèi)核 Makefile 使用帶有少量 if 語句的新穎的列表創(chuàng)建和操作風(fēng)格。

GNU Make 有兩種賦值操作符:“:=”和“=“。 ":= ”立即對右側(cè)進(jìn)行求值并且將結(jié)果字符串存儲于左側(cè)變量中。“=”更像公式定義;它以未求值形式保存右側(cè)的內(nèi)容并在使用左側(cè)變量的時(shí)候?qū)Υ藘?nèi)容進(jìn)行求值。
 

本文檔的所有示例都來自于實(shí)際的內(nèi)核源代碼。這些示例都被重新排版過 (改變了空白符和行的劃分),但其它都完全一致。

4、從頂層傳遞下去的變量
頂層 Makefile 導(dǎo)出以下變量: VERSION、 PATCHLEVEL、SUBLEVEL、EXTRAVERSION
這些變量定義了當(dāng)前內(nèi)核版本。少數(shù)體系結(jié)構(gòu) Makefile 直接使用這些值;它們應(yīng)該使用 $(KERNELRELEASE)。
$(VERSION)、$(PATCHLEVEL) 和 $(SUBLEVEL) 定義了三個(gè)基本版本編號,例如“2”、“4”和“0”。這三個(gè)值總是數(shù)值。
$(EXTRAVERSION) 定義了更低級別的預(yù)備補(bǔ)丁或附加補(bǔ)丁。它通常是類似于 “-pre4的”非數(shù)值字符串,并且往往為空。
KERNELRELEASE
$(KERNELRELEASE) 是類似于“2.4.0-pre4”的單個(gè)字符串,適于構(gòu)造安裝目錄名或在版本字符串中顯示。某些體系結(jié)構(gòu) Makefile 將它用于這樣的目的。
ARCH
該變量定義了目標(biāo)體系結(jié)構(gòu),例如“i386”、“arm”或 “sparc”。許多子目錄 Makefile 測試 $(ARCH) 以決定編譯那些文件。
在默認(rèn)情況下,頂層 Makefile 將 $(ARCH) 設(shè)定為主機(jī)系統(tǒng)的體系機(jī)構(gòu)。為了進(jìn)行交叉創(chuàng)建,用戶可以在命令行覆蓋 $(ARCH) 的值。

make ARCH=m68k ...

TOPDIR、HPATH
$(TOPDIR) 是內(nèi)核源代碼樹頂層目錄的路徑。子目錄 Makefile 需要此變量以便引入 $(TOPDIR)/Rules.make。
$(HPATH) 等價(jià)于 $(TOPDIR)/include。少數(shù)體系結(jié)構(gòu) Makefile 需要它以使用引入文件做一些特殊的事。
SUBDIRS
$(SUBDIRS) 是頂層 Makefile 應(yīng)該進(jìn)入以便完成 vmlinux 或模塊創(chuàng)建的目錄列表。$(SUBDIRS) 含有那些目錄取決于內(nèi)核配置。頂層 Makefile 定義此變量,體系結(jié)構(gòu)Makefile 擴(kuò)展此變量。
HEAD、CORE_FILES、NETWORKS、DRIVERS、LIBS、LINKFLAGS
$(HEAD)、$(CORE_FILES)、$(NETWORKS)、$(DRIVERS) 和 $(LIBS) 給出要連接到 vmlinux 中的目標(biāo)文件和庫的列表。
$(HEAD) 中的文件首先連接到 vmlinux 中。
$(LINKFLAGS) 指定創(chuàng)建 vmlinux 的標(biāo)志。
頂 層 Makefile 和體系結(jié)構(gòu) Makefile 聯(lián)合定義這些變量。頂層 Makefile 定義 $(CORE_FILES)、$(NETWORKS)、$(DRIVERS) 和 $(LIBS)。體系結(jié)構(gòu) Makefile 定義 $(HEAD) 和 $(LINKFLAGS) 并擴(kuò)展 $(CORE_FILES) 和 $(LIBS)。
注意:這些變量并不都是必需的。$(NETWORKS)、$(DRIVERS)甚至 $(LIBS) 都應(yīng)該合并到 $(CORE_FILES) 中去。
CPP、CC、AS、LD、AR、NM、STRIP、OBJCOPY、OBJDUMP、CPPFLAGS、CFLAGS、CFLAGS_KERNEL、MODFLAGS、AFLAGS、LDFLAGS、PERL、GENKSYMS
這些變量指定了 Rules.make 用于從源代碼文件創(chuàng)建目標(biāo)文件的命令和標(biāo)志。
$(CFLAGS_KERNEL) 含有用于編譯常駐內(nèi)核代碼的附加 C 編譯器標(biāo)志。
$(MODFLAGS) 含有用于編譯可載入內(nèi)核模塊的附加 C 編譯器標(biāo)志。將來該標(biāo)志可能要改為更通用的 $(CFLAGS_MODULE)。
$(AFLAGS) 含有匯編標(biāo)志。
$(GENKSYMS) 含有用于生成在啟用了 CONFIG_MODVERSIONS 時(shí)內(nèi)核符號簽名的命令。 genksyms 命令由 modutils 包提供。
CROSS_COMPILE
該變量是諸如 $(CC)、$(AS) 和 $(LD) 之類的其它變量的前綴路徑。體系結(jié)構(gòu)Makefile 有時(shí)顯式使用并設(shè)置該變量。子目錄 Makefile 不需要關(guān)心它。
如果需要,用戶可以在命令行中覆蓋 $(CROSS_COMPILE) 的值。
HOSTCC、HOSTCFLAGS
這些變量定義了用于編譯在本地主機(jī)運(yùn)行的程序的 C 編譯器和 C 編譯器標(biāo)志。它們使用單獨(dú)的變量是因?yàn)槟繕?biāo)體系結(jié)構(gòu)可能于主機(jī)體系結(jié)構(gòu)不同。
如果您的 Makefile 編譯并運(yùn)行一個(gè)在創(chuàng)建內(nèi)核的過程中運(yùn)行的程序,那它就應(yīng)該使用 $(HOSTCC) 和 $(HOSTCFLAGS)。
例如,drivers/pci 子目錄含有名為 gen-devlist.c 的助手程序。該程序讀入一個(gè) PCI ID 列表并生成名為 classlist.h 和 devlist.h 的 C 代碼。
假定用戶有一臺 i386 計(jì)算機(jī)并需要創(chuàng)建一個(gè)用于 ia64 機(jī)器的內(nèi)核。那么用戶就應(yīng)該在大多數(shù)編譯中使用 ia64 交叉編譯器,但應(yīng)該使用 i386 本地編譯器編譯 drivers/pci/gen-devlist.c。
還有,諸如 scripts/mkdep.c 和 scripts/lxdialog/*.c 那樣的 kbuild 助手程序應(yīng)該用 $(HOSTCC) 而不是 $(CC) 編譯。
ROOT_DEV、SVGA_MODE、RAMDISK
最終用戶編輯該變量以指定關(guān)于他們的內(nèi)核的特定配置信息。這些變量是古董!他們也只能用于 i386 體系結(jié)構(gòu)。他們實(shí)在是應(yīng)該用 CONFIG_* 選項(xiàng)來替代了。
MAKEBOOT
該變量只在頂層 Makefile 中定義和使用。頂層 Makefile 不該導(dǎo)出它。
INSTALL_PATH
該變量定義了體系結(jié)構(gòu) Makefile 應(yīng)該將常駐內(nèi)核映象和 System.map 文件安裝到那里去。
INSTALL_MOD_PATH、MODLIB
$(INSTALL_MOD_PATH) 指定了用于安裝模塊的 $(MODLIB) 的前綴。 Makefile 沒有定義該變量,但如果需要的話,用戶可以定義它。
$(MODLIB) 指定了模塊安裝的目錄。頂層 Makefile 將 $(MODLIB) 定義為 $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。如果需要用戶可以在命令行中覆蓋這個(gè)值。
CONFIG_SHELL
該變量是 Makefile 和 Rules.make 間私有的變量。體系結(jié)構(gòu) Makefile 和子目錄 Makefile 不應(yīng)該使用它。
MODVERFILE
內(nèi)部變量。由于它從不在頂層 Makefile 以外使用,所以不必導(dǎo)出它。
MAKE、MAKEFILES
一些 GNU Make 的內(nèi)部變量。
$(MAKEFILES) 特別用于強(qiáng)制體系結(jié)構(gòu) Makefile 和子目錄 Makefile 讀入 $(TOPDIR)/.config 而不必顯式地引入它。(這是個(gè)實(shí)線細(xì)節(jié)并可以修正)。


5、體系結(jié)構(gòu) Makefile 的結(jié)構(gòu)
5.1、體系結(jié)構(gòu)特定的變量
頂層 Makefile 引入一個(gè)體系結(jié)構(gòu) Makefile:arch/$(ARCH)/Makefile。本節(jié)解說體系結(jié)構(gòu) Makefile 的功能。

體系結(jié)構(gòu) Makefile 用體系結(jié)構(gòu)特定的至擴(kuò)展了某些頂層 Makefile 的變量。 SUBDIRS
頂層 Makefile 定義 $(SUBDIRS)。體系結(jié)構(gòu) Makefile 用一組體系結(jié)構(gòu)特定的目錄擴(kuò)展 $(SUBDIRS)。
例如:
# arch/alpha/Makefile

SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/mm
arch/alpha/lib arch/alpha/math-emu


該列表可能依賴于配置:
# arch/arm/Makefile

ifeq ($(CONFIG_ARCH_ACORN),y)
SUBDIRS += drivers/acorn
...
endif


CPP、CC、AS、LD、AR、NM、STRIP、OBJCOPY、OBJDUMP、CPPFLAGS、CFLAGS、CFLAGS_KERNEL、MODFLAGS、AFLAGS、LDFLAGS
頂層 Makefile 定義了這些變量,體系結(jié)構(gòu) Makefile 擴(kuò)展了它們。
很多體系結(jié)構(gòu) Makefile 動態(tài)地運(yùn)行目標(biāo) C 編譯器以探測它所支持的選項(xiàng):
# arch/i386/Makefile

# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2
-S -o /dev/null -xc /dev/null >/dev/null 2>&1;
then echo "-mpreferred-stack-boundary=2"; fi)


而且,$(CFLAGS) 當(dāng)然可能依賴于配置:
# arch/i386/Makefile

ifdef CONFIG_M386
CFLAGS += -march=i386
endif

ifdef CONFIG_M486
CFLAGS += -march=i486
endif

ifdef CONFIG_M586
CFLAGS += -march=i586
endif


某些體系結(jié)構(gòu) Makefile 重新定義了編譯命令以添加體系結(jié)構(gòu)特定的標(biāo)志:
# arch/s390/Makefile

LD=$(CROSS_COMPILE)ld -m elf_s390
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S




5.2、vmlinux 創(chuàng)建變量
體系結(jié)構(gòu) Makefile 和頂層 Makefile 合作以定義確定了如何創(chuàng)建 vmlinux 文件的變量。請注意沒有對應(yīng)的體系結(jié)構(gòu)特定的模塊部分;模塊創(chuàng)建機(jī)制跟體系結(jié)構(gòu)是完全獨(dú)立的。 HEAD、CORE_FILES、LIBS、LINKFLAGS
頂層 Makefile 定義了這些變量于體系結(jié)構(gòu)獨(dú)立的內(nèi)容,而體系結(jié)構(gòu) Makefile 擴(kuò)展了它們。請注意體系結(jié)構(gòu) Makefile 定義 (而不僅僅是擴(kuò)展了) $(HEAD) 和 $(LINKFLAGS)。
例如:
# arch/m68k/Makefile

ifndef CONFIG_SUN3
LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux.lds
else
LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux-sun3.lds -N
endif

...

ifndef CONFIG_SUN3
HEAD := arch/m68k/kernel/head.o
else
HEAD := arch/m68k/kernel/sun3-head.o
endif

SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib
CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES)
LIBS += arch/m68k/lib/lib.a




5.3、后-vmlinux 目標(biāo)
體系結(jié)構(gòu) Makefile 定義了獲取 vmlinux 文件、壓縮它、以啟動代碼包裝它、并將結(jié)果文件復(fù)制到某處的目標(biāo)。這包括各種類型的安裝命令。

這些后-vmlinux 目標(biāo)在不同體系結(jié)構(gòu)之間并不通用。下面是這些目標(biāo)和支持它們的體系結(jié)構(gòu)的列表 (來自于內(nèi)核版本 2.4.0-test6-pre5): balo mips
bootimage alpha
bootpfile alpha、ia64
bzImage i386、m68k
bzdisk i386
bzlilo i386
compressed i386、m68k、mips、mips64、sh
dasdfmt s390
Image arm
image s390
install arm、i386
lilo m68k
msb alpha、ia64
my-special-boot alpha、ia64
orionboot mips
rawboot alpha
silo s390
srmboot alpha
tftpboot.img sparc、sparc64
vmlinux.64 mips64
vmlinux.aout sparc64
zImage arm, i386, m68k, mips, mips64, ppc, sh
zImage.initrd ppc
zdisk i386, mips, mips64, sh
zinstall arm
zlilo i386
znetboot.initrd ppc


5.4、強(qiáng)制性體系結(jié)構(gòu)特定的目標(biāo)
體系結(jié)構(gòu) Makefile 必須定義以下體系結(jié)構(gòu)特定的目標(biāo)。這些目標(biāo)為對應(yīng)的頂層 Makefile 目標(biāo)提供了體系結(jié)構(gòu)特定的工作: archclean clean
archdep dep
archmrproper mrproper


6、子目錄 Makefile 的結(jié)構(gòu)
子目錄 Makefile 有四個(gè)部分。

6.1、注釋
第一部分是注釋頭。歷史上很多匿名人士編輯了內(nèi)核 Makefile 而沒有在頭中留下任何修改記錄;來自他們的注釋將是很有價(jià)值的。

6.2、目標(biāo)定義
第二部分是一組作為子目錄 Makefile 核心的定義。這些行定義了需要創(chuàng)建的文件、所有特殊的編譯選項(xiàng),以及必須遞歸進(jìn)入的子目錄。這些行的聲明嚴(yán)重地依賴于內(nèi)核配置變量 (CONFIG_* 符號)。

第二部分看起來是這樣:

# drivers/block/Makefile
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o

6.3、Rules.make 部分
第三部分只有一行:

include $(TOPDIR)/Rules.make

6.4、特殊規(guī)則
第四部分含有任何必需而 Rules.make 中的通用規(guī)則無法完成的特殊的 Makefile 規(guī)則。

7、Rules.make 變量
Rules.make 的公共界面由以下變量組成:

7.1、子目錄
一個(gè) Makefile 只負(fù)責(zé)它所在目錄目標(biāo)文件的創(chuàng)建。子目錄中的文件應(yīng)該由那些子目錄中的 Makefile 來創(chuàng)建。只要你讓創(chuàng)建系統(tǒng)知道這些子目錄,創(chuàng)建系統(tǒng)就會自動調(diào)用 make 以遞歸地進(jìn)入子目錄。

為此,使用 subdir-{y,m,n,} 變量:

subdir-$(CONFIG_ISDN) += i4l
subdir-$(CONFIG_ISDN_CAPI) += capi

在實(shí)際創(chuàng)建內(nèi)核時(shí),例如:vmlinux (“make {vmlinux、bzImage、...”),make 將遞歸下降到由 $(subdir-y) 列舉的目錄中。

當(dāng)創(chuàng)建模塊時(shí) (“make modules”),make 將遞歸下降到由 $(subdir-m) 列舉的目錄中。

當(dāng)創(chuàng)建依賴性關(guān)系時(shí)(“make dep”),make 需要察看所有子目錄,所以它將下降到由 $(subdir-y)、$(subdir-m)、$(subdir-n)、$(subdir-) 列舉的所有子目錄。

您可能會遇到配置選項(xiàng)被設(shè)置為“y”,但您仍然需要在那個(gè)子目錄中創(chuàng)建模塊的情況。

例如,drivers/isdn/capi/Makefile 中有:

obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o capiutil.o
obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o

可能 CONFIG_ISDN_CAPI=y,但 CONFIG_ISDN_CAPI_CAPI20=m。
這可以在其父母錄的 Makefile 以如下形式來表述:

mod-subdirs := i4l hisax capi eicon
subdir-$(CONFIG_ISDN_CAPI) += capi

即使子目錄 (“capi”) 只出現(xiàn)在 $(subdir-y) 而不在 $(subdir-m) 中出現(xiàn),使子目錄 (“capi”) 出現(xiàn)在 $(mod-subdirs) 變量中使創(chuàng)建系統(tǒng)在 “make modules” 的過程中進(jìn)入該子目錄。

7.2、目標(biāo)文件目標(biāo)
O_TARGET, obj-y
子目錄 Makefile 在列表 $(obj-y) 中為 vmlinux 指定目標(biāo)文件。這些列表依賴于內(nèi)核配置。
Rules.make 編譯所有的 $(obj-y) 文件。而后它調(diào)用 “$(LD) -r” 以將這些文件合并成為一個(gè)名為 $(O_TARGET) 的 .o 文件。這個(gè) $(O_TARGET) 將來由父 Makefile 連接到 vmlinux 之中。
$(obj-y) 中文件的順序是重要的。允許列表中出現(xiàn)重復(fù):第一次出現(xiàn)將被連接到 $(O_TARGET),而忽略隨后的出現(xiàn)。
連接順序是重要的,這是因?yàn)槟承┖瘮?shù)在啟動時(shí)將按照它們出現(xiàn)的順序被調(diào)用。所以要記住改變連接順序,比如說,就可能改變您探測到 SCSI 控制器的順序,從而改變您磁盤的編號。
例如:
# Makefile for the kernel ISDN subsystem and device drivers.

# The target object and module list name.

O_TARGET := vmlinux-obj.o

# Each configuration option enables a list of files.

obj-$(CONFIG_ISDN) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o

# The global Rules.make.

include $(TOPDIR)/Rules.make



7.3、庫文件目標(biāo)
L_TARGET
除了創(chuàng)建 O_TARGET 目標(biāo)文件,您還可以再為 $(obj-y) 列舉的目標(biāo)文件創(chuàng)建靜態(tài)連接庫。通常不必這樣做,它只用于 lib、arch/$(ARCH)/lib 目錄。

7.4、可載入模塊目標(biāo)
obj-m
$(obj-m) 指定了作為可載入內(nèi)核模塊創(chuàng)建的目標(biāo)文件。
一個(gè)模塊可以從一個(gè)或多個(gè)源代碼文件中創(chuàng)建出來。如果是一個(gè)源代碼文件,子目錄 Makefile 僅僅將文件添加到 $(obj-m) 即可。
例如:
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o


如果內(nèi)核模塊是從多個(gè)源代碼文件中創(chuàng)建出來,您就以跟上面相同的方法指定您要創(chuàng)建的模塊。
然而,創(chuàng)建系統(tǒng)當(dāng)然需要知道您要創(chuàng)建的模塊的各個(gè)部分,所以您必須通過設(shè)定變量 $(<模塊名>-obj) 來告訴它。
例如:
obj-$(CONFIG_ISDN) += isdn.o

isdn-objs := isdn_net.o isdn_tty.o isdn_v110.o isdn_common.o


在這個(gè)例子中,模塊名為 isdn.o。Rules.make 將編譯列舉在 $(isdn-objs) 中的文件,而后對這些文件運(yùn)行“$(LD) -r”以生成 isdn.o。
注意:當(dāng)然,當(dāng)您將目標(biāo)文件創(chuàng)建到內(nèi)核之中時(shí),以上語法仍然是有效的。所以,如果您的 CONFIG_ISDN=y,創(chuàng)建系統(tǒng)將按照您所預(yù)期的,由它的各個(gè)部分為您創(chuàng)建出 isdn.o,然后將它連接到 $(O_TARGET) 之中。

7.5、帶有導(dǎo)出符號的目標(biāo)文件
export-objs
當(dāng)使用可載入模塊時(shí),不是所有內(nèi)核/其它模塊中的全局符號 都自動成為可用的,您的模塊只能使用那些顯式導(dǎo)出的符號。
為了讓模塊能夠使用某個(gè)符號,要“導(dǎo)出”它,在源代碼中使用 EXPORT_SYMBOL()。此外,您還要在 Makefile 變量 $(export-objs) 中列舉所有導(dǎo)出符號的文件(例如,含有 EXPORT_SYMBOL() 指令的源代碼)。
例如:
# Objects that export symbols.

export-objs := isdn_common.o


這是因?yàn)?isdn_common.c 含有
EXPORT_SYMBOL(register_isdn);


這使得底層 ISDN 驅(qū)動程序能夠使用函數(shù) register_isdn。

7.6、編譯標(biāo)志
EXTRA_CFLAGS、EXTRA_AFLAGS、EXTRA_LDFLAGS、EXTRA_ARFLAGS
$(EXTRA_CFLAGS) 指定用 $(C) 編譯 C 文件的選項(xiàng)。該變量中的選項(xiàng)用于當(dāng)前目錄中編譯所有文件用的 $(CC) 命令。
例如:
# drivers/sound/emu10k1/Makefile
EXTRA_CFLAGS += -I.
ifdef DEBUG
EXTRA_CFLAGS += -DEMU10K1_DEBUG
endif


當(dāng)前目錄的子目錄并不使用 $(EXTRA_CFLAGS)。此外,它也不用于由 $(HOSTCC) 編譯的文件。
由于頂層 Makefile 擁有變量 $(CFLAGS) 并將該變量用于整個(gè)源代碼樹,因此 $(EXTRA_CFLAGS) 是必需的。
$(EXTRA_AFLAGS) 是用于編譯匯編語言源代碼的類似的單個(gè)目錄選項(xiàng)字符串。
示例:在編寫本文時(shí),內(nèi)核源代碼中尚無使用 $(EXTRA_AFLAGS) 的例子。
$(EXTRA_LDFLAGS) 和 $(EXTRA_ARFLAGS) 用于 $(LD) 和 $(AR) 的類似的單個(gè)目錄選項(xiàng)字符串。
示例:在編寫本文時(shí),內(nèi)核源代碼中尚無使用 $(EXTRA_LDFLAGS) 或 $(EXTRA_ARFLAGS) 的例子。
CFLAGS_$@, AFLAGS_$@
$(CFLAGS_$@) 為單個(gè)文件指定 $(CC) 選項(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


這三行分別為 aha152x.o、gdth.o 和 seagate.o 指定編譯選項(xiàng)。
$(AFLAGS_$@) 給出類似的用于編譯匯編語言源文件的選項(xiàng)。
例如:
# arch/arm/kernel/Makefile
AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional


Rules.make 有讓目標(biāo)文件依賴于用于編譯它的 $(CFLAGS_$@) 的值的功能。因此,如果你為某個(gè)文件改變了 $(CFLAGS_$@) 的值,不論是編輯 Makefile 還是以其他某種方式覆蓋了原來的值,Rules.make 都會正確地工作并以新選項(xiàng)重新編譯您的源代碼。
請注意:由于 Rules.make 的缺陷,匯編語言沒有標(biāo)志依賴性。如果您為某個(gè)文件編輯了 $(AFLAGS_$@),您就必須刪除目標(biāo)文件以便從源文件重新創(chuàng)建它。
LD_RFLAG
使用但從未定義該變量。這似乎是某種已放棄的嘗試的遺跡。

7.7、其它變量
IGNORE_FLAGS_OBJS
$(IGNORE_FLAGS_OBJS) 是一個(gè)無法自動跟蹤標(biāo)志依賴性關(guān)系的目標(biāo)文件的列表。這是個(gè)補(bǔ)充功能,用于處理實(shí)現(xiàn)依賴性標(biāo)志中的問題。(問題是標(biāo)志依賴性假定 %.o 文件是從一個(gè)匹配的 %.S 或 %.c 中創(chuàng)建出來的。有時(shí)并不是這樣)。
USE_STANDARD_AS_RULE
這是一個(gè)過渡變量。如果定義了 $(USE_STANDARD_AS_RULE) , Rules.make 就為將 %.S 文件匯編為 %.o 文件或 %.s 文件 (%.s 文件只對開發(fā)者才有用) 提供標(biāo)準(zhǔn)規(guī)則。
如果沒有定義 $(USE_STANDARD_AS_RULE),那么 Rules.make 就不提供這些標(biāo)準(zhǔn)規(guī)則。在這種情況下,子目錄 Makefile 必須為匯編 %.S 文件提供它的私有規(guī)則。
在 過去,所有 Makefile 都提供私有的 %.S 規(guī)則。較新的 Makefiles 應(yīng)該定義 USE_STANDARD_AS_RULE 并使用標(biāo)準(zhǔn)的 Rules.make 規(guī)則。一旦所有體系結(jié)構(gòu)的所有 Makefile 都使用 USE_STANDARD_AS_RULE,那么 Rules.make 就可以取消對 USE_STANDARD_AS_RULE 的測試。此后,所有其它 Makefile 就可以取消對 USE_STANDARD_AS_RULE 的定義。

8、新風(fēng)格變量
[ 本章回溯到將前面描述的編寫 Makefile 的方式稱為“新風(fēng)格”的時(shí)候。由于換句話說它仍然表述了同樣的事,所以我在此保持了這種說法,這可能有些用處 ]

“新風(fēng)格變量”比“舊風(fēng)格變量”更簡單更有效。因此,許多子目錄 Makefile 可以縮減 60%。作者希望所有體系結(jié)構(gòu) Makefile 和子目錄 Makefile 都能及時(shí)轉(zhuǎn)換到新風(fēng)格。

Rules.make 并不理解新風(fēng)格變量。因此,每個(gè)新風(fēng)格 Makefile 都有一個(gè)樣板代碼部分以便將新風(fēng)格變量轉(zhuǎn)換為舊風(fēng)格變量。這有點(diǎn)混淆,人們以“新風(fēng)格”定義大部分變量但最后幾行又落入了“舊風(fēng)格”。

8.1、新變量
obj-y obj-m obj-n obj-
這些變量代替了 $(O_OBJS)、$(OX_OBJS)、$(M_OBJS) 和 $(MX_OBJS)。
例如:
# drivers/block/Makefile
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o


請注意這里用 $(CONFIG_...) 在賦值操作符左側(cè)進(jìn)行替換。這使 GNU Make 具有組合索引的能力!每個(gè)這樣的賦值替換了舊風(fēng)格 Makefile 中的八行代碼。
在執(zhí)行所有的賦值之后,子目錄 Makefile 就創(chuàng)建了四個(gè)列表:$(obj-y)、$(obj-m)、 $(obj-n) 和 $(obj-)。
$(obj-y) 是包含在 vmlinux 之中的文件的列表。
$(obj-m) 是作為單獨(dú)模塊創(chuàng)建的文件列表。
忽略 $(obj-n) 和 $(obj-)。
每個(gè)列表都可能含有重復(fù)項(xiàng)目;此后重復(fù)的項(xiàng)目將被自動刪除。同時(shí)出現(xiàn)在 $(obj-y) 和 $(obj-m) 中的文件將自動從 $(obj-m) 列表中刪除。
Example:
# drivers/net/Makefile

...
obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
...
obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
...
obj-$(CONFIG_STNIC) += stnic.o 8390.o
...
obj-$(CONFIG_MAC8390) += daynaport.o 8390.o
...


在 這個(gè)例子中,四個(gè)不同的驅(qū)動程序都需要 8390.o 中的代碼。如果這四個(gè)驅(qū)動程序中的一個(gè)或多個(gè)要創(chuàng)建到 vmlinux 之中,即使其它驅(qū)動程序需要 8390.o 作為模塊進(jìn)行創(chuàng)建,8390.o 就會被創(chuàng)建到 vmlinux 之中而不是成為一個(gè)模塊。(模塊化的驅(qū)動程序能夠使用常駐于 vmlinux 映像中的 8390.o 代碼提供的服務(wù))。
export-objs
$(export-objs) 是子目錄中所有可能導(dǎo)出符號的文件的列表。構(gòu)造該列表的規(guī)范方法是:
grep -l EXPORT_SYMBOL *.c


(但看看那些在引入頭文件中偷偷調(diào)用 EXPORT_SYMBOL 的文件吧!)
這是個(gè)可能的列表,與內(nèi)核配置無關(guān)。$(export-objs) 列舉出所有導(dǎo)出符號的文件。而后樣板代碼就用 $(export-objs) 來將實(shí)際的文件列表劃分為 $(*_OBJS) 和 $(*X_OBJS)。
經(jīng)驗(yàn)表明在舊風(fēng)格 Makefile 中維護(hù)一個(gè)正確的 X 變量有困難并容易出錯。在新風(fēng)格 Makefile 中維護(hù) $(export-objs) 比較簡單并便于核對。
$(foo)-objs
某些內(nèi)核模塊由多個(gè)目標(biāo)文件連接組成。
對于每個(gè)多部分內(nèi)核模塊,都有一個(gè)列表列出所有組成該模塊的目標(biāo)文件。對于名為 foo.o 的內(nèi)核模塊,它的目標(biāo)文件列表就是 foo-objs。
例如:
# drivers/scsi/Makefile
list-multi := scsi_mod.o sr_mod.o initio.o a100u2w.o

...

scsi_mod-objs := hosts.o scsi.o scsi_ioctl.o constants.o
scsicam.o scsi_proc.o scsi_error.o
scsi_obsolete.o scsi_queue.o scsi_lib.o
scsi_merge.o scsi_dma.o scsi_scan.o
scsi_syms.o
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
initio-objs := ini9100u.o i91uscsi.o
a100u2w-objs := inia100.o i60uscsi.o


子目錄 Makefile 將以常見的配置相關(guān)方式將模塊加入 obj-* 列表:
obj-$(CONFIG_SCSI) += scsi_mod.o
obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o
obj-$(CONFIG_SCSI_INITIO) += initio.o
obj-$(CONFIG_SCSI_INIA100) += a100u2w.o


假定 CONFIG_SCSI=y。那么 vmlinux 就需要把它的 14 組件連接為 scsi_mod.o。
假定 CONFIG_BLK_DEV_SR=m。那么 sr_mod.o 的三個(gè)組件就要以 “$(LD) -r” 連接到一起以組成內(nèi)核模塊 sr_mod.o。
再假定 CONFIG_SCSI_INITIO=n。那么 initio.o 就進(jìn)入 $(obj-n) 列表而且這就是它的終點(diǎn)了。不會編譯它的組件文件,也不會創(chuàng)建組合文件。
subdir-y subdir-m subdir-n subdir-
這些變量替代了 $(ALL_SUB_DIRS)、$(SUB_DIRS) 和 $(MOD_SUB_DIRS)。
例如:
# drivers/Makefile
subdir-$(CONFIG_PCI) += pci
subdir-$(CONFIG_PCMCIA) += pcmcia
subdir-$(CONFIG_MTD) += mtd
subdir-$(CONFIG_SBUS) += sbus


這些變量按類似于 obj-* 的方式工作,但用于子目錄而不是目標(biāo)文件。
在所有賦值完成后,子目錄 Makefile 就組成了四個(gè)列表:$(subdir-y)、$(subdir-m)、 $(subdir-n) 和 $(subdir-)。
$(subdir-y) 是創(chuàng)建 vmlinux 時(shí)應(yīng)該進(jìn)入的子目錄列表。
$(subdir-m) 是創(chuàng)建模塊時(shí)應(yīng)該進(jìn)入的子目錄列表。
$(subdir-n) 和 $(subdir-) 只用于收集本目錄的所有子目錄的列表。
除 subdir-y 以外每個(gè)列表都可能含有重復(fù)項(xiàng)目;此后將自動刪除重復(fù)項(xiàng)目。
mod-subdirs
$(mod-subdirs) 是一個(gè)所有即使出現(xiàn)在 $(subdir-y) 中也應(yīng)該加入 $(subdir-m) 的子目錄的列表。
例如:
# fs/Makefile
mod-subdirs := nls


這意味著如果 CONFIG_NLS=y,nls 應(yīng)該加入 $(subdir-y) 和 $(subdir-m)。

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多