makefile的寫法問題 - Linux

Delia avatar
By Delia
at 2013-08-23T01:54

Table of Contents

※ 引述《Zoxge (Zoxge)》之銘言:
: 如果有很多個.cpp檔
: 就必須要有每個.cpp對應的target
: 但問題來了,當.cpp檔有幾百幾千個,又想要能自行判斷每個檔案是否被改過
: 這樣寫makefile不就xxx.o這樣的target也得要寫幾百幾千個 = =
: 請問有比較輕鬆的寫法嗎?
: 謝謝大家

給你我的 makefile 架構原形範例,
拿去對照查書理解一下內容,也許你會找到比我更好的寫法。

使用方法是,將你的 .cpp 檔案列表,照這個格式放進原始碼串列中,
如果 .cpp 有引入 .h 檔案,這個 makefile 也會一併幫你檢查 .h。

# 檔案開始

# .cpp 原始碼檔案名稱串列
SOURCE_CPP_FILES =\
./Tools/tools.cpp\
./Modules/modules.cpp\
./main.cpp

# .cpp 目的碼檔案名稱串列
OUTPUT_OBJECT_OF_CPP_FILES = $(SOURCE_CPP_FILES:.cpp=.o)

# .cpp 相依性規則輸出檔案名稱串列
OUTPUT_DEPENDENCY_RULE_OF_CPP_FILES = $(SOURCE_CPP_FILES:.cpp=.dep)

# 總輸出目的碼資源檔案名稱串列
ALL_OBJECT_FILES = $(OUTPUT_OBJECT_OF_CPP_FILES)

# ---------- 目標檔案巨集定義 ----------
# 目標檔檔案名稱
ALL_TARGET = ./MyTarget

# ---------- 主要 make 規則 ----------
all: $(ALL_TARGET)

# ---------- 目的碼檔案 make 規則 ----------
objects: $(ALL_OBJECT_FILES)

# ---------- 目的碼檔案以及目標檔案 clean 規則 ----------
clean: cleantarget cleanobjects cleandep

# ---------- 目標檔案 clean 規則 ----------
cleantarget:
rm -f $(ALL_TARGET)

# ---------- 目的碼檔案 clean 規則 ----------
cleanobjects:
rm -f $(ALL_OBJECT_FILES)

# ---------- 相依性規則檔案 clean 規則 ----------
cleandep:
rm -f $(OUTPUT_DEPENDENCY_RULE_OF_CPP_FILES)

# ---------- 連結目的碼檔案產生目標 ----------
$(ALL_TARGET): $(ALL_OBJECT_FILES)
g++ -o $@ $(ALL_OBJECT_FILES)

# ---------- .cpp 原始碼檔案相依性規則之建造規則 ----------
%.dep: %.cpp
g++ -MM $< -MT $*.o > $@

# ---------- 編譯 .cpp 原始碼檔案產生目的碼檔 ----------
%.o: %.cpp
g++ -c -o $@ $<

# ---------- 載入建造好的相依性規則 ----------
-include $(OUTPUT_DEPENDENCY_RULE_OF_CPP_FILES)

# 檔案結束

沒錯,很空洞,這只是個架構,將你自己相關的編譯參數,代入修改一下吧。
重點是你一定要去好好理解一下使用萬用字元與隱含目標的好處。

當然,如果真的原始碼列表真的數量驚人,那就得靠外部方式處理,這再舉個例子,
去改寫一下 makefile,將開頭的 SOURCE_CPP_FILES 巨集定義清除,換成:

-include MySource.lst

然後,下指令:

echo "SOURCE_CPP_FILES =\\" > MySource.lst;\
find ./ -name "*.cpp" | awk '{ print $1"\\" }' >> MySource.lst

(指令只是拋磚引玉,列表最後一個檔案名稱結尾會多個 \ 符號,
留給你自己研究怎樣方便清除嘍)



--
Tags: Linux

All Comments

Aaliyah avatar
By Aaliyah
at 2013-08-25T22:10
感謝您
照您的模板去做就成功了
但請問 %.dep: %.cpp 這一項是做什麼用呢?
Yedda avatar
By Yedda
at 2013-08-29T14:20
另外,這樣的寫法不會檢查.h檔是否被改過,請問要怎麼做呢?
Todd Johnson avatar
By Todd Johnson
at 2013-09-02T14:58
發現make clean做第二次,%.dep: %.cpp也會再跑一次 好怪@@
Frederica avatar
By Frederica
at 2013-09-05T02:34
是因為 -include $(OUTPUT_DEPENDENCY_RULE_OF_CPP_FILES)的
Charlie avatar
By Charlie
at 2013-09-05T07:13
關係,但不include這個好像也沒關係耶?
Edith avatar
By Edith
at 2013-09-10T02:28
如果確定資料夾底下所有檔案都要編,也可用wildcard吧

關於SAMBA速度的問題

Odelette avatar
By Odelette
at 2013-08-22T22:08
家裡設置了一台安裝ubuntu的電腦,以samba在區網分享資料夾 當使用windows8從ubuntu server抓檔案的時候,速度大約可以跑到90 mb/s 但是使用ubuntu client 從ubuntu server抓檔案時,速度卻掉到3x mb/s 在ubuntu下用軟體測試區網頻寬,clien ...

系統備份及使用serial登入

Hardy avatar
By Hardy
at 2013-08-22T19:38
大家好,我的作業系統是 Slitaz 1.0 今天嘗試了tar備份、還原, 備份的時候沒什麼問題,但還原的時候無法直接把tar解壓縮到/底下。 於是我用光碟開機,將硬碟掛載到/mnt,然後再解壓縮tar到/mnt。 這樣還原的方式是不是太麻煩了? 第二個問題是:為了做 RS232 登入介面,必須 ...

能否nohup的程式重新顯示在terminal上

Ina avatar
By Ina
at 2013-08-22T16:12
各位好 我的程式需要在伺服器上一直運作 不中斷 所以我用nohup執行我的程式 但是我又想定期觀看印在螢幕上的即時訊息 看看是否有錯誤 nohup執行的程式會把輸出寫成nohup.out檔案 但是我測試後 他寫入nohup.out的不是and#34;即時and#34;的 而是buffer滿了才會寫進去 而 ...

運行windows硬體

Hedy avatar
By Hedy
at 2013-08-22T13:40
想要運行兩個硬體(PG和LA), 請參考以下網頁 (http://www.acute.com.tw/big5/product/product_pg2000.php#pkpg2000) (http://www.acute.com.tw/big5/product/product_la2000p.php#tl200 ...

ubuntu12.04無法進入圖形介面

Joseph avatar
By Joseph
at 2013-08-22T10:59
剛剛在軟體中心移除掉一些沒在用的網際網路相關的軟體,移除到一半筆電突然跳出黑屏 有一些error但我沒注意到是什麼,直覺就給他按ctrl+alt+del重新開機(囧) 結果開機後就只會停在圖形介面正在loading的畫面,連登入方塊都跑不出來 試過tty1~6都還可以正常運作,不過有亂碼 查過一些網路資料沒 ...