make用法

make是一個(gè)命令工具,它解釋 Makefile 中的指令(應(yīng)該說(shuō)是規(guī)則)韭脊。在 Makefile文件中描述了整個(gè)工程所有文件的編譯順序、編譯規(guī)則单旁。

準(zhǔn)備知識(shí):編譯沪羔,鏈接,靜態(tài)庫(kù)象浑,共享庫(kù)
  • 編譯:把高級(jí)語(yǔ)言所書寫的代碼轉(zhuǎn)換成機(jī)器可識(shí)別的指令任内,此時(shí)還不能夠被執(zhí)行,編譯器通過(guò)檢查高級(jí)語(yǔ)言的語(yǔ)法融柬,函數(shù)和變量的聲明是否正確死嗦!如果正確則產(chǎn)生中間目標(biāo)文件(目標(biāo)文件在Liunx中默認(rèn)后綴為“.o”)
  • 鏈接:將多.o 文件,或者.o 文件和庫(kù)文件鏈接成為可被操作系統(tǒng)執(zhí)行的可執(zhí)行程序
  • 靜態(tài)庫(kù):又稱為文檔文件(Archive File) 粒氧。它是多個(gè).o文件的集合越除。Linux中靜態(tài)庫(kù)文件的后綴為“.a”
  • 共享庫(kù):也是多個(gè).o 文件的集合,但是這些.o 文件時(shí)有編譯器按照一種特殊的方式生成(共享庫(kù)已經(jīng)具備了可執(zhí)行條件)

在執(zhí)行 make 之前外盯,需要一個(gè)命名為 Makefile 的特殊文件(本文的后續(xù)將使用Makefile 作為這個(gè)特殊文件的文件名)來(lái)告訴 make 需要做什么(完成什么任務(wù))摘盆,該怎么做。
當(dāng)使用make 工具進(jìn)行編譯時(shí)饱苟,工程中以下幾種文件在執(zhí)行make 時(shí)將會(huì)被編譯(重新編譯):

  • 所有的源文件沒(méi)有被編譯過(guò)孩擂,則對(duì)各個(gè) C 源文件進(jìn)行編譯并進(jìn)行鏈接,生成最后的可執(zhí)行程序箱熬;
  • 每一個(gè)在上次執(zhí)行 make 之后修改過(guò)的 C 源代碼文件在本次執(zhí)行make 時(shí)將會(huì)被重新編譯类垦;
  • 頭文件在上一次執(zhí)行make 之后被修改。則所有包含此頭文件的 C 源文件在本次執(zhí)make 時(shí)將會(huì)被重新編譯城须。
Makefile規(guī)則介紹

一個(gè)簡(jiǎn)單的 Makefile 描述規(guī)則組成:

      TARGET... : PREREQUISITES...

            COMMAND

            ...

            ...
  • target:規(guī)則的目標(biāo)蚤认。通常是最后需要生成的文件名或者為了實(shí)現(xiàn)這個(gè)目的而必需的中間過(guò)程文件名「夥ィ可以是.o文件砰琢、也可以是最后的可執(zhí)行程序的文件名等。另外,目標(biāo)也可以是一個(gè)make執(zhí)行的動(dòng)作的名稱陪汽,如目標(biāo)“clean”(目標(biāo)“clean”不是一個(gè)文件训唱,它僅僅代表執(zhí)行一個(gè)動(dòng)作的標(biāo)識(shí)),我們稱這樣的目標(biāo)是“偽目標(biāo)”挚冤。
  • prerequisites:規(guī)則的依賴雪情。生成規(guī)則目標(biāo)所需要的文件名列表。通常一個(gè)目標(biāo)依賴于一個(gè)或者多個(gè)文件你辣。
  • command:規(guī)則的命令行。是規(guī)則所要執(zhí)行的動(dòng)作(任意的shell 命令或者是可在shell 下執(zhí)行的程序)尘执。它限定了make 執(zhí)行這條規(guī)則時(shí)所需要的動(dòng)作舍哄。
    這也是書寫 Makefile 中容易產(chǎn)生,而且比較隱蔽的錯(cuò)誤誊锭。
    命令就是在任何一個(gè)目標(biāo)的依賴文件發(fā)生變化后重建目標(biāo)的動(dòng)作描述表悬。一個(gè)目標(biāo)可以沒(méi)有依賴而只有動(dòng)作(指定的命令)。比如Makefile 中的目標(biāo)“clean”丧靡,此目標(biāo)沒(méi)有依賴蟆沫,只有命令。它所定義的命令用來(lái)刪除 make 過(guò)程產(chǎn)生的中間文件(進(jìn)行清理工作)温治。
    在 Makefile 中“規(guī)則”就是描述在什么情況下饭庞、如何重建規(guī)則的目標(biāo)文件,通常規(guī)則中包括了目標(biāo)的依賴關(guān)系(目標(biāo)的依賴文件)和重建目標(biāo)的命令熬荆。make 執(zhí)行重建目標(biāo)的命令舟山,來(lái)創(chuàng)建或者重建規(guī)則的目標(biāo)(此目標(biāo)文件也可以是觸發(fā)這個(gè)規(guī)則的上一個(gè)規(guī)則中的依賴文件)。規(guī)則包含了文件之間的依賴關(guān)系和更新此規(guī)則目標(biāo)所需要的命令卤恳。
    一個(gè) Makefile 文件中通常還包含了除規(guī)則以外的很多東西(后續(xù)我們會(huì)一步一步的展開)累盗。一個(gè)最簡(jiǎn)單的Makefile 可能只包含規(guī)則。規(guī)則在有些 Makefile 中可能看起來(lái)非常復(fù)雜突琳,但是無(wú)論規(guī)則的書寫是多么的復(fù)雜若债,它都符合規(guī)則的基本格式。
    make 程序根據(jù)規(guī)則的依賴關(guān)系拆融,決定是否執(zhí)行規(guī)則所定義的命令的過(guò)程我們稱之為執(zhí)行規(guī)則蠢琳。
簡(jiǎn)單的示例

一個(gè)簡(jiǎn)單的Makefile,來(lái)描述如何創(chuàng)建最終的可執(zhí)行文件“edit”镜豹,此可執(zhí)行文件依賴于8個(gè)C源文件和3個(gè)頭文件挪凑。Makefile文件的內(nèi)容如下:

  #sample Makefile

  edit : main.o kbd.o command.o display.o \

          insert.o search.o files.o utils.o

        cc -o edit main.o kbd.o command.o display.o \

              insert.o search.o files.o utils.o

  main.o : main.c defs.h

        cc -c main.c

  kbd.o : kbd.c defs.h command.h

        cc -c kbd.c

  command.o : command.c defs.h command.h

        cc -c command.c

  display.o : display.c defs.h buffer.h

        cc -c display.c

  insert.o : insert.c defs.h buffer.h

        cc -c insert.c

  search.o : search.c defs.h buffer.h

        cc -c search.c

  files.o : files.c defs.h buffer.h command.h

        cc -c files.c

  utils.o : utils.c defs.h

        cc -c utils.c

  clean :

        rm edit main.o kbd.o command.o display.o \

              insert.o search.o files.o utils.o

首先書寫時(shí),可以將一個(gè)較長(zhǎng)行使用反斜線(\ )來(lái)分解為多行逛艰。但需要注意:反斜線之后不能有空格(這也是大 家最容易犯的錯(cuò)誤躏碳,錯(cuò)誤比較隱蔽)。
在完成了這個(gè)Maekfile以后;需要?jiǎng)?chuàng)建可執(zhí)行程序“edit”菇绵,所要做的就是在包含此Makefile的目錄(當(dāng)然也在代碼所在的目錄)下輸入命令“make”肄渗。刪除已經(jīng)此目錄下之前使用“make”生成的文件(包括那些中間過(guò)程的.o文件),也只需要輸入命令“make clean”就可以了咬最。

make如何工作

默認(rèn)的情況下翎嫡,make執(zhí)行的是Makefile中的第一個(gè)規(guī)則,此規(guī)則的第一個(gè)目標(biāo)稱之為“最終目的”或者“終極目標(biāo)”(就是一個(gè)Makefile最終需要更新或者創(chuàng)建的目標(biāo))永乌。
上例的 Makefile惑申,目標(biāo)edit在Makefile中是第一個(gè)目標(biāo),因此它就是make的終極目標(biāo)翅雏。當(dāng)修改了任何C源文件或者頭文件后圈驼,執(zhí)行 make 將會(huì)重建終極目標(biāo)edit
當(dāng)在shell提示符下輸入“make”命令以后望几。make讀取當(dāng)前目錄下的Makefile文件绩脆,并將Makefile文件中的第一個(gè)目標(biāo)作為其執(zhí)行的終極目標(biāo),開始處理第一個(gè)規(guī)則(終極目標(biāo)所在的規(guī)則)橄抹。在上例中靴迫,第一個(gè)規(guī)則就是目標(biāo)edit所在的規(guī)則。規(guī)則描述了edit的依賴關(guān)系楼誓,并定義了鏈接.o文件生成目標(biāo)edit的命令玉锌;make在執(zhí)行這個(gè)規(guī)則所定義的命令之前,首先處理目標(biāo)edit的所有的依賴文件(例子中的那些.o文件)的更新規(guī)則(以這些.o文件為目標(biāo)的規(guī)則)疟羹。對(duì)這些.o文件為目標(biāo)的規(guī)則處理有下列三種情況:

  1. 目標(biāo).o 文件不存在芬沉,使用其描述規(guī)則創(chuàng)建它;
  2. 目標(biāo).o 文件存在阁猜,目標(biāo).o 文件所依賴的.c 源文件丸逸、.h 文件中的任何一個(gè)比目標(biāo).o文件“更新”(在上一次 make 之后被修改)。則根據(jù)規(guī)則重新編譯生成它剃袍;
  3. 目標(biāo).o 文件存在黄刚,目標(biāo).o 文件比它的任何一個(gè)依賴文件(的.c 源文件、.h 文件) “更新”(它的依賴文件在上一次make 之后沒(méi)有被修改)民效,則什么也不做憔维。

這些.o 文件所在的規(guī)則之所以會(huì)被執(zhí)行,是因?yàn)檫@些.o 文件出現(xiàn)在終極目標(biāo)的依賴列表中畏邢。在 Makefile 中一個(gè)規(guī)則的目標(biāo)如果不是終極目標(biāo)所依賴的(或者終極目標(biāo)的依賴文件所依賴的)业扒,那么這個(gè)規(guī)則將不會(huì)被執(zhí)行,除非明確指定執(zhí)行這個(gè)規(guī)則(可以通過(guò)make的命令行指定重建目標(biāo)舒萎,那么這個(gè)目標(biāo)所在的規(guī)則就會(huì)被執(zhí)行程储,例如make clean)。在編譯或者重新編譯生成一個(gè).o文件時(shí),make同樣會(huì)去尋找它的依賴文件的重建規(guī)則(是這樣一個(gè)規(guī)則:這個(gè)依賴文件在規(guī)則中作為目標(biāo)出現(xiàn))章鲤,在這里就是.c 和.h 文件的重建規(guī)則摊灭。在上例的Makefile中沒(méi)有哪個(gè)規(guī)則的目標(biāo)是.c或者.h 文件,所以沒(méi)有重建.c 和.h 文件的規(guī)則败徊。
完成了對(duì).o 文件的創(chuàng)建(第一次編譯)或者更新之后帚呼,make 程序?qū)⑻幚斫K極目標(biāo)“edit”所在的規(guī)則,分為以下三種情況:

  1. 目標(biāo)文件“edit”不存在皱蹦,則執(zhí)行規(guī)則以創(chuàng)建目標(biāo)“edit”煤杀。
  2. 目標(biāo)文件“edit”存在,其依賴文件中有一個(gè)或者多個(gè)文件比它“更新”沪哺,則根據(jù)規(guī)則重新鏈接生成“edit”沈自。
  3. 目標(biāo)文件“edit”存在,它比它的任何一個(gè)依賴文件都“更新”凤粗,則什么也不做。

上例中今豆,如果更改了源文件“insert.c”后執(zhí)行make嫌拣,“insert.o”將被更新,之后終極目標(biāo)“edit”將會(huì)被重生成呆躲;如果我們修改了頭文件“command.h”之后運(yùn)行“make”异逐,那么“kbd.o”、“command.o”和“files.o”將會(huì)被重新編譯插掂,之后同樣終極目標(biāo)“edit”也將被重新生成灰瞻。

指定變量

objects作為一個(gè)變量,它代表所有的.o文件的列表辅甥。在定義了此變量后酝润,我們就可以在需要使用這些.o文件列表的地方使用“$(objects)”來(lái)表示.o文件的列表,而不需要羅列所有的.o文件璃弄。

make如何解析makefile文件

GUN make 的執(zhí)行過(guò)程分為兩個(gè)階段要销。

  1. 讀取所有的 makefile 文件(包括“MAKIFILES”變量指定的、指示符“include”指定的夏块、以及命令行選項(xiàng)“-f(--file)”指定的 makefile 文件)疏咐,內(nèi)建所有的變量、明確規(guī)則和隱含規(guī)則脐供,并建立所有目標(biāo)和依賴之間的依賴關(guān)系結(jié)構(gòu)鏈表浑塞。
  2. 根據(jù)第一階段已經(jīng)建立的依賴關(guān)系結(jié)構(gòu)鏈表決定哪些目標(biāo)需要更新,并使用對(duì)應(yīng)的規(guī)則來(lái)重建這些目標(biāo)政己。
總結(jié)

make 的執(zhí)行過(guò)程如下:

  1. 依次讀取變量MAKEFILES定義的makefile文件列表
  2. 讀取工作目錄下的makefile文件(根據(jù)命名的查找順序GNUmakefile酌壕, makefileMakefile,首先找到哪個(gè)就讀取哪個(gè))
  3. 依次讀取工作目錄makefile文件中使用指示符include包含的文件
  4. 查找重建所有已讀取的makefile文件的規(guī)則(如果存在一個(gè)目標(biāo)是當(dāng)前讀取的 某一個(gè)makefile文件仅孩,則執(zhí)行此規(guī)則重建此 makefile文件托猩,完成以后從第一步開始重新執(zhí)行)
  5. 初始化變量值并展開那些需要立即展開的變量和函數(shù)并根據(jù)預(yù)設(shè)條件確定執(zhí)行分支
  6. 根據(jù)終極目標(biāo)以及其他目標(biāo)的依賴關(guān)系建立依賴關(guān)系鏈表
  7. 執(zhí)行除終極目標(biāo)以外的所有的目標(biāo)的規(guī)則(規(guī)則中如果依賴文件中任一個(gè) 文件的時(shí)間戳比目標(biāo)文件新,則使用規(guī)則所定義的命令重建目標(biāo)文件)
  8. 執(zhí)行終極目標(biāo)所在的規(guī)則
說(shuō)明:

執(zhí)行一個(gè)規(guī)則的過(guò)程是這樣的:
對(duì)于一個(gè)存在的規(guī)則(明確規(guī)則和隱含規(guī)則)
首先辽慕,make程序?qū)⒈容^目標(biāo)文件和所有的依賴文件的時(shí)間戳京腥。如果目標(biāo)的時(shí)間戳比所有依賴文件的時(shí)間戳更新(依賴文件在上一次執(zhí)行make之后沒(méi)有被修改),那么什么也不做溅蛉。否則(依賴文件中的某一個(gè)或者全部在上一次執(zhí)行make后已經(jīng)被修改過(guò))公浪,規(guī)則所定義的重建目標(biāo)的命令將會(huì)被執(zhí)行。這就是make工作的基礎(chǔ)船侧,也是其執(zhí)行規(guī)制所定 義命令的依據(jù)欠气。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市镜撩,隨后出現(xiàn)的幾起案子预柒,更是在濱河造成了極大的恐慌,老刑警劉巖袁梗,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宜鸯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡遮怜,警方通過(guò)查閱死者的電腦和手機(jī)淋袖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锯梁,“玉大人即碗,你說(shuō)我怎么就攤上這事∧暗剩” “怎么了剥懒?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)合敦。 經(jīng)常有香客問(wèn)我蕊肥,道長(zhǎng),這世上最難降的妖魔是什么蛤肌? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任壁却,我火速辦了婚禮,結(jié)果婚禮上裸准,老公的妹妹穿的比我還像新娘展东。我一直安慰自己,他們只是感情好炒俱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布盐肃。 她就那樣靜靜地躺著爪膊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砸王。 梳的紋絲不亂的頭發(fā)上推盛,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音谦铃,去河邊找鬼耘成。 笑死,一個(gè)胖子當(dāng)著我的面吹牛驹闰,可吹牛的內(nèi)容都是我干的瘪菌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嘹朗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼师妙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起屹培,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤默穴,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后褪秀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蓄诽,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年溜歪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了若专。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片许蓖。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝴猪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出膊爪,到底是詐尸還是另有隱情自阱,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布米酬,位于F島的核電站沛豌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赃额。R本人自食惡果不足惜加派,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望跳芳。 院中可真熱鬧芍锦,春花似錦、人聲如沸飞盆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至孽水,卻和暖如春票腰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背女气。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工杏慰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人主卫。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓逃默,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親簇搅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子柴灯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容