歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> 全力打造Make程式和重新編譯核心技術

全力打造Make程式和重新編譯核心技術

日期:2017/2/27 14:24:47   编辑:更多Linux
  Make通常用來維護程式,使可執行檔的內容保持和原始程式的一致性,因其依循唯有變動才需重新編譯連結的方式,由各檔之間的「依存關系」自動去編譯連結,如此可省下了寶貴的時間和系統資源。在Linux中最普遍的例子應是核心(kernel)的重 編,當讀者把gcc等程式和核心原始程式安裝完後(Slackware中為D套件,SLS中為C和 S套件),便可依實際情況去更新或置換核心的內容。核心是由許多不同的部份所組成 ,如行程的管理、檔案系統的支援、周邊配備的驅動程式、網路通訊的協定等,當組 成的部分有所更新或是不需要時,就需要重編核心,以便產生符合真實環境的核心程 式,使得PC能得到最佳的利用。如沒有SCSI卡的PC便不需要SCSI的驅動程式,而且可 依光碟和音效卡的種類更換不同的驅動程式。如此繁瑣的過程,在make的幫助下,可 以作得又快又好,只需透過一連串的選擇,其馀就完全交給make去負責,真是省事又 方便。和核心編譯有關的細節我們稍後再共同研討。make的最初目的是幫助程式設計 師作為編譯連結時的管理,因此我們先來看看make的用法。     使用時機和環境   當程式寫作或是更新後,編連的步驟便是使用make的最好時機。在Linux中,啟 動make只消打make便可,make會先去找同目錄下的Makefile或是makefile,若找不到 便出現make的參數使用方法。makefile是一個文書檔,可用vi或是jed編輯,它可說 是make的script,make就完全依此檔的內容來動作。在這個檔中,記錄了檔案的產生 方法、相關性質和一些變數等。在這個檔中,凡是以#為開頭者,整行都視為注解, 和shell的script file是相同的。makefile中約略可分成變數區和指令區兩部分, 縱貫檔案的有依存、字尾等規則,共同構成makefile的語法。     Makefile中的變數   在makefile中可將一字串設定給一變數,需要時可如shell的script file展開 ,因此也可稱為巨集(marco),變數設定的方式為:     變數名稱=設定值     除了某些特殊符號外(如#、:、;、=、空白、定位字元、新列字元),其馀都可作 為設定值的內容。一般來說,最好使用英數字,以避免發生不可預料的錯誤,以下是 一些合法的設定       SOURCE = test1.c test2.c test3.c    OBJ = main.o     當要取用(展開)變數時,只需用()將變數括起來,前頭加上$符號即可,如$(OBJ) 這個變數,當make執行至此時,將視為main.o。     依存關系   make的主要工作方式,是依「依存關系」(dependency)來工作的,而所謂的依存關系,就是指兩或多個檔案間彼此的關系,譬如我們寫了一個test.c程式,當我們 編譯如下時:       $ gcc -O -o test test.c     便會產生test.o這個目的檔,因此test.o便是依於test.c,當test.c改變時, test.o也需重新編譯,才能保持程式的最新版本;若test.o是由test1.c和test2.c 所組成的,那test.o同時依存於test1.c及test2.c,依存關系便是相關檔案的先後關系,和檔案的「生成」方式,如C語言的原始檔.c需cc或gcc作編譯後才能生成目標檔 .o,而且make功能強大,在依存規則中並不限定只能作和編譯有關的動作。     接下來就是將依存規則寫入makefile中了,依存規則的格式如下:     目標檔;依存檔;命令     「目標檔」就是「依存檔」照「命令」的方式造出的檔案,如上例便可寫成:       test:test.c;gcc -O -o test test.c     或是可將「命令」寫在下一行,但是需有定位字元作為前導,因此可寫成:       test:test.c       gcc -O -o test test.c       通常以此方式撰寫,認為是較好的方式;若「目標檔」或「依存檔」中有兩個以 上的檔案,各檔案名稱間以空白隔開便可,如下:       test:test1.c test2.c       gcc -O -o test test1.c test.c     如此定下規則,那天若是test1.c或test2.c有修改時(日期會比test.o還新) , make便會重新編譯,若是test.o為最晚者,那就沒有執行命令的必要了。     接下來我們先看范例一:     范例一:     01 #  02 # Makefile for cshow  03 # By Ivor Chen  04 # 08/31/1994  05 #  06  07 CC = gcc  08 OPTIMIZE = -fomit-frame-pointer -O2 -s  09 CFLAGS = $(DEFINES) $(OPTIMIZE)  10 LFLAGS = -N  11  12 PROGS = cshow  13 PROGS_O = cshow.o  14 LIBS = -lvgagl -lvga  15  16 all: progs  17  18 progs: $(PROGS)  19  20 objs: $(PROGS_O)  21  22 .c.o:  23 $(CC) $(CFLAGS) -c -o $*.o $.depend  44 gcc -MM $(patsubst %.o,%.c,$(PROGS_O)) >>.depend  45  46 include .depend     范例一是筆者的cshow程式的makefile,其中01至05行以#開頭作為注解用;07至 14行是設定變數,其中07-10所設定的是有關編譯器及其命令,11至14行則設定被編 譯的檔案名稱及額外需被連結的程式庫名稱;第16行便是一個依存規則,若是我們在 命令列下只打make,那make便會去尋找makefile中的第一個規則來工作,在此這便是 第一個規則,但這個規則比較特殊:一、本規則並無「命令」,二、本規則中的all 並不是檔名,而且其後的progs是下一條規則(第18行)的「目標檔」,這樣一來,當 我們一去make all時,由於all是由progs所構成,因此會跳到第18行去,而第18行 的$(PROGS)是cshow,為做本make最終產生的檔案,為一可執行檔,第20行的cshow.o 便是最終的目的檔,那cshow和cshow.o又是如何產生的?這和第22、25、28行有關, 這幾行是利用下一節的「字尾規則」,稍後再論。   范例一中第32和35行是makefile中另外常見的規則,其目的不是「產生」目的檔 ,而是去「刪除」某些檔案,35行的動作包含在32之中,35行的目的是刪除可執行檔 (rm -f $(PROGS));而32行會先執行35行的動作,再去刪除*.o和*~的檔;若是我 們更新了一大群source的部份時,最好要make clean,否則仍會發生.o和其source 間版本不同的錯誤。     字尾規則   通常我們會以特定的字尾來表示不同檔案的種類,如.c 便是代表c語言的原始檔 , 而.o 通常代表此檔經特定的編譯程式所產生的目的檔,由於在同一系統中同一語 言原始檔的編譯程式皆相同,我們便可為這些原始檔定出一定的編譯方式,這便是字 尾規則(Suffix rule)的用意所在,字尾規則通常是在於定義Makefile的內建依存 規則;字尾規則的語法如下:     .字尾一.字尾二:      命令  '  其中的意義是字尾一的檔案經「命令」的作用後產生字尾二的檔案,如范例一中 的第22和23行:     22 .c.o:  23 $(CC) $(CFLAGS) -c -o $*.o $



Copyright © Linux教程網 All Rights Reserved