欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Linux內核構建系統之四

回到我們的主框架上面來(lái),討論完配置目標的處理后,就輪到框架中 "ifeq ($(config-targets),1)-endif" 塊的 else 部分了。這部分是為了處理那些構建目標以及和.config無(wú)關(guān)的目標,其對這些目標處理的代碼都位于框架中的E部分中。在E部分之前,有一個(gè)不小的 "ifeq ($(dot-config),1)-endif" 塊,我們暫先不去理會(huì ),且看這個(gè) ifeq-endif 塊之前有一小段注釋?zhuān)?/p>

 

# ===========================================================================# Build targets only - this includes vmlinux, arch specific targets, clean# targets and others. In general all targets except *config targets.

 

這段注釋字面上的意思是說(shuō) "ifeq ($(config-targets),1)-endif" 塊的 else 部分處理的都是 Build targets,也就是除了配置目標之外的其他目標。注意他這里對 Build targets 分類(lèi)方法,其實(shí)和我們之前的分類(lèi)方法是有差異的,他這里所謂的 Build targets ,除了包括我們之前分類(lèi)中所說(shuō)的構建目標外,還包括之前我們說(shuō)的和 .config 文件無(wú)關(guān)的那些目標。這其實(shí)是對同個(gè)東西的兩種不同分類(lèi)罷了,不影響我們的分析。其實(shí)不管哪種分類(lèi),都改變不了在本 else 部分既處理真正的構建目標,又處理那些和 .config 文件無(wú)關(guān)目標的事實(shí)。

好,鑒于我們已有這樣的事實(shí)認同。那接下來(lái)理解前面說(shuō)的那個(gè)不小的 "ifeq ($(dot-config),1)-endif" 塊就比較容易了。很顯然這個(gè)時(shí)候如果變量 dot-config 等于 1,那說(shuō)明針對的是那些真正的構建目標,因為他們需要文件 .config 來(lái)完成真正的構建。而如果這個(gè)變量不為1,那么針對的就是那些和 .config 完全無(wú)關(guān)的目標了。

當 dot-config 等于 1 時(shí),構建系統首先會(huì )嘗試性的包含 include/config/auto.conf 文件。為什么說(shuō)是嘗試性的?這是 GNU make 做 "-include" 的特性。其意思和是否存在所包含的文件以及是否能根據所存在的規則去重新創(chuàng )建所包含文件有關(guān)系。

GNU Make 是這樣一個(gè)大致的讀取Makefile的流程:首先它讀入主Makefile,在讀的過(guò)程中,如果碰到 "include" 或 "-include",它就會(huì )包含對應的文件。如果對應的文件不存在,則暫時(shí)跳過(guò)做包含的地方,繼續讀入。待所有makefie都讀完后。GNU Make會(huì )考慮將每個(gè)makefile作為目標,在全局范圍內查找是否有能生成這些目標的規則,如果發(fā)現有一個(gè)makefile可以被一條規則生成,那么GNU Make就會(huì )先生成這個(gè)makefile。生成后,GNU Make又會(huì )從零開(kāi)始讀入主Makefile以及所有被包含的makefile,然后再檢查是否有makefile可以被remade….這樣一次又一次,直到所有的makefile都不需要再次生成了,它才處理依賴(lài)規則鏈。它之這樣做,是為了保證所有 makefile 都是 update-to-date 的。

那如果你的子makefile是被 "include" 所包含的,但是這個(gè)makefile本身不存在,且無(wú)法用一條規則去Remake出來(lái),那么 GNU Make就會(huì )報錯并退出。相反,如果你用的是 "-include",那么 GNU Make就什么都不做,就好象什么也沒(méi)發(fā)生過(guò)那樣繼續處理后面的事情。所以,我們說(shuō)這里是嘗試性的,通俗點(diǎn)就是”有則包含,沒(méi)有也罷了“:)。

接下來(lái)回到主框架,假如你的 make 命令是 "make ARCH=arm CROSS_COMPILE=arm-linux- zImage",那么dot-config 等于 1,并且變量 KBUILD_EXTMOD 會(huì )等于空。構建系統又會(huì )先嘗試性的包含文件 include/config/auto.conf.cmd,然后繼續處理主框架中的 G1部分。我們先看看G1部分的代碼:

 

# To avoid any implicit rule to kick in, define an empty command$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # If .config is newer than include/config/auto.conf, someone tinkered# with it and forgot to run make oldconfig.# if auto.conf.cmd is missing then we are probably in a cleaned tree so# we execute the config step to be sure to catch updated Kconfig filesinclude/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd        $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig

 

:),你看到這里也許會(huì )露出些許微笑,因為你還記得那個(gè) "-include include/config/auto.conf"。沒(méi)錯,針對你的make命令,GNU Make在處理任何目標之前,它一定會(huì )努力的為我們生成文件 include/cofig/auto.conf ,用的就是這里的這條對應規則。注意這里的細節,GNU Make同樣也會(huì )努力重新用上面這條規則去生成 include/config/auto.conf.cmd 文件,可是無(wú)奈上面這條規則既沒(méi)有依賴(lài),又沒(méi)有命令,所以GNU Make 是怎么也沒(méi)辦法生成 auto.conf.cmd。那么 auto.conf.cmd 文件又是從什么地方生成呢?答案是在生成 include/config/auto.conf 的時(shí)候。稍后,我們會(huì )看到,它同樣在這個(gè)時(shí)候生成了另外一個(gè)文件 include/linux/autoconf.h。

既然已經(jīng)說(shuō)到這幾個(gè)文件了,那我就預先來(lái)回答一下上面提出來(lái)的問(wèn)題。什么問(wèn)題?就是配置過(guò)程最后產(chǎn)生了用于記載配置結果的 .config ,那么其中的配置結果由誰(shuí)使用,又是如何使用的問(wèn)題。我們說(shuō)在整個(gè)Linux內核系統中,有兩方面的用戶(hù)需要關(guān)注所記載的配置結果。一個(gè)自然是內核構建系統,它需要根據配置結果產(chǎn)生具有指定功能的內核映像;另外一個(gè)就是大部分代碼為C語(yǔ)言代碼的Linux內核本身,它也需要用戶(hù)的配置結果,主要用來(lái)預處理C代碼。前者使用配置結果,并不是直接通過(guò) .config 文件來(lái)的,而是將其轉換成兩個(gè)文件:include/config/auto.conf 和 include/config/auto.conf.cmd。后者也沒(méi)辦法直接通過(guò) .config 文件來(lái)使用配置結果,它需要將其轉換成C語(yǔ)言頭文件的形式使用,在這里就是文件 include/linux/autoconf.h 。關(guān)于這三個(gè)文件的內容,我們稍后敘述。

還是回到上面處理 auto.conf 的規則中來(lái),變量 KCONFIG_CONFIG 指代的就是配置文件 .config 。目標 auto.conf 依賴(lài)于 .config 和 auto.conf.cmd 。當GNU Make使用這條規則來(lái)remake auto.conf的時(shí)候,這兩個(gè)文件即使不存在也沒(méi)有關(guān)系。因為這樣的話(huà),GNU Make 會(huì )因為有上面這條沒(méi)有依賴(lài)也沒(méi)有命令的規則而認為這兩個(gè)依賴(lài)是最新的,所以此時(shí)auto.conf規則的命令總是會(huì )被得到執行。

這是有意思的地方,因為這是不是意味著(zhù)我可以在一個(gè)剛剛解壓出來(lái)的Linux內核目錄中直接用命令 "make ARCH=arm CROSS_COMPILE=arm-linux- zImage"來(lái)完成構建呢?咱們試一下:

從結果看前面都沒(méi)問(wèn)題,直到用conf進(jìn)行最后一步的配置時(shí)出現了錯誤。至于錯誤原因呢,是因為找不到文件 .config 。我們可以找出出現錯誤的代碼,就在文件scripts/kconfig/conf.c 的main函數中,如下所示的代碼片段:

 

if (sync_kconfig) {                name = conf_get_configname();                if (stat(name, &tmpstat)) {                        fprintf(stderr, _("***/n"                                "*** You have not yet configured your kernel!/n"                                "*** (missing kernel config file /"%s/")/n"                                "***/n"                                "*** Please run some configurator (e.g. /"make oldconfig/" or/n"                                "*** /"make menuconfig/" or /"make xconfig/")./n"                                "***/n"), name);                        exit(1);                }        }

 

就像前面講的,這個(gè)時(shí)候GNU Make會(huì )執行auto.conf規則的對應命令"$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig"。而針對這個(gè)命令,配置程序 conf 最后會(huì )在main函數上面這個(gè)代碼片段的前面,將上面這個(gè)代碼片段中的 sync_kconfig 設置為1。接下來(lái)取得配置文件的名稱(chēng)放在 name 變量里面,再使用 stat 函數查詢(xún)這個(gè)文件的狀態(tài)。結果該函數返回非0值,使得GNU Make認為配置文件.config不存在而報錯。

回到處理 auto.conf 的那條規則上來(lái)??紤]一下如果這個(gè)時(shí)候 auto.conf 文件和 .config 文件都存在,但是 .config 比較新的話(huà)會(huì )怎么樣呢?想想,這會(huì )是一個(gè)怎么樣的 Scenario呢?如果你剛剛編譯過(guò)內核并已生成映像文件,這個(gè)時(shí)候你從你朋友那里取來(lái)一個(gè) .config 文件,并且將其放到了你的內核源碼樹(shù)下面,這個(gè)時(shí)候就產(chǎn)生了這種情況。這個(gè)時(shí)候你需要根據你的內核的版本來(lái)做處理。如果你的版本和你的朋友一樣,那沒(méi)問(wèn)題,你大可以直接 "make ... zImage"。但是,如果你們的版本不一樣,你最好做下 "make ... oldconfig"。這個(gè)命令的作用是針對原來(lái)版本內核的配置文件設置來(lái)配置新版本的內核。新版內核中沒(méi)變的配置選項可以設置成原來(lái)的值,但是新添加的配置項就需要你自己手動(dòng)設置了。

再次回到處理 auto.conf 的那條規則上來(lái),我們看到它的命令 "$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig",這個(gè)命令最終會(huì )導致GNU Make執行文件 scripts/kconfig/Makefile 中針對目標 silentoldconfig 的命令:

$(obj)/conf -s arch/arm/Kconfig

conf配置程序在前面已經(jīng)有所提及,其對應的代碼都在目錄 scripts/kconfig/ 中。conf 的主函數main即定義在 conf.c 文件中。其實(shí),目標silentoldconfig 和 目標oldconfig類(lèi)似,只不過(guò)它多了生成auto.conf、auto.conf.cmd以及autoconf.h等三個(gè)文件的任務(wù)。這是怎么做到的?答案就在conf.c文件中 main 函數最后的一段代碼:

 

int main(int ac, char **av){        int opt;        const char *name;        struct stat tmpstat;         .....        .....                if (sync_kconfig) {                /* silentoldconfig is used during the build so we shall update autoconf.                 * All other commands are only used to generate a config.                 */                if (conf_get_changed() && conf_write(NULL)) {                        fprintf(stderr, _("/n*** Error during writing of the kernel configuration./n/n"));                        exit(1);                }                if (conf_write_autoconf()) {                        fprintf(stderr, _("/n*** Error during update of the kernel configuration./n/n"));                        return 1;                }        } else {                if (conf_write(NULL)) {                        fprintf(stderr, _("/n*** Error during writing of the kernel configuration./n/n"));                        exit(1);                }        }        return 0;}

 

前面我們已經(jīng)介紹過(guò),當用 conf 處理 silentoldconfig 時(shí),變量sync_kconfig會(huì )被設置為1。實(shí)際上,也只有處理此目標時(shí),它才會(huì )被設置成1,其他的目標都不會(huì )。對于oldconfig、menuconfig等目標來(lái)說(shuō),conf程序最后會(huì )直接調用函數 conf_write 將配置結果寫(xiě)到配置文件 .config 中去。該函數的定義在同目錄的另外一個(gè)文件 confdata.c 中,這里我們不再細究下去了,你可以自己探究。而對于 silentoldconfig 目標來(lái)說(shuō),conf 程序除了調用 conf_write 來(lái)寫(xiě) .config 文件外,它還會(huì )調用 conf_write_autoconf 函數來(lái)完成 auto.conf、auto.conf.cmd 和 autoconf.h 三個(gè)文件的生成。我們且來(lái)看看同樣定義在 confdata.c 文件中的 conf_write_autoconf 函數:

該函數一開(kāi)始就寫(xiě) include/config/auto.conf.cmd 文件,然后將對應的內容寫(xiě)入到兩個(gè)臨時(shí)文件 .tmpconfig 和 .tmpconfig.h 中,并在最后將這兩個(gè)文件分別重新命名為include/config/auto.conf 和 include/linux/autoconf.h。注意上面代碼中對 conf_split_config 函數的調用,其目的是在目錄 include/config 中產(chǎn)生一系列的頭文件,至于這些頭文件如何產(chǎn)生的、以及它們的作用,我們這里先留下一個(gè)伏筆,回頭再來(lái)探究。

知道了這幾個(gè)文件是如何產(chǎn)生的。我們再來(lái)注意一下它們的內容。文件 auto.conf.cmd 里面記錄的是 auto.conf 目標的相關(guān)依賴(lài),而文件 auto.conf 和文件 autoconf.h 的內容和 .config 文件的內容直接相關(guān)。舉例來(lái)說(shuō),如果你找到有個(gè)定義在 .config 文件里的變量形式:CONFIG_MMU=y 表示要將虛擬內存管理的功能編譯進(jìn)內核,那么在 auto.conf 里面也會(huì )有完全相同的定義形式:CONFIG_MMU=y。而在文件 autoconf.h 文件中,則會(huì )有一個(gè)這樣形式的宏定義:#define CONFIG_MMU 1。假如.config中的形式是 CONFIG_IKCONFIG=m,那么在 auto.conf 中的形式也會(huì )是:CONFIG_IKCONFIG=m ,而在文件 autoconf.h 中的定義形式則變成:#define CONFIG_IKCONFIG_MODULE 1 。

前面說(shuō)的是當 KBUILD_EXTMOD 為空的時(shí)候,那么當這個(gè)變量取值不為空(也就是我們嘗試在用 "make ... -M=..." 之類(lèi)的命令來(lái)編譯外部模塊)時(shí),GNU Make 只是簡(jiǎn)單的處理上面框架中的G2部分。編譯外部模塊時(shí)并不需要關(guān)心 auto.conf/autoconf.h 是不是最新的。它只是檢查他們是否存在,如果不存在,它就報錯并退出。

之前我們說(shuō)過(guò)構建目標以及和.config無(wú)關(guān)的目標是混在一塊處理的。那當 dot-config 等于 1 時(shí),處理的是構建目標,而在 dot-config 等于 0 時(shí),構建系統處理的是那些和文件 .config沒(méi)有關(guān)系的目標。注意看我們的框架,處理和.config無(wú)關(guān)目標的時(shí)候,構建系統只是簡(jiǎn)單的針對 auto.conf 目標定義了一個(gè)既沒(méi)有依賴(lài)又沒(méi)有命令的規則:

 

# Dummy target needed, because used as prerequisiteinclude/config/auto.conf: ;

 

這樣做的意思是因為 auto.conf 在后面會(huì )為多個(gè)其他目標所依賴(lài)。我們在這里只是登記一下說(shuō):“嘿,兄弟我(auto.conf)已經(jīng)是最新的了,你們別再管我了,只管繼續做你們自己的事情就好?!?/p>

關(guān)于對上面框架代碼E部分中和 .config 文件無(wú)關(guān)目標的處理,這里限于篇幅,我們就不再多講,您可自己研究。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
auto.conf, auto.conf.cmd, autoconf.h
[轉載]使用Automake,Autoconf生成Makefile
Autoconf手冊
用configure建立工具的學(xué)習
autotools使用流程
UBoot的配置編譯過(guò)程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久