以前寫的makefile,有一些地方不夠人性化,標頭檔案或原始碼檔案比較多的情況,要手動輸入很多個地方。這次參考了一些資料,完善一下。
原來的做法:
# !!!===
inc1 = ./
inc2 = ./inc
inc3 =
incdirs := -i$(inc1) -i$(inc2)
# !!!===
# source file(s), including c file(s) or cpp file(s)
# you can also use $(wildcard *.c), etc.
src_dir = .
src_dir1 =
src_dir2 =
src_dir3 =
# ok for c/c++
src = $(wildcard $(src_dir)/*.c $(src_dir)/*.cpp)
src+=$(wildcard $(src_dir1)/*.c $(src_dir1)/*.cpp)
src+=$(wildcard $(src_dir2)/*.c $(src_dir2)/*.cpp)
src+=$(wildcard $(src_dir3)/*.c $(src_dir3)/*.cpp)
從上面內容看到,如果有多個標頭檔案、原始碼路徑的話,要分別新增2個地方。這樣工作量比較多。
無意間看到一篇文章:上面提到了用find命令查詢,比較好解決上述問題。
標頭檔案部分改為:
# !!!===
# include head file directory here
inc = ./inc
inc := $(shell find $(inc) -type d)
incdirs := $(addprefix -i, $(inc))
這樣,只需要在inc給定標頭檔案所在目錄即可,其它不需要修改了。使用find加上-type d表示將指定目錄下所有子目錄都作為頭檔案目錄。這樣有好有不好,如果目錄太多,又不是一定存在標頭檔案,則在編譯時會帶很多路徑。解決此問題也簡單,將所有標頭檔案放到inc目錄,該目錄也可以分不同子目錄存放標頭檔案,這是一種折中的方法,在實際中也這樣使用。
原始碼目錄改為:
src_dirs = .
srcs := $(shell find $(src_dirs) -name '*.cpp' -or -name '*.c')
這樣修改,可以搜尋當前目錄下所有子目錄的原始碼檔案,包括.c和.cpp檔案。
這種做法的好處是,不需要考慮太多的目錄層次,但是正因為如此,所有的目錄都會被搜尋到。
由前面引申出來的思考:如果不想搜尋所有目錄,那就要一一指定哪些目錄需要編譯了。那麼,相應的修改如下:
inc = ./inc ../3rdparty/zlib/inc # 一一指定哪些是真正的標頭檔案
incdirs := $(addprefix -i, $(inc))
src_dirs = . ./foo ./bar ./main # 一一指定哪些是真正要編譯的目錄
srcs := $(shell find $(src_dirs) -maxdepth 1 -name '*.cpp' -or -name '*.c') # 這裡使用-maxdepth 1只搜尋一層目錄
雖然本次只是修改了一點內容,但便捷性大大提高,而且,即使是多個目錄的工程,只要目錄設計合適,只需要乙個makefile即可完成編譯工作,無須額外的子makefile。以上涉及的目錄,僅做示例而已,具體根據實際情況修改。詳細參考提交記錄。
李遲 2018.7.1
cmake 和 makefile的模板
這篇主要是最近在用makefile和cmake。這玩意吧,就賊容易忘,我就默默寫一篇小短文記錄一下。就是放乙個模板,以後直接在模板上做改動。executable為目標的可執行檔名,可以根據具體的情況對其進行修改。executable test 修改隱含規則中巨集 cross compile usr ...
常用的C C 工程Makefile模板
在linux下做開發難免要接觸makefile,整個專案的構建都依賴於它。100個developer有100種makefile的寫法,在乙個較大的專案中,各種各樣的makefile無論在開發 後期維護還是整個系統的持續整合都是乙個負擔。有幸參與重構乙個遺留系統的makefile,以下是一些心得和乙個...
makefile的乙個模板
include i.include i usr local include libxml2 i usr local ssl include i usr local include target agent lib lstdc lrt lpthread lxml2 objs patsubst cpp,...