Shell 脚本中如何使用make命令
最近開發的項目中需要編寫Shell腳本對整個工程進行自動化編譯,即在Shell腳本中使用make命令來進行編譯,下面回顧一下Shell腳本中如何使用make命令)
? ? ? ? 在開發一個系統時,一般是將一個系統分成幾個模塊,這樣做提高了系統的可維護性,但由于各個模塊間不可避免存在關聯,所以當一個模塊改動后,其他模塊也許會有所更新,當然對小系統來說,手工編譯連接是沒問題,但是如果是一個大系統,存在很多個模塊,那么手工編譯的方法就不適用了。為此,在Linux系統中,專門提供了一個make命令來自動維護目標文件,與手工編譯和連接相比,make命令的優點在于他只更新修改過的文件(在Linux中,一個文件被創建或更新后有一個最后修改時間,make命令就是通過這個最后修改時間來判斷此文件是否被修改),而對沒修改的文件則置之不理,并且make命令不會漏掉一個需要更新的文件。
? ? ? ?文件和文件間或模塊或模塊間有可能存在倚賴關系,make命令也是依據這種依賴關系來進行維護的,所以我們有必要了解什么是依賴關系;make命令當然不會自己知道這些依賴關系,而需要程序員將這些依賴關系寫入一個叫makefile的文件中。
? ? ? ?下面是詳細解析:
一、Make命令
1、make命令基礎概念
?? ?Make這個詞,英語的意思是”制作”。Make命令直接用了這個意思,就是要做出某個文件。比如,要做出文件a.txt,就可以執行下面的命令。
? ? ? ?比如,假設文件a.txt 依賴于b.txt 和 c.txt ,是后面兩個文件連接(cat命令)的產物。那么,make 需要知道下面的規則。
[cpp]?view plaincopy
? ? ? ?像這樣的規則,都寫在一個叫做Makefile的文件中,Make命令依賴這個文件進行構建。Makefile文件也可以寫為makefile, 或者用命令行參數指定為其他文件名。
2、make命令使用方法
? ?Make命本身可帶有四種參數:標志、宏定義、描述文件名和目標文件名。其標準形式為:
Make [flags] [macro definitions] [targets]
Unix系統下標志位flags選項及其含義為:
?
-f file 指定file文件為描述文件,如果file參數為"-"符,那么描述文件指向標準輸入。如果沒有"-f"參數,則系統將默認當前目錄下名為makefile或者名為Makefile的文件為描述文件。在Linux中, GNU make 工具在當前工作目錄中按照GNUmakefile、makefile、Makefile的順序搜索 makefile文件。
-i 忽略命令執行返回的出錯信息。?
-s 沉默模式,在執行之前不輸出相應的命令行信息。?
-r 禁止使用build-in規則。?
-n 非執行模式,輸出所有執行命令,但并不執行。?
-t 更新目標文件。?
-q make操作將根據目標文件是否已經更新返回"0"或非"0"的狀態信息。?
-p 輸出所有宏定義和目標文件描述。?
-d Debug模式,輸出有關文件和檢測時間的詳細信息。
Linux下make標志位的常用選項與Unix系統中稍有不同,下面我們只列出了不同部分:
-c dir 在讀取 makefile 之前改變到指定的目錄dir。?
-I dir 當包含其他 makefile文件時,利用該選項指定搜索目錄。?
-h help文擋,顯示所有的make選項。?
-w 在處理 makefile 之前和之后,都顯示工作目錄。
通過命令行參數中的target ,可指定make要編譯的目標,并且允許同時定義編譯多個目標,操作時按照從左向右的順序依次編譯target選項中指定的目標文件。如果命令行中沒有指定目標,則系統默認target指向描述文件中第一個目標文件。
通常,makefile 中還定義有 clean 目標,可用來清除編譯過程中的中間文件,例如:
clean:?
rm -f *.o
運行 make clean 時,將執行 rm -f *.o 命令,最終刪除所有編譯過程中產生的所有中間文件。
隱含規則
在make 工具中包含有一些內置的或隱含的規則,這些規則定義了如何從不同的依賴文件建立特定類型的目標。Unix系統通常支持一種基于文件擴展名即文件名后綴的隱含規則。這種后綴規則定義了如何將一個具有特定文件名后綴的文件(例如.c文件),轉換成為具有另一種文件名后綴的文件(例如.o文件):
?
.c:.o?
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<?
系統中默認的常用文件擴展名及其含義為:?
.o 目標文件?
.c C源文件?
.f FORTRAN源文件?
.s 匯編源文件?
.y Yacc-C源語法?
.l Lex源語法
在早期的Unix系統系統中還支持Yacc-C源語法和Lex源語法。在編譯過程中,系統會首先在makefile文件中尋找與目標文件相關的.C文件,如果還有與之相依賴的.y和.l文件,則首先將其轉換為.c文件后再編譯生成相應的.o文件;如果沒有與目標相關的.c文件而只有相關的.y文件,則系統將直接編譯.y文件。
而GNU make 除了支持后綴規則外還支持另一種類型的隱含規則--模式規則。這種規則更加通用,因為可以利用模式規則定義更加復雜的依賴性規則。模式規則看起來非常類似于正則規則,但在目標名稱的前面多了一個 % 號,同時可用來定義目標和依賴文件之間的關系,例如下面的模式規則定義了如何將任意一個 file.c 文件轉換為 file.o 文件:
%.c:%.o?
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<?
二、Makefile文件
1、概述
? ? ?Makefile文件由一系列規則(rules)構成。每條規則的形式如下。
<target> : <prerequisites> [tab] <commands>
? ? ?上面第一行冒號前面的部分,叫做”目標”(target),冒號后面的部分叫做”前置條件”(prerequisites);第二行必須由一個tab鍵起首,后面跟著”命令”(commands)。
? ? ?“目標”是必需的,不可省略;”前置條件”和”命令”都是可選的,但是兩者之中必須至少存在一個。
? ? ? 每條規則就明確兩件事:構建目標的前置條件是什么,以及如何構建。
2、 目標(target)
? ? ??一個目標(target)就構成一條規則。目標通常是文件名,指明Make命令所要構建的對象,比如 a.txt 。目標可以是一個文件名,也可以是多個文件名,之間用空格分隔
? ? ? 除了文件名,目標還可以是某個操作的名字,這稱為”偽目標”(phony target)。
[cpp]?view plaincopy
? ? 上面代碼的目標是clean,它不是文件名,而是一個操作的名字,屬于”偽目標 “,作用是刪除對象文件。
? ? 但是,如果當前目錄中,正好有一個文件叫做clean,那么這個命令不會執行。因為Make發現clean文件已經存在,就認為沒有必要重新構建了,就不會執行指定的rm命令
? ? 為了避免這種情況,可以明確聲明clean是”偽目標”,寫法如下。
[cpp]?view plaincopy
? ? 如果Make命令運行時沒有指定目標,默認會執行Makefile文件的第一個目標。
? ? $ make
? ? 上面代碼執行Makefile文件的第一個目標。
例:執行多個目標
[cpp]?view plaincopy
三、shell 腳本各種執行方式(source ./*.sh, . ./*.sh, ./*.sh)的區別
結論一: ./*.sh的執行方式等價于sh ./*.sh或者bash ./*.sh,此三種執行腳本的方式都是重新啟動一個子shell,在子shell中執行此腳本。
結論二: .source ./*.sh和 . ./*.sh的執行方式是等價的,即兩種執行方式都是在當前shell進程中執行此腳本,而不是重新啟動一個shell 而在子shell進程中執行此腳本。
驗證依據:沒有被export導出的變量(即非環境變量)是不能被子shell繼承的
驗證結果:
[cpp]?view plaincopy總結
以上是生活随笔為你收集整理的Shell 脚本中如何使用make命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSHOP后台设置SMTP发邮件提示 E
- 下一篇: H5页面在自己APP中图标显示正常,接入