制造還是制造
安裝.使用make工具,我們可以將大型開發項目分解成多個更易於管理的模塊。對於包含數百個源文件的應用程序,請使用make和。
makefile工具可以簡潔明了地理順源文件之間的復雜關系。而且這麽多源文件,如果每次都要鍵入gcc命令來編譯,對程序員來說會非常困難。
對我來說是壹場災難。make工具可以自動完成編譯工作,只能編譯上次編譯後程序員修改的部分。因此,make的有效使用和
Makefile工具可以大大提高項目開發的效率。同時掌握make和makefile之後,妳就不會再對Linux下的應用軟件無所適從了。
不幸的是,這個強大但非常復雜的編譯器工具在許多關於Linux應用程序的書中都沒有詳細介紹。在這裏我將向您詳細介紹make及其描述文件。
makefile .
生成文件文件
Make工具最重要也是最基本的功能就是通過makefile文件描述源程序之間的關系,自動維護編譯工作。makefile文件需要根據壹些語法來編寫,文件
中間
需要說明如何編譯源文件並連接生成可執行文件,並定義源文件之間的依賴關系。Makefile文件由許多編譯器編譯,包括Windows NT。
編譯器下-維護編譯信息的常用方法是在集成開發環境中,用戶通過友好的界面修改makefile文件。
在UNIX系統中,習慣使用makefile作為Makefile文件。如果要使用其他文件作為makefile,可以使用與下面類似的make命令選項來指定makefile:
$ make -f生成文件. debug
例如,壹個名為prog的程序由三個C源文件filea.c、fileb.c和filec.c以及庫文件LS編譯生成,這三個文件還包含來自。
妳自己的頭文件。
、B.H .和C.H .通常,C編譯器會輸出三個目標文件,filea.o、fileb.o和filec.o..假設文件a.c和文件b.c都必須
聲明使用了壹個名為defs的文件,但是filec.c沒有。也就是filea.c和fileb.c中有這樣的語句:
#包含“定義”
下面的文檔描述了這些文件之間的相互關系:
#這是壹個描述makefile的例子
prog : filea.o fileb.o filec.o
cc文件a.o文件b.o文件c.o -LS -o程序
filea.o : filea.c a.h defs
cc -c文件
fileb.o : fileb.c b.h defs
抄送檔案
filec.o : filec.c
抄送檔案
這個描述文檔是壹個簡單的makefile文件。
請註意,在上面的示例中,第壹個字符為#的行為註釋行。第壹個取消註釋的行指定prog是通過鏈接三個目標文件filea.o、fileb.o和filec.o生成的,第三行描述了如何從prog所依賴的文件創建可執行文件。接下來的4、6和8行分別指定了三個目標文件,而。c和。它們所依賴的h文件和defs文件。第5、7和9行指定如何從目標所依賴的文本中檢索信息。
確立目標。
當文件。c或a.h文件在編譯後被修改,make工具可以自動重新編譯filea.o,如果filea.c和a.h在編譯前後都沒有被修改,test.o仍然存在,則不需要重新編譯。這種依賴性在編譯具有多個源文件的程序時尤其重要。通過對這種依賴的定義,make工具可以避免許多不必要的編譯工作。當然,使用Shell
腳本也可以達到自動編譯的效果。但是Shell腳本會編譯所有的源文件,包括那些不壹定要重新編譯的,而make tool可以根據目標的上次編譯時間和目標所依賴的源文件的更新時間自動確定應該編譯哪個源文件。
作為描述文檔,Makefile壹般需要包含以下內容:
◆宏定義
◆源文件之間的相互依賴
◆可執行命令
簡單宏在Makefile中允許引用源文件和相關編譯信息,在Linux中也稱為變量。引用宏時,只需在變量前加壹個$符號,但值得註意的是,如果變量名超過壹個字符,引用時必須加括號()。以下是所有有效的宏引用:
美元(CFLAGS)
2美元
$Z
$(Z)
最後兩個引用完全壹樣。需要註意的是,壹些宏預定義的變量,在Unix系統中,$ *,$ @,$?和美元
件帶來極大的便利。
#為目標文件定義宏
OBJECTS= filea.o fileb.o filec.o
#為庫文件定義宏
LIBES= -LS
#使用宏重寫makefile
prog: $(對象)
cc $(對象)$(庫)-o prog
……
此時,如果執行不帶參數的make命令,將連接三個目標文件和庫文件ls;但是如果在make命令後加上壹個新的宏定義:
制作“LIBES= -LL -LS”
命令行後面的宏定義會覆蓋makefile文件中的宏定義。如果ll也是壹個庫文件,make命令將連接三個目標文件和兩個庫文件LS和LL。
Unix系統中對常量NULL沒有明確的定義,所以我們在定義NULL字符串時應該使用以下宏定義:
STRINGNAME=
制作命令
在make命令之後,不僅可以出現宏定義,還可以出現其他命令行參數,這些參數指定要編譯的目標文件。它的標準形式是:
target 1[target 2…]:[:][dependent 1…][;命令][#…]
[(tab)命令][#…]
方括號的中間部分表示選項。目標和從屬可以包含字符、數字、句點和“/”符號。除了引用,命令不能包含“#”,並且不允許換行符。
正常情況下,命令行參數只包含壹個“:”。此時,命令序列通常與makefile中定義文件間依賴關系的壹些描述行相關。如果與目標相關聯的描述行指定了相關的命令序列,那麽這些相關的命令將被執行,即使分號和(tab)之後的aommand字段甚至可能為空。如果與目標關聯的行沒有指定命令,將調用系統默認的目標文件生成規則。
如果命令行參數包含兩個冒號“::”,此時的命令序列可能與makefile中描述文件依賴關系的所有行相關。此時,將執行與目標相關聯的描述行。
指向的相關命令。同時,將執行內置規則。
如果在執行command命令時返回壹個非“0”的錯誤信號,例如,makefile中有壹個錯誤目標文件名或壹個以連字符開頭的命令字符串,make操作壹般會停止,但如果make後有壹個“-i”參數,make會忽略這樣的錯誤信號。
Make名稱本身可以接受四個參數:標誌、宏定義、描述文件名和目標文件名。它的標準形式是:
制作[標誌][宏定義][目標]
Unix系統下的flag flags選項及其含義是:
-f file將文件指定為描述文件。如果文件參數是“-”,那麽描述文件指向標準輸入。如果沒有“-f”參數,系統將默認使用壹個名為makefile的文件或當前目錄下壹個名為Makefile的文件作為描述文件。在Linux中,GNU make工具按照GNUmakefile、makefile、makefile的順序在當前工作目錄中搜索Makefile。
-我忽略命令執行返回的錯誤消息。
-s靜默模式,在執行之前不輸出相應的命令行信息。
-r禁止內置規則。
-n非執行模式,輸出所有執行命令,但不執行它們。
-t更新目標文件。
-q make操作將根據目標文件是否已更新返回“0”或非“0”狀態信息。
-p輸出所有宏定義和目標文件描述。
-d調試模式,輸出有關文件和檢測時間的詳細信息。
Linux中make標誌位的常用選項與Unix系統中的略有不同。下面我們只列出不同的部分:
-c dir在讀取makefile之前更改指定的目錄dir。
-I dir當包含其他makefile文件時,使用此選項指定搜索目錄。
-h幫助文檔,顯示所有make選項。
-w顯示處理makefile前後的工作目錄。
通過命令行參數中的target,可以指定make要編譯的目標,並且可以同時定義和編譯多個目標。操作時,從左到右依次編譯目標選項中指定的目標文件。如果在命令行上沒有指定目標,系統默認目標指向描述文件中的第壹個目標文件。
通常,makefile中還定義了壹個clean target,可以用來在編譯時清除中間文件,比如:
清潔:
rm -f *。o
當您運行make clean時,rm -f *。o命令將被執行,編譯過程中生成的所有中間文件將最終被刪除。
隱性規則
make工具中有壹些內置或隱含的規則,這些規則定義了如何從不同的依賴文件建立特定類型的目標。Unix系統通常支持基於文件擴展名的隱式規則,即文件名後綴。此後綴規則定義如何將具有特定文件名後綴的文件(例如. c文件)轉換為具有另壹個文件名後綴的文件(例如。o文件):
。丙:。o
$(CC)$(CFLAGS)$(CPPFLAGS)-c-o $ @ $ & lt;
系統中默認的常用文件擴展名及其含義如下:
。o目標文件
。抄送源文件
。fFORTRAN源文件
。的程序集源文件
。yYacc-C源語法
。lLex源語法
早期的Unix系統也支持Yacc-C源代碼語法和Lex源代碼語法。在編譯過程中,系統將首先查找。c文件與makefile文件中的目標文件相關,如果有依賴的話。y和。l文件,先轉換成。c文件,然後編譯它們生成相應的。o文件;如果沒有與目標相關的. c文件,只有壹個相關的。y文件,系統將編譯。y文件直接。
而GNU make支持除後綴規則之外的另壹種類型的隱式規則——模式規則。這條規則更通用,因為您可以使用模式規則來定義更復雜的依賴關系規則。模式規則看起來非常類似於常規規則,但是在目標名稱前面有壹個%符號,它也可以用於定義目標和依賴文件之間的關系。例如,以下模式規則定義了如何將任何file.c文件轉換為file.o文件:
%.c:%。o
$(CC)$(CFLAGS)$(CPPFLAGS)-c-o $ @ $ & lt;
#示例#
下面會舉壹個更全面的例子來進壹步解釋makefile和make命令的執行,其中make命令不僅涉及C源文件還包括Yacc語法。這個例子選自“Unix
程序員手冊第7版,2A卷”第283-284頁
以下是描述文件的具體內容:
Make命令的描述文件
#發送至打印
P=und -3 | opr -r2
#目標文件所需的源文件
FILES = Makefile version . c defs main . c donamc . c misc . c file . c \
dosys.c gram.y lex.c gcos.c
#目標文件的定義
OBJECTS = ve sion . o main . o donamc . o misc . o file . o dosys . o gram . o
LIBES= -LS
LINT= lnit -p
CFLAGS= -O
制造:$(對象)
cc $(CFLAGS)$(OBJECTS)$(LIBES)-o make
尺寸制造
$(對象):定義
gram.o: lex.c
清理:
-rm *。o克. c
安裝:
@size make /usr/bin/make
cp制作/usr/bin/制作;rm品牌
#打印最近更改的文件
打印:$(文件)
pr $?| $P
觸摸打印
測試:
make-DP | grep-v TIME & gt;1zap
/usr/bin/make-DP | grep-v TIME & gt;2zap
diff 1zap 2zap
rm 1zap 2zap
lint:dosys . c donamc . c file . c main . c misc . c version . c gram . c
$(LINT)dosys . c donamc . c file . c main . c misc . c version . c \
gram.c
rm克. c
拱門:
ar uv /sys/source/s2/make.a $(文件)
通常在描述文件中,您應該定義要求輸出如上執行的命令。執行make命令後,輸出結果是:
$ make
版本
cc -c主
cc -c多納馬克
cc -c雜項
cc -c文件
劑量
yacc gram.y
mv y . tab . c g . c
克拉姆
cc version . o main . o donamc . o misc . o file . o dosys . o gram . o \
-LS -o品牌
13188+3348+3044 = 19580 b = 046174 b
最終的數字信息是執行“@size make”命令的輸出結果。之所以只有輸出結果而沒有對應的命令行,是因為“@size make”命令以“@”開頭,這個符號禁止打印其所在的命令行。
描述文件中的最後幾個命令行對於維護編譯信息非常有用。“打印”命令行的功能是在最後壹次執行“打印”命令後,打印出所有更改的文件名。領帶
系統使用壹個名為print的0字節文件來確定執行打印命令的具體時間,而宏$?指向那些在打印文件更改後被修改的文件的文件名。如果要指定打印命令執行後輸出結果將發送到指定文件,可以修改p:
制作印刷品。zap "
在Linux中,大部分軟件提供的是源代碼,而不是現成的可執行文件,這就需要用戶根據自己系統的實際情況和自己的需求對源程序進行配置和編譯,然後軟件才能使用。只有掌握了make工具,才能真正享受到Linux這個自由軟件世界帶來的無窮樂趣。
這個答案是計算機網絡分類專家李小重推薦的。