開始我會插播一段我如何學習makefile的廢話,如果不想聽的話,請直接跳到我的makefile教程。
首先得先說明學習makefile真是一個痛苦的過程,尤其是用乾巴巴的看書來學習的過程,簡直可以用如坐鍼氈來形容了……不過作為一個想成為真正程式設計師的人這又算得了什麼呢?為了不被人詬病程式設計只會用IDE,你得硬著頭皮來學習這個讓人痛苦的東西,好在有一句話,痛苦是進步的標識,這至少說明了你在進步,也挺好的。
通過這幾天的痛苦學習,我覺得學習makefile得分這麼幾個步驟:
1、熟悉大概的makefile語句,寫幾個簡單的makefile–只需要很簡單的,能編譯出幾個檔案的demo程式即可,可以嚴重提高自信心;—done
2、讀這本書《GNU Make專案管理》的1、2、3、6、8章;–done
3、然後著手寫一個較大型系統的makefile;–done
4、goto 2;–todo
5、在平時的專案中提醒自己用makefile來管理,不斷的查詢遇到的新知識點,記錄,回顧;–todo
我得說,走完第2步給我的感覺不是我學會了makefile,實則是我依然寫不了太大的makefile,只能說我再看到大型的makefile不再害怕了,我自信我能看得懂這個makefile所要表現的編譯系統。這也算是對makefile的入門吧。
—-—————————–—-———————————-
當我在著手完成上面的第3步的時候,真的還是什麼都不會,最痛苦的是不知道怎麼下手,苦於沒有找到錯綜複雜的困境中的“繩頭”,我當時能想到的一件事就是google,我用了這樣的關鍵字:the best way of wrighting makefile,然後我得到了這個地址。這裡面一個很重要的資訊就是避免使用傳統上的巢狀makefile,具體用什麼方式來構建一個大的工程呢?我有找到了這篇論文《Recursive make considered harmful》,其中講述的很清楚,我查了下被引用的次數還是不少的,關於這篇文章,請參考這裡,不再贅述。
當我讀完這篇論文之後,我開始重新思考我該怎樣完成上面的步驟3,然後慢慢的嘗試完成其中一個靜態庫的編譯,最後寫成這個摸樣:
# include some common definitions of make
include common.mk MODULES := asyn_frame rsa platform torrent_parser utility CFLAGS += $(patsubst %,-I%,$(MODULES))
CFLAGS += -I. -I./include
CFLAGS += -DLINUX -DNDEBUG
CFLAGS += -O2 SRC := $(wildcard *.c) # It's used for debug makefile.
MODULES_MK := $(patsubst %,src/%/module.mk,$(MODULES))
include $(MODULES_MK) OBJ := $(patsubst %.c,%.o,$(SRC)) LIB := libcommon.a $(LIB) : $(OBJ)
@echo 'enter produce the lib files*************'
$(AR) $(LIB) $(OBJ)
$(RM) $(OBJ)
@echo 'leave produce the lib files*************' all : $(LIB) %d : %c
@set -e; $(RM) $@; $(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; $(RM) $@.$$$$
-include $(SRC:.c=.d) .PHONY : clean all test :
@echo 'make test enter'
@echo 'the src of asyn_frame:'
@echo $(SRC)
@echo 'the obj of asyn_frame:'
@echo $(OBJ)
@echo 'the mk file of common'
@echo $(MODULES)
@echo $(MODULES_MK)
@echo $(CFLAGS)
@echo 'make test leaving' clean :
$(RM) $(LIB) $(OBJ)
find . -name "*.d" | xargs rm -f
看起來不算複雜,但是從無到有的過程還是比較曲折的,可以看到這裡面有一個偽目標test,這是我用來測試make中的基本變數的,不斷地嘗試終於出來這個還算能用的東西。所以總算是完成了步驟3,當然是在預計的時間內,心中很是舒服,至少可以說我的知識庫中又多了一項武器。
走完第3步之後我沒有再繼續走第4步,因為我覺得目前看來我還沒有到需要非常熟悉makefile的地步,學習它的初衷也是為了能在日常的工作實踐中幫助自己做實際的專案,如果過於沉浸在理論上就與我的初衷相違背了,非我所欲也,更何況目前的專案大都是跨平臺的,所以CMake才是我的菜。此刻我選擇“淺嘗輒止”,但是我還是回顧了一遍makefile的基礎知識,我的參考資料是網上看的比較多的陳皓的《跟我一起寫makefile》,總共14章,我覺得這個系列也不是特別好,很多東西都是GNU manual的摘錄,當然也還有作者自己的理解,不過作為參考幫助回顧一些常見的知識點還是很有幫助的。這也就是我為啥沒有找那本大而全的教科書,而是看了這種網上的精簡tutorial。
前面基本上是我學習makefile的簡單歷程,耗費的時間大約在3周左右,畢竟工作了、有小孩了,真沒有太多自己的時間了,不過有了這件事讓我得到一個很好的習慣就是每天早上能在5點半左右起來,看兩個小時的書再去上班,這真是無心插柳的結果,因為晚上實在沒有時間做這些事。。。前面雖然有很多的廢話,但是我覺得學習知識不是最關鍵的,瞭解怎樣獲取知識才是重要的而且通常是最難的,我試圖用比較簡單的語言來描述這個獲取知識的思考過程,但細細讀來還是覺得囉嗦滿地。。嘿嘿,就這樣吧,反正就是這麼一回事,我也不想做什麼事後諸葛亮。
下面我會轉入正文,寫一個我自己的makefile教程:
目錄:
1、構建多級目錄結構的makefile最佳實踐 — The Best Way
2、一個真實專案的makefile及其解釋
3、makefile最常用的知識點整理
4、參考資料
具體的內容請移步這裡《我的makefile教程》。