Makefile偽目標詳解
本節我們討論一個Makefile中的一個重要的特殊目標:偽目標。
偽目標是這樣一個目標:它不代表一個真正的檔名,在執行make時可以指定這個目標來執行其所在規則定義的命令,有時我們也可以將一個偽目標稱為標籤。使用偽目標有兩點原因:1. 避免在我們的Makefile中定義的只執行命令的的目標(此目標的目的為了執行執行一系列命令,而不需要建立這個目標)和工作目錄下的實際檔案出現名字衝突。2. 提高執行make時的效率,特別是對於一個大型的工程來說,編譯的效率也許你同樣關心。以下就這兩個問題我們進行分析討論:
1. 如果我們需要書寫這樣一個規則:規則所定義的命令不是去建立目標檔案,而是使用make指定具體的目標來執一些特定的命令。像下邊那樣:
clean:
rm *.o temp
規則中“rm”不是建立檔案“clean”的命令,只是刪除當前目錄下的所有.o檔案和temp檔案。在工作目錄下不存在“clean”這個檔案時,我們輸入“make clean”後,“rm *.o temp”總會被執行。這是我們的初衷。
但當前工作目錄下存在檔案“clean”時情況就不一樣了,在我們輸入“make clean”時。規則沒有依賴檔案,所以目標被認為是最新的而不去執行規則作定義的命令,命令“rm”將不會被執行。這並不是我們的初衷。為了避免這個問題,我們可以將目標“clean”明確的宣告為偽目標。將一個目標宣告為偽目標需要將它作為特殊目標.PHONY
.PHONY : clean
這樣目標“clean”就是一個偽目標,無論當前目錄下是否存在“clean”這個檔案。我們輸入“make clean”之後。“rm”命令都會被執行。而且,當一個目標被宣告為偽目標後,make在執行此規則時不會試圖去查詢隱含規則來建立這個目標。這樣也提高了make的執行效率,同時我們也不用擔心由於目標和檔名重名而使我們的期望失敗。在書寫偽目標規則時,首先需要宣告目標是一個偽目標,之後才是偽目標的規則定義。目標“clean”書寫格式應該如下:
.PHONY: clean
clean:
rm *.o temp
2. 偽目標的另外一使用場合在make
SUBDIRS = foo bar baz
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done
但這種實現方法存在以下幾個問題。1. 當子目錄執行make出現錯誤時,make不會退出。就是說,在對某一個目錄執行make失敗以後,會繼續對其他的目錄進行make。在最終執行失敗的情況下,我們很難根據錯誤的提示定位出具體是是那個目錄下的Makefile出現錯誤。這給問題定位造成了很大的困難。為了避免這樣的問題,我們可以在命令列部分加入錯誤的監測,在命令執行錯誤後make退出。不幸的是,如果在執行make時使用了“-k”選項,此方式將失效。2. 另外一個問題就是使用這種shell的迴圈方式時,沒有用到make對目錄的並行處理功能,因為規則的命令是一條完整的shell命令,不能被並行的執行。
我們可以通過偽目標方式來克服以上實現方式所存在的兩個問題。
SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C [email protected]
foo: baz
上邊的實現中使用了一個沒有命令列的規則“foo: baz”,用來限制子目錄的make順序。此規則的含義時在處理“foo”目錄之前,需要等待“baz”目錄處理完成。在書寫一個並行執行make的Makefile時,目錄的處理順序是需要特別注意的。
一般情況下,一個偽目標不作為一個另外一個目標檔案的依賴。這是因為當一個目標檔案的依賴包含偽目標時,每一次在執行這個規則時偽目標所定義的命令都會被執行(因為它是規則的依賴,重建規則目標檔案時需要首先重建它的依賴)。當偽目標沒有作為任何目標(此目標是一個可被建立或者已存在的檔案)的依賴時,我們只能通過make的命令列選項明確指定這個偽目標,來執行它所定義的命令。例如我們的“make clean”。
Makefile中,偽目標可以有自己的依賴。在一個目錄下如果需要建立多個可執行程式,我們可以將所有程式的重建規則在一個Makefile中描述。因為Makefile中第一個目標是“終極目標”,約定的做法是使用一個稱為“all”的偽目標來作為終極目標,它的依賴檔案就是那些需要建立的程式。下邊就是一個例子:
#sample Makefile
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2 : prog2.o
cc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
cc -o prog3 prog3.o sort.o utils.o
執行make時,目標“all”被作為終極目標。為了完成對它的更新,make會建立(不存在)或者重建(已存在)目標“all”的所有依賴檔案(prog1、prog2和prog3)。當需要單獨更新某一個程式時,我們可以通過make的命令列選項來明確指定需要重建的程式。(例如: “make prog1”)。當一個偽目標作為另外一個偽目標依賴時,make將其作為另外一個偽目標的子例程來處理(可以這樣理解:其作為另外一個偽目標的必須執行的部分,就行C語言中的函式呼叫一樣)。下邊的例子就是這種用法:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diff
“cleanobj”和“cleandiff”這兩個偽目標有點像“子程式”的意思(執行目標“clearall時會觸發它們所定義的命令被執行”)。我們可以輸入“make cleanall”和“make cleanobj”和“make cleandiff”命令來達到清除不同種類檔案的目的。例子首先通過特殊目標“.PHONY”聲明瞭多個偽目標,它們之間使用空各分割,之後才是各個偽目標的規則定義。
說明:
通常在清除檔案的偽目標所定義的命令中“rm”使用選項“–f”(--force)來防止在缺少刪除檔案時出錯並退出,使“make clean”過程失敗。也可以在“rm”之前加上“-”來防止“rm”錯誤退出,這種方式時make會提示錯誤資訊但不會退出。為了不看到這些討厭的資訊,需要使用上述的第一種方式。
另外make存在一個內嵌隱含變數“RM”,它被定義為:“RM = rm –f”。因此在書寫“clean”規則的命令列時可以使用變數“$(RM)”來代替“rm”,這樣可以免出現一些不必要的麻煩!這是我們推薦的用法。
Refer: http://www.cnblogs.com/hnrainll/archive/2011/04/12/2014082.html
相關推薦
Makefile偽目標詳解
本節我們討論一個Makefile中的一個重要的特殊目標:偽目標。 偽目標是這樣一個目標:它不代表一個真正的檔名,在執行make時可以指定這個目標來執行其所在規則定義的命令,有時我們也可以將一個偽目標稱為標籤。使用偽目標有兩點原因:1. 避免在我們的Makefile中定義的
Makefile偽目標
而是 一次 我們 避免 並行 重名 理解 目標 完整 本節我們討論一個Makefile中的一個重要的特殊目標:偽目標。 偽目標是這樣一個目標:它不代表一個真正的文件名,在執行make時可以指定這個目標來執行其所在規則定義的命令,有時我們也可以將一個偽目標稱為標簽。使用
自動生成Makefile的全過程詳解
change make auto osc .cn 轉換成 otto 創建 準備 一、簡介 Linux下的程序開發人員,一定都遇到過Makefile,用make命令來編譯自己寫的程序確實是很方便。一般情況下,大家都是手工寫一個簡單Makefile,如果要想寫出一個符合自由軟件
css中偽類/偽元素詳解
input 其他 中文 tro 網頁 單元 web link 語言 一、偽類和偽元素 偽類和偽元素都是用來修飾不在文檔樹中的部分,區別在於, 偽類用於當已有元素處於的某個狀態時,為其添加對應的樣式,這個狀態是根據用戶行為而動態變化的(如:hover/:active)。
Makefile概述及詳解
Makefile 值得一提的是,在Makefile中的命令,必須要以[Tab]鍵開始。 什麼是makefile?或許很多Winodws的程式設計師都不知道這個東西,因為那些Windows的IDE都為你做了這個工作,但我覺得要作一個好的和pr
CSS偽類偽元素詳解
CSS選擇器大致可以分成5類:基本選擇器,層次選擇器,屬性選擇器,偽類,偽元素。基本,層次,屬性選擇器比較容易理解,畢竟它們選擇的物件都屬於DOM中看得見摸得著的元素。但偽類和偽元素相對比較抽象,稍微有一點點理解上的難度。本篇就是我對偽類和偽元素的理解。 先介紹一下偽類和偽元素有什麼區別?其
makefile偽目標理解
makefile偽目標控制子makefile執行 下面的makefile耽誤了我半天時間,我要紀念下 程式碼塊 程式碼塊語法遵循標準markdown程式碼,例如: SUBDIRS =bin
Makefile 偽目標.PHONY
在接觸Makefile的時候,我們經常會看到.PHONY標記,它就是偽目標,所謂偽目標,就是指沒有真正的檔案和它對應,只是一個標識而已。make程式看到.PHONY後面的目標後就會去執行對應的命令。例如
MAKEFILE詳解 多目標 靜態模式 十三
六、多目標 Makefile的規則中的目標可以不止一個,其支援多目標,有可能我們的多個目標同時依賴於一個檔案,並且其生成的命令大體類似。於是我們就能把其合併起來。當然,多個目標的生成規則的執行命令是同一個,這可能會可我們帶來麻煩,不過好在我們的可以使用一個自動化變數“[email protected
makefile詳解 多行變數 環境變數 目標變數 模式變數 十九
六、多行變數 還有一種設定變數值的方法是使用define關鍵字。使用define關鍵字設定變數的值可以有換行,這有利於定義一系列的命令(前面我們講過“命令包”的技術就是利用這個關鍵字)。 define指示符後面跟的是變數的名字,而重起一行定義變數的值,定義是以endef關鍵字結束。其工作方式和“=”操作符
makefile學習之路——偽目標
偽目標 makefile 由於在makefile中,make在默認情況下將目標當作是一個文件來處理,所以這裏就會出現一個情況,如果makefile中的目標是實際已經存在的文件,那麽,我們在使用makefile的時候,就會報錯。為了避免這種情況的出現,就引入了偽目標的概念。 引
makefile詳解
makefile原文鏈接:https://blog.csdn.net/qq_38646470/article/details/79917494專欄鏈接:https://blog.csdn.net/column/details/20028.html 或許很多Wino
Faster R-CNN:詳解目標檢測的實現過程
最大的 中心 width 小數據 等等 eat tar 優先 博文 本文詳細解釋了 Faster R-CNN 的網絡架構和工作流,一步步帶領讀者理解目標檢測的工作原理,作者本人也提供了 Luminoth 實現,供大家參考。 Luminoth 實現:h
Hadoop偽分佈安裝詳解+MapReduce執行原理+基於MapReduce的KNN演算法實現
本篇部落格將圍繞Hadoop偽分佈安裝+MapReduce執行原理+基於MapReduce的KNN演算法實現這三個方面進行敘述。 (一)Hadoop偽分佈安裝 1、簡述Hadoop的安裝模式中–偽分佈模式與叢集模式的區別與聯絡. Hadoop的安裝方式有三種:本地模式,偽分佈模式
(二十二)訪問者模式詳解(偽動態雙分派)
作者:zuoxiaolong8810(左瀟龍),轉載請註明出處,特別說明:本博文來自博主原部落格,為保證新部落格中博文的完整性,特複製到此留存,如需轉載請註明新部落格地址即可。 本次LZ
Hadoop單機式偽分散式安裝詳解
Ubuntu、centos7、6叢集搭建:https://blog.csdn.net/qq_40938267/article/details/83476896 遇到的問題以及解決方法: 1.在./bin/hdfs namenode –format時 載入不出class 檢視配置的
Linux下多資料夾編寫Makefile詳解
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
基於Tensorflow的目標檢測(Detection)的程式碼案例詳解
這篇博文我主要闡述了基於Tensorflow的Faster RCNN在Windows上的一個Demo程式,其中,分為兩個部分,一個是訓練資料匯入部分,一個是網路架構部分開始。源程式git地址我會放在文章最後,下載後可以參考對應看一下。 一、程式執行環境說明 首先,我想闡述一堆巨坑,下面只要有
Sass中的巢狀---結合線上編譯詳解選擇器巢狀、屬性巢狀、偽類巢狀
推薦部落格:https://blog.hypers.io/2017/08/06/sass%20&%20compass%20%E6%95%99%E7%A8%8B%20--%20%E8%AF%AD%E6%B3%95%E7%AF%87(%E4%B8%80)/?utm_source=tuicool&