Makefile自動依賴寫法

從開始學習到瞭解到makefile自動依賴到目前爲止總算是掌握了makefile的自動依賴寫法

因爲接觸的項目代碼分佈的問題源文件和頭文件不在同一個目錄下,,網上很多makefile自動依賴的方案不能直接拿來用.所以是在其基礎上進行的改編

總體來說 是這麼個過程 

先決條件 工程目錄結構爲 頂層中放置

1 Makefile 

2 src目錄放置源文件 

3 inc目錄 

4 可能有lib目錄  

生成的程序在頂層目錄中

第一步 寫好你的環境變量 一般設置如下參數即可

CC=gcc
CFLAGS=-g -rdynamic -W -Wall
SRC=src
INC=-I. -I./inc
LIB=lib/xxxx.a   #如果有
TARGET=demo

第二步 獲取所有參與編譯的源文件 

在這步中我所使用的是makefile提供的函數 

SOURCES = $(wildcard src/*.cpp)
OBJ=$(patsubst %.cpp, %.o,$(SOURCES))
這樣在SOURCES中獲取到的是所有參加編譯的cpp文件 但是如果有多個目錄放置的話 可以使用追加方式添加其他的目錄下的源文件,最好在做完這一步之後進行驗證

兩個函數的用途分別是  獲取匹配的文件列表  和對匹配的字符串進行替換 將.cpp替換成.o,具體的詳細內容可以百度,不贅述

第三步 寫下如下語句

ALL: $(TARGET)
$(TARGET):$(OBJ)
	$(CC) $(CFLAGS) -o $(TARGET) $(OBJ) $(LIB) 

很明顯是申明要生成的文件 爲TARGET也就是demo

第四步 設置自動依賴關係

%d:%cpp
	@$(CC) -MM $(CFLAGS) $< $(INC) > [email protected];
	@sed -i 's,\($(*F)\)o[ :]*,$(*D)/\1o: ,g'  [email protected] ;
	@sed 's,\($*\)o[ :]*,\1o $@ : ,g' < [email protected] > $@;
	@echo "\t$(CC) -c -o $*o $< $(INC)" >>$@;
	@$(RM) [email protected]
-include $(patsubst %.cpp, %.d,$(SOURCES))
這個地方有幾個位置需要注意 第一點也就是最重要的一點 

就是%d:%cpp  是沒有.

%d:%cpp  是沒有.

%d:%cpp  是沒有.

重要的事情說三遍

當然如果要加點的話可是可行的,但是需要對整個結構進行一些變形,在這裏就不展開了

解釋一下上面語句發生的事情

@$(CC) -MM $(CFLAGS) $< $(INC) > [email protected];
這句是非常通用的獲取依賴頭文件的方法,不過在最後的寫入文件裏面我沒有用$$$$作爲進程號設置文件名,我覺得這樣比較麻煩還需要\來支持寫在一行,直接指定一個不會重複的就可以了

@sed -i 's,\($(*F)\)o[ :]*,$(*D)/\1o: ,g'  [email protected] ;
這一句也是十分常見 第一句的結果爲 a.o: src/a.cpp inc/a.h 這句話的意思爲將其替換成  src/a.o: src/a.cpp inc/a.h 

這個替換對下面的有關鍵性幫助 ,因爲OBJ裏面存的變量都是形如src/a.o的 與這個相對應起來

@sed 's,\($*\)o[ :]*,\1o $@ : ,g' < [email protected] > $@;
這一句不展開講,也很通用 將  src/a.o: src/a.cpp inc/a.h 替換爲   src/a.o src/a.d: src/a.cpp inc/a.h 

@echo "\t$(CC) -c -o $*o $< $(INC)" >>$@;

這一句是分目錄src和inc編譯的關鍵,沒有這一句編譯將不能正常進行.這是在src/a.d中手動添加inc目錄進編譯選項中,沒有這個 將在編譯的時候報找不到頭文件

	@$(RM) [email protected]
-include $(patsubst %.cpp, %.d,$(SOURCES))
這兩句都不說了  一個是刪除,另外一個是包含src/a.d的makefile規則的文件

到這裏我們的makefile自動依賴就完成了,可以作用於多個目錄,有着比較良好的通用性,可以試試

當然少不了clean 這個就自己寫吧



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章