日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
C編程鬼話(huà):完善MVC的DEMO,閑話(huà)MAKEFILE

不得不說(shuō)一句,從開(kāi)始,到現(xiàn)在,我不得不忍受著無(wú)法使用make MAKEFILE的折磨。而如果從開(kāi)始到現(xiàn)在,所有的例子你都親自敲過(guò)諸如如下的命令:

淇縣網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,淇縣網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為淇縣成百上千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的淇縣做網(wǎng)站的公司定做!

 
 
 
  1. gcc -Wall attr.c value.c view.c control.c model.c -o attr

你或許會(huì)對(duì)C語(yǔ)言編程喪失信心。你甚至可能會(huì)出現(xiàn)一個(gè)代碼編譯的錯(cuò)誤。當(dāng)你敲入

 
 
 
  1. gcc -Wall attr.c value.c view.c model.c -o attr

鏈接會(huì)有問(wèn)題。這些手工的小失誤,帶來(lái)的都是麻煩事。還有更麻煩的。如果我們有100個(gè)C文件整合起來(lái)的工程。不算多,真的。如果改動(dòng)一個(gè)文件,也按照上面的方式及執(zhí)行,就會(huì)很慢。特別是debug的時(shí)候,思路往往在你上次廁所后就容易斷掉。嘗試幾種測(cè)試方法,迅速觀(guān)測(cè)結(jié)果,對(duì)于某些類(lèi)型的測(cè)試是需要的。而debug也經(jīng)常需要反復(fù)的修改和編譯鏈接。

一種好的做法,是我們先編譯,把對(duì)象文件保存,當(dāng)出現(xiàn)某個(gè)具體文件修改后,可以只對(duì)這個(gè)文件進(jìn)行編譯,而其他文件沒(méi)必要處理,然后由此對(duì)此次以及上次生成的沒(méi)有改變對(duì)應(yīng)源碼的對(duì)象文件一起鏈接。編譯相對(duì)鏈接,是個(gè)比較慢的工作。由此在你只改動(dòng)control.c前后你可以如下操作。

沒(méi)改動(dòng)control.c前,我們可以

 
 
 
  1. gcc -Wall -c attr.c value.c view.c control.c model.c

以上由于有了-c所以是多所有的C文件進(jìn)行編譯,生成同名的,后綴為.o的對(duì)象文件。

 
 
 
  1. gcc attr.o value.o view.o control.o model.o -o attr

這是將所有的對(duì)象文件作為資源,鏈接生成一個(gè)attr的執(zhí)行文件。

僅改動(dòng)了control.c,那么我們可以

 
 
 
  1. gcc -Wall -c control.c
  2. gcc attr.o value.o view.o control.o model.o -o attr

但這樣也帶來(lái)個(gè)問(wèn)題。很多情況下,經(jīng)常出現(xiàn)你實(shí)際改動(dòng)的文件,并沒(méi)有被編譯,而原先的.o文件也存在。上述工作都不會(huì)報(bào)錯(cuò),而且你的改動(dòng)并沒(méi)有被執(zhí)行程序所體現(xiàn)。通常的情況,你會(huì)徹底崩潰,為什么左改右改,就是沒(méi)變化。

這里提到一個(gè)新的參考文獻(xiàn) 6. 徐海兵 譯。 我不認(rèn)識(shí)他,哈。不過(guò)難得我推薦一本中文書(shū)籍。理由如下:

1、這書(shū)即便有人認(rèn)為翻譯的爛,但多少對(duì)你學(xué)習(xí)make足以,沒(méi)覺(jué)得有什么翻譯不足導(dǎo)致影響原理,概念理解的地方。

2、make 更是個(gè)工具。主要是拿來(lái)用的。除非整天折騰makefile的人,相信我,通常你每3個(gè)月,才組織設(shè)計(jì)一次makefile,那么原理和概念的東西,還是會(huì)有失憶性遺漏,快速用起來(lái)這是關(guān)鍵。這和C標(biāo)準(zhǔn)資料還不一樣。后者。原理理解的一些偏差,可能導(dǎo)致代碼涉及的很大改動(dòng)。

推薦gun make 中文手冊(cè) 。但不會(huì)如同其他參考文獻(xiàn)一樣,給出章節(jié)出處,做詳細(xì)闡述,是希望你該養(yǎng)成,自己通讀資料的習(xí)慣,而不是別人告訴你,具體哪頁(yè),哪行的保姆時(shí)學(xué)習(xí)。 因此,我不會(huì)給出任何參考文獻(xiàn) 6的引用,當(dāng)然絕對(duì)不是對(duì)徐海兵的冒犯及不信任。

鬼話(huà):如果你說(shuō)你會(huì)寫(xiě)C程序,而不會(huì)用make,拜托,千萬(wàn)別出去拿C的招牌說(shuō)事了。丟人,而且丟大了。

這里先說(shuō)說(shuō)make的精髓。我認(rèn)為有以下幾個(gè)方面。

1、文件敏感性。也即,當(dāng)make工作,會(huì)對(duì)文件是否修改很敏感。于是,你可以丟給他一堆文件,當(dāng)這些文件被更新時(shí),它是可以根據(jù)規(guī)則,進(jìn)行有選擇的處理。

2、依賴(lài),這種依賴(lài),你可以理解成因果關(guān)系。甚至可以理解成觸發(fā)事件的響應(yīng)。這可比一般的腳本要爽太多。

3、規(guī)則。這是編程序的一個(gè)境界。突出強(qiáng)調(diào)規(guī)則,如同數(shù)學(xué)突出強(qiáng)調(diào)邏輯關(guān)系,而不是強(qiáng)調(diào)具體數(shù)值一樣。

4、腳本化。靈活的組織邏輯,而不是呆板的一行行的解釋執(zhí)行規(guī)則。

鬼話(huà):為什么說(shuō)make是這么好的東西。如果你認(rèn)為某個(gè)應(yīng)用程序或者linux的創(chuàng)始人算大牛,確實(shí)是大牛,那么make可以說(shuō)是一堆歷史上的大牛,在經(jīng)歷過(guò)痛苦后,努力創(chuàng)造出來(lái)的東西。任何贊美之詞,如果你用在其他應(yīng)用軟件或工具上,make都值得同等對(duì)待。C語(yǔ)言,除了自身在代碼性能,底層開(kāi)發(fā)上可以超越其他高級(jí)語(yǔ)言外,原生的make操作,也足以讓一個(gè)C程序員,藐視其他夸夸其談某個(gè)IDE多么人性化的程序員,因?yàn)榇蠖鄶?shù)你看到的IDE,后臺(tái)都藏著make,make不單單為C語(yǔ)言服務(wù),無(wú)非C程序員當(dāng)然也包括C++程序員經(jīng)常直接面向make。不是我在激起語(yǔ)言和程序員的類(lèi)別之爭(zhēng)。make 的設(shè)計(jì),思想,對(duì)比現(xiàn)在很多什么架構(gòu),框架,要高明的多。雖然你看它是非常簡(jiǎn)單和樸素的。相信我,make的熟練使用后,你一定會(huì)有對(duì)C語(yǔ)言設(shè)計(jì)脫胎換骨的感覺(jué),無(wú)論你在那個(gè)操作系統(tǒng)下。當(dāng)然make這不是本書(shū)的重點(diǎn),具體的學(xué)習(xí),需要系統(tǒng)的看對(duì)應(yīng)的資料,包括上面推薦的那本,此處僅介紹如何簡(jiǎn)單的應(yīng)用,以降低我們現(xiàn)有C語(yǔ)言設(shè)計(jì)中的開(kāi)發(fā)負(fù)擔(dān)。

先說(shuō)說(shuō)make的操作。通常就是個(gè)簡(jiǎn)單的

 
 
 
  1. make

命令。make程序,會(huì)自動(dòng)查找配置文件。也是傳說(shuō)中的makefile,這算慣例,或潛規(guī)則?;蛘吣憧梢?/p>

 
 
 
  1. make -f filename

filename 是一個(gè)任意文件。

但不是潛規(guī)則要求的文件名。這樣做通常用于臨時(shí)性的make使用,正式情況,不需要如此折騰。潛規(guī)則有個(gè)好處,你被潛規(guī)則了,其他人也會(huì)被潛規(guī)則。這樣降低你和其他人的交流成本。

由此,另一個(gè)做法是將你的計(jì)劃,寫(xiě)在名為 GNUmakefile ,makefile ,Makefile這幾種文件名中任意一個(gè)。恩。make的潛規(guī)則文件名也有幾種寫(xiě)法。但潛規(guī)則中的潛規(guī)則是,我們都用Makefile。如果老師考你 make的潛規(guī)則,都可以識(shí)別哪幾個(gè)文件名,他們的依次順序時(shí),你可以毫不猶豫的向他豎中指。他如果問(wèn)哪學(xué)的,你可以說(shuō)是野鬼教的,因?yàn)樗麤](méi)有說(shuō)是那個(gè)版 本的make。不過(guò)豎歸豎,為了防止意外,你還是要知道,GNU make是按照GNUmakefile ,makefile ,Makefile依次進(jìn)行查找的,同時(shí)盡可能的確保你的目錄下只有Makefile一個(gè)文件。

需要特別說(shuō)明的是,GNUmakefile人如其名,只有GNU make可以識(shí)別,make也有不同的版本和來(lái)源和C的編譯器一樣,只不過(guò)linux上用GNU make的還是比較多。但仍然建議使用 Makefile這個(gè)文件名。

有了潛規(guī)則,你就不需要如此寫(xiě)

 
 
 
  1. $make Makefile

直接 make會(huì)查找。那么我們先做第一個(gè)例子。你將下面的內(nèi)容,保存為Makefile這個(gè)文件在./attr這個(gè)目錄下

 
 
 
  1. what:
  2. gcc -Wall -c ./attr.c ./control.c ./view.c ./value.c ./model.c
  3. gcc ./attr.o ./control.o ./view.o ./value.o ./model.o -o attr
  4. heihei:
  5. rm *.o

注意兩個(gè)書(shū)寫(xiě)問(wèn)題

1、what需要頂頭寫(xiě),表示一個(gè)操作的開(kāi)始,用此來(lái)直接區(qū)分不同操作的描述范圍

2、gcc等實(shí)際操作的內(nèi)容前面需要空一個(gè)tab。

鬼話(huà):“操作”只是我的口頭語(yǔ),官方的說(shuō)法叫“規(guī)則的目標(biāo)”,我只是希望新手理解實(shí)際就是一個(gè)操作,而且操作里面可以有很多命令 依次組成依次執(zhí)行,而且make一次只會(huì)對(duì)一個(gè)操作進(jìn)行操作,除非其他操作和這個(gè)操作有依賴(lài)關(guān)系。但操作通常都是有操作的結(jié)果(輸出的文件),所以叫規(guī)則 的目標(biāo)

鬼話(huà):“頂頭寫(xiě)”除了描述“規(guī)則的目標(biāo)”外,還有很多其他頂頭寫(xiě)的事情,因此,不單單要頂頭寫(xiě),你還需要加上個(gè)‘:’,這樣,make就可以知道,頂頭寫(xiě),同時(shí)存在一個(gè)‘:’則是一個(gè)操作的開(kāi)始,也就是“規(guī)則的目標(biāo)”。

鬼話(huà):關(guān)于"what",我實(shí)在想不出什么名詞,能說(shuō)明“規(guī)則的目標(biāo)”有什么特殊的命名方式。用what是希望大家理解,規(guī)則的目標(biāo)的名字,并沒(méi)有什么特殊約束,你愛(ài)怎么寫(xiě)怎么寫(xiě),但存在一些潛規(guī)則和make的規(guī)矩會(huì)讓你吃苦頭,只是我在邊上 “what,寫(xiě)這個(gè)例子時(shí),我確實(shí)在what,heihei"。比如通常,heihei應(yīng)該用 clean來(lái)實(shí)現(xiàn)。同時(shí),你執(zhí)行如下命令

 
 
 
  1. make
  2. make what
  3. make clean

你會(huì)發(fā)現(xiàn),make沒(méi)有后面的參數(shù)時(shí),執(zhí)行了what。不是因?yàn)閣hat的單詞字幕更少。而是因?yàn)閣hat是第一個(gè)規(guī)則。因此,通常你需要將最常用的,當(dāng)然 未 必是build操作,放在第一個(gè)。這樣可以簡(jiǎn)化你的操作。直接make就可以。但這個(gè)最常用的,與你和你的開(kāi)發(fā)小組第一直覺(jué)希望make做什么有關(guān)系。通常程 序員之間會(huì)說(shuō)“這樣這樣后,make一下”而不會(huì)解釋make what。

你問(wèn)“make what?"

同事說(shuō):“對(duì)就是make what!"

"make what what ???”

“就是make what 啊,你what 什么 what ???”

這說(shuō)明兩個(gè)問(wèn)題,第一,make的第一個(gè)規(guī)則,盡可能是你們小組的共識(shí)常用工作,第二,命名很重要。你和你的同伙"what"來(lái)“what"去,最多相互 懷疑智商問(wèn)題。但如果你起名叫“l(fā)ove",然后和你的女同事說(shuō),記得make love一下。當(dāng)心她告你性騷擾。

現(xiàn)在你已經(jīng)發(fā)現(xiàn)make 針對(duì)Makefile有第一個(gè)好處了。就是批處理化。算是腳本的一種功能體現(xiàn)吧。不過(guò)你反復(fù)的執(zhí)行

 
 
 
  1. make what

系統(tǒng)會(huì)機(jī)械呆板的毫無(wú)保留的進(jìn)行執(zhí)行。如果我們只想執(zhí)行那些被改變的呢?你可以嘗試如下方式:

 
 
 
  1. what: ./control.c
  2. gcc -Wall -c ./attr.c ./control.c ./view.c ./value.c ./model.c
  3. gcc ./attr.o ./control.o ./view.o ./value.o ./model.o -o attr

保存,我們?cè)賵?zhí)行兩邊make。或者make what。

現(xiàn)在回到haha上。繼續(xù)make haha ,兩邊,恩,你會(huì)發(fā)現(xiàn)和前面一樣。沒(méi)錯(cuò)。我們?cè)贀Q一下

 
 
 
  1. ./control.o:./control.c
  2. gcc -Wall -c ./attr.c ./control.c ./view.c ./value.c ./model.c
  3. gcc ./attr.o ./control.o ./view.o ./value.o ./model.o -o attr
  4. clean:
  5. rm *.o

我們?cè)賛ake,此時(shí)make會(huì)提示,./contorl.o是最新的了。沒(méi)有必要處理。這是因?yàn)閙ake會(huì)根據(jù)目標(biāo),./control.o的依賴(lài),./control.c來(lái)判斷,是否需要對(duì)目標(biāo)進(jìn)行重新處理。如果依賴(lài)沒(méi)有被更新過(guò),那么目標(biāo)對(duì)應(yīng)的處理,就是下面的兩個(gè)gcc命令,則不會(huì)進(jìn)行。這樣好處是顯而易見(jiàn)的。你對(duì)應(yīng)的C文件沒(méi)有更新,何必處理呢?

你此時(shí),將control.c的第一行,加次回車(chē),意思是讓文件多個(gè)空白行。保存,再

 
 
 
  1. make

此時(shí),gcc又被運(yùn)行了。怎么樣?讓make幫你查找當(dāng)前那些文件被改動(dòng)了,很方便,很貼心吧。不過(guò)此時(shí)又有個(gè)問(wèn)題,你嘗試將model.c同樣加上一個(gè)空白行,保存,再

 
 
 
  1. make

結(jié)果提示,已是最新文件。沒(méi)辦法,確實(shí)如此啊,你的依賴(lài)規(guī)則只提到了control.c,而你的目標(biāo)是./control.o,無(wú)非目標(biāo)下的執(zhí)行,你做了很多.o的生成,和最終attr執(zhí)行程序的鏈接。同樣的錯(cuò)誤會(huì)發(fā)生在你修改control.h。make會(huì)查找依賴(lài)的文件的更新情況。但是不會(huì)啟動(dòng)C的預(yù)編譯系統(tǒng)來(lái)判斷,其所#include的文件是否更新。

你可以嘗試

 
 
 
  1. make
  2. make clean
  3. make

此時(shí),clean會(huì)刪除掉所有的.o文件,所以第二次make又再次運(yùn)行。因此make除了看依賴(lài)是否改變,還會(huì)看目標(biāo)是否存在。由此引發(fā)一個(gè)問(wèn)題。你嘗試

 
 
 
  1. make
  2. rm attr
  3. make

怎么樣?第二次make不工作了。因?yàn)?/control.o確實(shí)存在啊。即便./attr被刪除了。但和目標(biāo)生成的依賴(lài)沒(méi)有關(guān)系。和目標(biāo)也沒(méi)關(guān)系。雖然你的批處理的最終目標(biāo)是./attr。但是make 的默認(rèn)操作是看./control.o由此你需要注意,考慮一個(gè)現(xiàn)實(shí),最終編譯鏈接,是做什么事情?通常我們將編譯鏈接的工作稱(chēng)為build。區(qū)別于強(qiáng)制工作 rebuild,即便所有的文件沒(méi)有被更新,也將所有的文件進(jìn)行重新操作。由此我們可以如下寫(xiě):

 
 
 
  1. control.o:./control.c ./control.h
  2. gcc -Wall -c ./control.c
  3. ./value.o:./value.c ./value.h
  4. gcc -Wall -c ./model.c
  5. ./model.o:./model.c ./value.h
  6. gcc -Wall -c ./model.c
  7. ./view.o:./view.c ./value.h
  8. gcc -Wall -c ./view.c
  9. ./attr.o:./attr.c ./value.h
  10. gcc -Wall -c ./attr.c
  11. build:./control.o ./value.o ./model.o ./view.o ./attr.o
  12. gcc ./attr.o ./control.o ./view.o ./value.o ./model.o -o attr
  13. rebuild:
  14. clean
  15. build
  16. clean:
  17. rm *.o

我們運(yùn)行一下

 
 
 
  1. make clean
  2. make

哦,第一次單獨(dú)的make會(huì)出來(lái)一個(gè)

 
 
 
  1. gcc -Wall -c ./control.c
  2. make build

哦。有一堆 gcc -Wall,還有一個(gè)錯(cuò)誤,提示,沒(méi)有value.o這個(gè)文件。導(dǎo)致無(wú)法鏈接。還是那句

鬼話(huà):我盡可能教錯(cuò)的,這樣你才知道,對(duì)的有什么價(jià)值。與其挨老師的板子說(shuō)你不努力死記硬背,不如到我野鬼的坑里摔一摔,鍛煉個(gè)強(qiáng)健筋骨。

如果你再運(yùn)行make rebuild

會(huì)提示,找不到clean

如果你再次運(yùn)行

 
 
 
  1. make build

則仍然會(huì)繼續(xù)執(zhí)行,不在乎是否.o存在,C文件是否被更新。

即便你更新 define_attr.h,對(duì)于model.o仍然無(wú)動(dòng)于衷。你忘了在./model.o的依賴(lài)中增加這個(gè)文件了嘛。

上面這個(gè)情況說(shuō)明了幾個(gè)問(wèn)題:

1、make 仍然是針對(duì)第一個(gè)規(guī)則目標(biāo)進(jìn)行默認(rèn)處理。

2、make build 依次檢測(cè).o文件這些目標(biāo),并根據(jù).o文件啟動(dòng)對(duì)應(yīng)的目標(biāo)的執(zhí)行。

3、你會(huì)發(fā)現(xiàn),./value.o:的實(shí)際執(zhí)行書(shū)寫(xiě)不當(dāng),導(dǎo)致沒(méi)有去完成./value.o的生成,而是做了model.o的工作。

4、clean我確實(shí)寫(xiě)了,為什么找不到?

5、很多依賴(lài)好煩人,難道我們需要根據(jù)C代碼一個(gè)個(gè)找頭文件?你忘了在./model.o的依賴(lài)中增加這個(gè)文件了嘛。

6、make build總在執(zhí)行。正常,build看成了一個(gè)目標(biāo)。而這個(gè)目標(biāo)并不是文件,則make始終認(rèn)為這個(gè)目標(biāo)需要執(zhí)行。

針對(duì)第一個(gè)問(wèn)題,如果你反復(fù)debug時(shí),需要盡可能的將所有的編譯,并鏈接,那么build是需要作為默認(rèn)規(guī)則。因此我們需要把build調(diào)整到第一個(gè)位置。

第二第三個(gè)問(wèn)題是,該死的規(guī)則依賴(lài)的書(shū)寫(xiě)方式,還是麻煩和容易書(shū)寫(xiě)出錯(cuò)。我們可以使用通配符和自動(dòng)化變量來(lái)設(shè)計(jì)一個(gè)通用處理方法。如下

 
 
 
  1. %.o:%.c
  2. gcc -Wall -c $< $@

%表示一個(gè)通配符。這只能正對(duì) x.o ,而不會(huì)針對(duì)x.p.o等情況。

 
 
 
  1. %.o:%.c

表示,任意文件名,后綴為.c的,為依賴(lài),對(duì)應(yīng)的目標(biāo)文件是同名的文件名,后綴為.o,我們使用同樣一個(gè)規(guī)則。

$< 表示規(guī)則的依賴(lài),$@表示規(guī)則的目標(biāo)。其實(shí)你更本不需要寫(xiě)這個(gè)內(nèi)容,make也隱藏了這個(gè)默認(rèn)規(guī)則。無(wú)非默認(rèn)的情況并沒(méi)有沒(méi)用-Wall

第四個(gè)問(wèn)題是,為什么rebuild的操作找不到clean。很簡(jiǎn)單,clean是個(gè)操作規(guī)則,你可以理解成一個(gè)函數(shù)調(diào)用另一個(gè)函數(shù),而不是具體的執(zhí)行語(yǔ)句,當(dāng)然切記clean并不是個(gè)函數(shù),因此你應(yīng)當(dāng)把clean作為一個(gè)依賴(lài)放到rebuild 之后,而不是作為操作。clean不是磁盤(pán)文件,此時(shí)make 在磁盤(pán)上尋找clean自然找不到。這還只是個(gè)故事,如果想讓故事增加點(diǎn)懸疑,你可以讓磁盤(pán)上真有個(gè)叫clean的文件。這種情況下,如果僅是個(gè)操作,而不是文件,那么你需要用.PHONY來(lái)說(shuō)明一下。

第5個(gè)問(wèn)題,我們可以借助gcc的一個(gè)工作, -MM,其目的是,對(duì)C文件進(jìn)行分析,列出其依賴(lài)的頭文件是什么。你可以執(zhí)行如下命令

 
 
 
  1. gcc -M model.c
  2. gcc -MM model.c

看一下 ,上述兩個(gè)參數(shù)的差異。為了省省屏幕,通常還是-MM吧,他可以忽略默認(rèn)的頭文件位置,也即那些 <>內(nèi)的頭文件。除非你需要檢查<>內(nèi)的頭文件是否路徑引用正確。否則 -MM是選擇。此時(shí)gcc給自動(dòng)給你打印出依賴(lài),只不過(guò)在屏幕上。你完全可以將其輸出在一個(gè)文件里。如下:

 
 
 
  1. gcc -MM model.c > model.d

我們可以在Makefile 里 增加

 
 
 
  1. sinclude model.d

這基本等同于C語(yǔ)言里的#include。將model.d的內(nèi)容增加到當(dāng)前Makefile中進(jìn)行分析,執(zhí)行。

第6個(gè)問(wèn)題,一個(gè)簡(jiǎn)單的方法如下,我們可以讓build的依賴(lài)是最終的執(zhí)行文件。而最終的執(zhí)行文件作為一個(gè)目標(biāo),其依賴(lài)各種.o如下

 
 
 
  1. build: attr
  2. attr:./control.o ./value.o ./model.o ./view.o ./attr.o

因此我們的Makefile可以如下設(shè)計(jì)

 
 
 
  1. build:attr
  2. attr:%.o
  3. gcc ./attr.o ./control.o ./view.o ./value.o ./model.o -o attr
  4. rebuild:
  5. clean
  6. build
  7. clean:
  8. rm *.o *.d
  9. include view.d model.d value.d attr.d control.d
  10. %.o :%.c %d
  11. gcc -Wall -c $< -o $@
  12. .PHONY: rebuild clean build

不過(guò)這樣還是麻煩,因?yàn)槟阈枰止ぐ阉械?d文件進(jìn)行生成才能使用,而且你會(huì)發(fā)現(xiàn)源代碼的文件名被使用了很多地方,無(wú)非是后綴有.d,有.o,雖然我們使用%.o做了個(gè)通配符的.o依賴(lài),讓所有當(dāng)前能找到.o都加入進(jìn)來(lái),但仍然是麻煩。一個(gè)簡(jiǎn)單清爽的做法如下:

 
 
 
  1. CFLAG := -Wall -c
  2. CC := gcc
  3. sources = model.c view.c attr.c control.c value.c
  4. build:attr
  5. %.o :%.c
  6.     $(CC) $(CFLAG) $< -o $@
  7. %.d: %.c
  8.     $(CC) -MM  $< > $@.$$$$; \
  9.     sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
  10.     rm -f $@.$$$$
  11. sinclude $(sources:.c=.d)
  12. attr:$(sources:.c=.o)
  13.     gcc $^ -o $@
  14.     
  15. clean:
  16.     -rm  %.o %.d
  17. rebuild:clean build
  18.         
  19. .PHONY:rebuild clean build 

注意幾個(gè)問(wèn)題

$< ,$@,$^詳細(xì)信息,你需要參考文獻(xiàn) 6,他們是自動(dòng)化變量。

%,和*的差異,也需要仔細(xì)閱讀參考文獻(xiàn) 6 。

sinclude 可以引入一批文件。

rm之前多了個(gè) -,意思是如果這是個(gè)錯(cuò)誤執(zhí)行,則忽略,而不是make中斷。你覺(jué)得沒(méi)用?那你將 -rm %.o刪除掉。然后嘗試執(zhí)行以下命令

 
 
 
  1. make clean
  2. make rebuild

沒(méi)有.o文件,好事啊,難道就不能繼續(xù)build嗎?make對(duì)實(shí)際的執(zhí)行命令,如果出錯(cuò)就停止了。還是安心加上 -吧,如果有些執(zhí)行不在乎其是否正常,rm是典型的例子。

%d:%c后面執(zhí)行的是什么意思?你在參考文獻(xiàn)6中同樣可以找到。這里還引入了變量的概念。

鬼話(huà):變量是個(gè)好東西,你可以和C語(yǔ)言中的#define近似理解。不過(guò)還是有些區(qū)別,在展開(kāi)的時(shí)候。同時(shí)特別諸如CC,CFLAG這些變量,屬于隱含的變量。本身系統(tǒng)會(huì)有一定默認(rèn)的含義,上面這樣的做法,是重新書(shū)寫(xiě)定義,不要亂表示其他內(nèi)容。多看看書(shū)是有好處的。

針對(duì)上面的內(nèi)容,基本上你可以直接根據(jù)C文件的列表,也即你修改sources的后續(xù)內(nèi)容進(jìn)行自動(dòng)化編譯了。包括依賴(lài)的自動(dòng)生成。當(dāng)然你完全可以如下操作,畢竟gcc -MM的內(nèi)容,通常不重要,看這也眼花。

 
 
 
  1. %.d: %.c
  2. @set -e; rm -f $@;\
  3. $(CC) -MM $(CFLAGS) $< > $@.$$$$;\
  4. sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;\
  5. rm -f $@.$$$$

鬼話(huà):上面這些內(nèi)容該怎么解釋。我說(shuō)了。多半你也忘,不如你自己查資料。與其google一下,不如找到shell的相關(guān)書(shū)籍尋找答案。我希望從告訴你什么資料,多少頁(yè)多少行,最初級(jí)階段開(kāi)始,到我告訴你這本書(shū),你自己找,到你自己去尋找一本書(shū),找到相關(guān)內(nèi)容,這么延伸的提升你自主查找資料的能力。別抱怨我懶,我勤快了,你就懶。我懶,你就有機(jī)會(huì)勤快了。


分享標(biāo)題:C編程鬼話(huà):完善MVC的DEMO,閑話(huà)MAKEFILE
文章出自:http://m.5511xx.com/article/ccehoso.html