Makefile劄記之:Makefile工作原理及隱含規則應用

來源:互聯網
上載者:User

從只有一個Makefile的單級Makefile開始。

對於一個稍大的項目或者說軟體來說,來源程式(.c檔案或者是.h檔案),以及來源程式檔案夾,絕對不只是一個檔案或者來源程式檔案夾,想想你寫的代碼只有一個來源程式或者程式檔案夾還是什麼時候。一個好的程式員,總是希望自己寫的代碼檔案,清晰,一目瞭然,通過不同的檔案夾,不用的名字就能大致看出該程式的功能。

當只有一個來源程式檔案的時候,比如main.h,main.c,這個時候,由於來源程式檔案少,我們可以手動對程式進行編譯:gcc  main.c   -o  main_exe。這個時候,手動編譯器還是很方便的。但是,如果程式有幾十甚至幾百幾千個的時候,這個時候,通過gcc手動的對來源程式進行編譯的時候,就有困難了。另外,好的程式員會去考慮到程式的可移植性和程式檔案之間的關係,我們總是希望把來源程式拿過來直接編譯然後就能運行,我們會把來源程式放在不同的檔案夾下。這樣一來,對於手動編譯器就更加困難了。這個時候,Makefile優勢就顯現出來了。

下面以執行個體來說明Makefile究竟如何編寫,

 

 

/*

*************************************

name:example-one.c

*************************************

*/

#include “example-one.h”

{

      …….

      ……..

}

 

 

*************************************

name:example-one.h

養成每個.c來源程式都有一個與之同名的.h

與之對應來做一些聲明。

*************************************

*/

#include <>

#include <>

 

 

 

 

/*

*************************************

name:example-two.c

*************************************

*/

#include “example-two.h”

#include “example-one.h”

{

      …….

      ……..

}

 

 

*************************************

name:example-two.h

養成每個.c來源程式都有一個與之同名的.h

與之對應來做一些聲明。

*************************************

*/

#include <>

#include <>

 

 

 

 

 

…..

…..

 

 

*************************************

name:main.c

*************************************

#include “example-two.h”

{

  

}

 

在這裡我不講Makefile的規則,對於這些規則,網上的關於Makefile的編寫都大同小異,我主要講講Makefile的工作原理。

按照上述檔案之間的關係不難看出,example-two.c由於使用了example-one.c的東西,那麼當我們編譯example-two.c的時候就需要example-one.c。

還是先來說下幾個關鍵詞

target:cond

按照Makefile的規則,target就是目標,然後cond就是要編譯得到target目標所需要的條件。

其實在很多情況下,我們的Makefile可以唯寫出

%:%.o

這個規則就可以了。

以這個例子為例。雖然按照實際情況上來說,有個層次關係,main.o的編譯需要example-two.c, example-two.h作為必要條件,同理,example-two.o需要example-one.h和example-one.c作為必要條件。

但是,你可以試試,這個例子的Makefile可以簡化到如此簡單:

OBJS := main.o example-one.o example-two.o

EXEC := test

$(EXEC):$(OBJS)

tab           gcc –o $(EXEC)  $(OBJS)

 

寫好commamd之後,make就可以編譯出程式了,絕對沒問題。

Makefile其實也是一種指令碼語言。他只需要知道編譯成可執行程式EXEC所必須的目標檔案OBJS有哪些(這裡對於將目標檔案.o檔案,源檔案 .h, .c檔案同名很重要,所以要養成這種習慣會給變成帶來很大的方便的)。

    GNU 的make 工作時的執行步驟入下:

1、讀入所有的Makefile。

2、讀入被include 的其它Makefile。

3、初始設定檔案中的變數。

4、推導隱晦規則,並分析所有規則。

5、為所有的目標檔案建立依賴關係鏈。

6、根據依賴關係,決定哪些目標要重建。

7、執行產生命令。

當make一旦知道可執行檔所需的目標檔案.o檔案之後,他發現要產生可執行檔需要哪些.o檔案,他就會在你所指定的目錄已經目前的目錄中尋找,當他找不到某一.o檔案的時候,就會啟動隱含規則去試圖產生.o檔案。同樣,當產生.o檔案的時候就會去找相應的.c檔案和.h檔案。這才是這個例子會有如此簡單的Makefile的真正原因。而Makefile的編寫工作最終落實到你給出檔案,讓make去找檔案。而本身來源程式.c檔案中的include也同時告訴Makefile,.c檔案需要哪些.h條件,所以在由.c檔案到.o檔案的過程中可以由它自動來完成,不需要我們明確的顯示的告訴他這些關係。

給個不恰當的比喻:.c  .h檔案相當於人,通過#include  已經extern 等血緣關係,在make之後,構成了家庭這種.o檔案。

family.o: zhang.c   wang.c   zhang_son.h

所有的人都用過這種關係來構成家庭。

然後那麼社區這種可執行檔是有家庭這種.o檔案構成的。那麼在組裝可執行檔這一階段只需要列出該社區的所有的家庭,於是也就自動完成了社區的組建。

community:family_one.o  family_two.o…

總之,在組裝可執行程式的規則中,要列出所需要的所有的.o檔案。

 

 

 

 

 

 

著作權申明:
轉載文章請註明原文出處http://blog.csdn.net/feiyinzilgd/archive/2010/02/07/5297161.aspx
並請聯絡譚海燕本人或者前往譚海燕個人首頁留言 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.