專案實用makefile

2021-06-28 02:59:33 字數 4287 閱讀 6963

本文**:

中,已經說明了單個makefile管理層次目錄的侷限性。本文,主要總結一下專案中的一種實用makefile樹寫法,為10來個人協作的中小型專案makefile編寫,提供參考。

1. 需求

從實用角度,makefile樹應該達到以下需求:

1)自動加入編譯系統。新增目錄、檔案後,能夠自動新增(理想),或只需少許修改,就能新增到整個專案編譯中。

2)可讀性好,易於新增。新增目錄、檔案,linux新人能自己看懂新增(理想),或只需口頭10s描述就能很好完成。

3)模組化。新增目錄、檔案後的makefile,和其他目錄完全沒有關係(理想),或只需與最鄰近的前、後有關係。

2. 實現

2.1 自動加入編譯系統

使用makefile遞迴執行,能夠解決此問題。以下指令碼,能夠執行subdirs指定的子目錄內的makefile。

[plain]view plain

copy

makefile。  

subdirs = modual-a modual-b modual-c  

.phony: subdirs $(subdirs)  

subdirs: $(subdirs)  

$(subdirs):  

$(make) -c $@  

說明:1)變數subdirs,指定當前目錄下,要遞迴編譯的子目錄。

2).phony及subdirs目標結構,能保證遞迴到子目錄中。

2.2 可讀性好,易於新增;模組化

使用makefile的變數定義,其位置前後不敏感特性可以做到。示例指令碼如下:

[plain]view plain

copy

subdirs = modual-a modual-b modual-c  

objects = x.o y.o z.o  

all:subdirs $  

clean:cleansubdirs  

rm $  

說明:1)變數objects,指定當前目錄的目標檔案。新增乙個檔案z.cpp,在變數objects中,增加z.o即可。

2)新增乙個目錄dir-c,在變數subdirs中,增加dir-c。然後參考本目錄中的makfile,在dir-c中,建立乙個類似makfile即可。

2.3 減少重複指令碼

實現中,將makefile中的共用變數,轉移到檔案中,使用include包含,能夠達到函式效果,減少重複指令碼,容易改變。

3. 例項):

[plain]view plain

copy

project-test  

+-- makeconfig  

|     +-- make.global  

+-- src  

|     +-- module-a  

|     |     +-- test.cpp  

|     |     +-- makefile  

|     +-- module-b  

|     |     +-- test.cpp  

|     |     +-- makefile  

|     +-- main.cpp  

|     +-- makefile  

+-- makefile  

說明:1)project-test/makeconfig/make.global,要包含的makefile共用變數。

2)project-test/makefile,頂層makefile,指定可執行目標,及原始碼目錄。

3)project-test/src/makefile,子目錄的makeflile。目錄module-a、module-b的類似,每個目錄乙個。

3.1 project-test/makeconfig/make.global

如下所示:

[plain]view plain

copy

# compile macro  

cc      = g++  

cflags      = -o2 -wall  

ldflags = -lm   

includes    = -i/usr/local/include  

# recursive make  

.phony: subdirs $ cleansubdirs  

subdirs: $  

$:  

$ -c $@ all  

# recursive make clean  

cleansubdirs:  

@for dir in $; do \  

$ -c $$dir clean; \  

done  

# dependence  

%.o: %.cpp  

$ $ $ -c $< -o $@  

%.o: %.cc  

$ $ $ -c $< -o $@    

說明:1)包含4個區域,共用變數,遞迴make,遞迴makeclean,依賴關係。

2)遞迴makeclean,使用了不列印的shell語法。原因是,如果和遞迴一樣寫,會造成目標過載警告。

3.2 project-test/makefile

如下所示: 

[plain]view plain

copy

# target, subdir, objects in current dir  

target      = test  

subdirs = src  

objects =   

all:subdirs $  

$ -o $ $$(find ./$ -name '*.o') $ $  

clean:cleansubdirs  

rm -f $ $  

# path of "make global scripts"  

# note, use absolute path. export once, use in all subdirs  

export projectpath=$  

export makeinclude=$/makeconfig/make.global  

# include "make global scripts"  

include $  

說明:1)使用shell語法,搜尋出指定目錄的所有.o,鏈結為執行目標檔案。

2)使用export,指定專案絕對路徑,指定共用變數,包含所有目錄共用的makefile變數。

3)每個目標使用乙個頂層的makefile,來執行make和makeclean的遞迴入口,共用makefile。

3.3 project-test/src/makefile

如下所示:

[plain]view plain

copy

# subdir and objects in current dir  

subdirs = module-a module-b  

objects = main.o  

all:subdirs $  

clean:cleansubdirs  

rm -f $  

include $  

說明:1)增加目錄,只用修改子目錄變數subdirs;增加檔案,修改當前目標檔案變數objects。

2)不同目錄下,原始碼相同名字,但類、函式不相同,可以正常編譯。 

4. 專業makefile樹

以上,只是乙個專案最最普通的makefile樹。乙個實現檔案乙個.o檔案,不考慮庫生成,不考慮功能配置項,不考慮平台相容性。

一些開源專案,考慮了各種平台相容性,及功能特性,通常使用了autoconf和automake,自動生成特殊標頭檔案和巨集定義,來達到效果。使用以下3條命令,向使用者提供配置項設定,編譯,庫、標頭檔案、或目標檔案安裝路徑。在複雜相容專案中,非常實用。

./configure

make

make install

還在繼續學習中。

參考資料:

1. gnu make manual:

2. 同事j的makefile樹。

專案實用makefile

中,已經說明了單個makefile管理層次目錄的侷限性。本文,主要總結一下專案中的一種實用makefile樹寫法,為10來個人協作的中小型專案makefile編寫,提供參考。1.需求 從實用角度,makefile樹應該達到以下需求 1 自動加入編譯系統。新增目錄 檔案後,能夠自動新增 理想 或只需少...

專案實用makefile

中,已經說明了單個makefile管理層次目錄的侷限性。本文,主要總結一下專案中的一種實用makefile樹寫法,為10來個人協作的中小型專案makefile編寫,提供參考。1.需求 從實用角度,makefile樹應該達到以下需求 1 自動加入編譯系統。新增目錄 檔案後,能夠自動新增 理想 或只需少...

c 手寫Makefile 簡單實用的方法

在makefile規則中,萬用字元會被自動展開。但在變數的定義和函式引用時 萬用字元將失效。這種情況下如果需要萬用字元有效,就需要使用函式 wildcard 使用wildcard可以很好的獲取指定路徑下的所有.cpp檔案。比如src wildcard cc 可以獲取當前路徑下所有的.cc檔案 獲取到...