Makefile基礎(chǔ)

什么是Makefile?

  • 一個工程中的源文件不計其數(shù),其按類型、功能问麸、模塊分別放在若干個目錄中,Makefile定義了一系列規(guī)則來制定钞翔,哪些文件需要先編譯口叙,哪些文件需要重新編譯,如何進(jìn)行鏈接等操作嗅战。
  • Makefile就是"自動化編譯"妄田,告訴make命令如何編譯和鏈接俺亮。
  • Makefile也是make命令的配置腳本,默認(rèn)情況下GUN make會在當(dāng)前目錄下尋找文件疟呐,按照優(yōu)先級依次尋找 GNUmakefile -> makefile -> Makefile脚曾。也可使用 make -f/-file “文件名" 手動指定Makefile文件

Makefile文件內(nèi)容

  • 顯示規(guī)則
    • 如何生成一個或多個目標(biāo)文件
  • 隱晦規(guī)則
    • 依賴于Makefile自動推導(dǎo),可以簡略書寫Makefile
  • 變量定義
    • 可以定義變量 一般為String启具,類似于“宏”本讥,當(dāng)Makefile被執(zhí)行時,變量會擴(kuò)展到相應(yīng)的引用位置上
  • 文件指示
    • 一個Makefile引用另外一個Makefile鲁冯。類似于C的include
    • 根據(jù)情況拷沸,指定Makefile有效部分。類似于C的預(yù)編譯
    • 定義多行命令
  • 注釋
    • 只有行注釋“#”

Makefile的規(guī)則

target ... : prerequisites ...
    command
或
target ... : prerequisites ... ; command
  • target: 目標(biāo)文件薯演∽采郑可以是Object File,也可以是執(zhí)行文件跨扮,還可以是標(biāo)簽(Label)序无。
    • 如果是多文件用空格隔開。
    • 也可使用通配符
  • prerequisites:依賴文件衡创,即要生成那個target所需要的文件或其他target
  • command:make需要執(zhí)行的命令
    如果命令太長可以使用“\”作為換行符進(jìn)行換行

Makefile的規(guī)則就是告訴make 文件的依賴關(guān)系以及如何生成目標(biāo)文件帝嗡;

target的文件依賴prerequisite文件,生成規(guī)則在command中

如果prerequisite有一個以上的文件比target新璃氢,target會被認(rèn)為是過時的需要重新生成哟玷,command將被執(zhí)行,從而生成新的target一也。
示例

# 當(dāng)前目錄存在main.c碗降、tool.c、tool.h三個文件
# 要生成一個main目標(biāo)文件依賴于main.o tool.o
main: main.o tool.o
# 生成目標(biāo)的命令
    gcc main.o tool.o -o main
# .PHONY:顯式的指明clean是一個“偽目標(biāo)”
.PHONY: clean
# clean: 標(biāo)簽塘秦,不會生成“clean”文件讼渊,這樣的target稱之為“偽目標(biāo)”,偽目標(biāo)的名字不能和文件名重復(fù)尊剔。clean一般放在文件最后
clean:
# -rm “-” 表示如果某些文件出現(xiàn)問題 跳過
    -rm main *.o

clean偽目標(biāo)需要make顯式調(diào)用make clean

makefile執(zhí)行效果如下

makefile執(zhí)行效果

Makefile是如何工作的

默認(rèn)方式下爪幻,輸入make命令后:

  • make會在當(dāng)前目錄下找名字叫“Makefile”或“makefile”的文件。
  • 如果找到须误,它會找文件中第一個目標(biāo)文件(target)挨稿,并把這個target作為最終目標(biāo)文件,如前面示例中的“main”京痢。
  • 如果main文件不存在奶甘,或main所依賴的.o的修改時間要比main文件新,那么它會執(zhí)行后面所定義的命令來生成main文件
  • 如果main所依賴的.o文件也存在祭椰,那么make會在當(dāng)前文件中找目標(biāo)為.o文件的依賴性臭家,若找到則根據(jù)規(guī)則生成.o文件疲陕。
  • make再用.o文件聲明make的終極任務(wù),也就是可執(zhí)行文件“main”钉赁。

make會層層找文件依賴關(guān)系蹄殃,直到最終編譯出第一個目標(biāo)文件,如果在找的過程出現(xiàn)錯誤你踩,make會退出并拋出錯誤诅岩。Make只管文件的依賴性,編譯錯誤不會理會

Makef中變量的使用

? 如果工程需要加入一個新的“.o”文件 Makefile需要修改多處带膜,為了易維護(hù)吩谦,在Makefile中我們可以使用變量。比如膝藕,我們聲明一個變量為objects式廷,這樣就可以方便的在Makefile中以$(objects)的方式使用這個變量了。

我們修改一下剛剛的Makefile文件

objects = main.o tool.o
main: $(objects)
    gcc $(objects) -o main
.PHONY: clean
clean:
    -rm main $(object)

引用其他的Makefile

在實際開發(fā)中我們會按類型將源文件會分成不同的模塊束莫,每個模塊有一個單獨的Makefile文件懒棉,那么編譯時就需要引入其他模塊的Makefile草描,在Makefile中可以使用include關(guān)鍵字引入其他模塊

# 語法格式
include <filename>
# 如果文件找不到览绿,而你希望make時不理會那些無法讀取的文件而繼續(xù)執(zhí)行,可以在include前加"-"
-include <filename>

環(huán)境變量 MAKEFILES

? 如果當(dāng)前環(huán)境中定義了環(huán)境變量MAKEFILES穗慕,make會把這個變量中的值做一個類似于include的動作饿敲。這個變量中的值是其它的Makefile,用空格分隔逛绵。只是怀各,它和include不同的是,從這個環(huán)境變量中引入的Makefile的“目標(biāo)”不會起作用术浪,如果環(huán)境變量中定義的文件發(fā)現(xiàn)錯誤瓢对,make也會不理。但是建議不要使用這個環(huán)境變量胰苏,因為只要這個變量一被定義硕蛹,那么當(dāng)你使用make時,所有的Makefile都會受到它的影響硕并。

? 也許有時候Makefile出現(xiàn)了奇怪的事法焰,可以查看當(dāng)前環(huán)境中有沒有定義這個變量。

Makefile預(yù)定義變量

Makefile預(yù)定義變量

Makefile自動變量

Makefile自動變量

函數(shù)

# 不帶參數(shù)
define FUNC
$(info echo "hello")
endef

# 調(diào)用 FUNC函數(shù) 輸出hello
$(call FUNC)

# 帶參數(shù)
define FUNC1
$(info echo $(1) $(2))  
endef

# 調(diào)用FUNC1函數(shù) 輸出hello world
$(call FUNC1,hello,world)

make的工作流程

  1. 讀入所有的Makefile倔毙。
  2. 讀入被include的其他Makefile埃仪。
  3. 初始化文件中的變量。
  4. 推導(dǎo)隱晦規(guī)則陕赃,并分析所有規(guī)則卵蛉。
  5. 為所有的目標(biāo)文件創(chuàng)建依賴關(guān)系鏈颁股。
  6. 根據(jù)依賴關(guān)系,決定哪些目標(biāo)要重新生成毙玻。
  7. 執(zhí)行生成命令豌蟋。

上面的流程分兩個階段:1-5 為第一階段、6桑滩、7為第二階段

在第一階段中如果定義的變量被使用了梧疲,make會把變量展開在使用的位置,但不完全展開运准,如果變量出現(xiàn)在依賴關(guān)系的規(guī)則中幌氮,只有依賴被使用的時候,變量才會被展開

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胁澳,一起剝皮案震驚了整個濱河市该互,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌韭畸,老刑警劉巖宇智,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異胰丁,居然都是意外死亡随橘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門锦庸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來机蔗,“玉大人,你說我怎么就攤上這事甘萧±趾幔” “怎么了愚隧?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我气筋,道長聋伦,這世上最難降的妖魔是什么滚朵? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任胚迫,我火速辦了婚禮,結(jié)果婚禮上汇恤,老公的妹妹穿的比我還像新娘庞钢。我一直安慰自己,他們只是感情好因谎,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布基括。 她就那樣靜靜地躺著,像睡著了一般财岔。 火紅的嫁衣襯著肌膚如雪风皿。 梳的紋絲不亂的頭發(fā)上河爹,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音桐款,去河邊找鬼咸这。 笑死,一個胖子當(dāng)著我的面吹牛魔眨,可吹牛的內(nèi)容都是我干的媳维。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼遏暴,長吁一口氣:“原來是場噩夢啊……” “哼侄刽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起朋凉,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤州丹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后杂彭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墓毒,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年亲怠,在試婚紗的時候發(fā)現(xiàn)自己被綠了所计。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡赁炎,死狀恐怖醉箕,靈堂內(nèi)的尸體忽然破棺而出钾腺,到底是詐尸還是另有隱情徙垫,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布放棒,位于F島的核電站姻报,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏间螟。R本人自食惡果不足惜吴旋,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厢破。 院中可真熱鬧荣瑟,春花似錦、人聲如沸摩泪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽见坑。三九已至嚷掠,卻和暖如春捏检,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背不皆。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工贯城, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霹娄。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓能犯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親犬耻。 傳聞我的和親對象是個殘疾皇子悲雳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

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