軟體工程通用makefile寫法學習總結
工程通用makefile簡單實現
最近學習了一下makefile,總結了一些經驗,自己試著寫了一套簡單通用的軟體工程makefile,總結下來以後可能會用到。
我的工程目錄是這樣的結構:
頂層目錄是app/,app/include/存放公共的標頭檔案,app/lib/存放公共的.a,app/obj/存放下層模組編譯出的.a。
app層下面有三個模組分別是init,mod1,mod2。各模組編譯出的.o放在obj下面,然後連結成.a檔案放到上一級目錄的obj下面。
app層通過連結lib和obj下面所有的.a來生成可執行檔案。
模組目錄下面的makefile:
DIR_INC = ./inc ../mod1/inc ../mod2/inc
DIR_SRC = ./src
DIR_OBJ = ./obj
DIR_BIN = ../obj
TARGET = $(DIR_BIN)/libinit.a
INCLUDE += $(DIR_INC)
DEFINES +=
CC ?= gcc
CFLAGS ?= -Wall
AR ?= ar
ARFLAG ?= -cr
SRC = $(wildcard ${DIR_SRC}/*.c)
OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC}))
all : $(TARGET)
$(TARGET):$(OBJ)
$(AR) $(ARFLAG) [email protected] $(OBJ)
$(DIR_OBJ)/%.o:$(DIR_SRC)/%.c
$(CC) $(CFLAGS) $(addprefix -I, $(INCLUDE)) $(addprefix -D, $(DEFINES)) -c $< -o [email protected]
.PHONY : clean
clean :
rm -rf $(DIR_OBJ)/*.o
app目錄下面的makefile:
執行結果如下,達到了預期效果。DIR_APP = $(shell pwd) DIR_MOD = ./mod1 ./mod2 ./init DIR_OBJ = ./obj DIR_BIN = ./bin DIR_LIB = ./lib TARGET = $(DIR_BIN)/app1 export INCLUDE = $(DIR_APP)/include export CC ?= gcc export CFLAGS ?= -Wall -g export DEFINES ?= _DEBUG_ all : @for subdir in $(DIR_MOD); \ do $(MAKE) -C $$subdir all || exit 1; done $(CC) -o $(TARGET) -Wl,--start-group $(DIR_OBJ)/*.a $(DIR_LIB)/*.a -Wl,--end-group .PHONY : clean clean : @for subdir in $(DIR_MOD); \ do $(MAKE) -C $$subdir clean || exit 1; done rm -rf $(DIR_BIN)/* $(DIR_OBJ)/*
make all
make clean
需要注意的事項:
1.模組目錄下面的DIR_INC需要手工指定需要包含的標頭檔案路徑。
2.模組目錄下面的TARGET指定為需要輸出的.a,設計上是每個模組單獨生成一個.a。
3.原本想要實現的效果是,在每個模組目錄下面單獨執行makefile,可以生成.a,無需依賴上層,這樣就需要.c中包含標頭檔案時指定相對路徑,或者DIR_INC指定清楚需要的標頭檔案路徑。
4.模組下面的makefile,用了一些?=定義的變數,表示如果上層沒有傳遞該變數下來,則使用本定義來執行。這樣可以減少對上層makefile的依賴。
遇到的幾個問題:
1.模組層makefile編譯時,提示找不到標頭檔案:
原因是:定義標頭檔案的變數有很多項時,需要每一項都指定-I引數,需要使用加頭函式$(addprefix -I, $(INCLUDE)),這樣編譯時每一項都會加-I引數。巨集定義同理,都要加-D。
2.在app層編譯可執行程式時,連結所有.a,提示函式未定義:
原因是:連結器在連結.a時,由於連結的順序問題,導致有些.a中的函式定義找不到。此時需要使用-Wl,--start-group *.a -Wl,--end-group,意思是連結時,在中間包含的所有.a中查詢符號定義,直到找到為止。
可以優化的地方:
1.不知道這樣可以不可以,在app層makefile中,指定INCLUDE=$(shell find ./ -name inc),這樣上層就可以把所有標頭檔案路徑傳給模組層使用,模組層無需再手工修改需要包含的路徑了。
2.可以在app層上再指定一層project層,大型工程可能會編譯出很多可執行程式,可以集中控制app層編譯。
3.編譯選項之類的,可以在app層指定一個compilier.mk檔案,專門定義清楚。
可以使用的除錯手段:
1.nm filename
檢視檔案的函式符號表。U表示不是本檔案定義的函式。一般是呼叫的其他檔案的函式。T表示本檔案定義的函式。
[[email protected] obj]$ nm libinit.a main.o:U App1Lib
U App1Mod1
U App1Mod2
0000000000000000 T main
U puts
2.readelf -a filename
解析檔案的符號表。
3.ar -t
檢視.a連結了哪些檔案。
常用makefile命令
1.makefile中的幾個符號含義: [email protected] 表示目標檔案 $^ 表示所有依賴的檔案 $< 表示第一個依賴的檔案 $? 表示比目標還要新的所有依賴檔案 := 賦值時只能定義前面已經定義好的變數 ?= 如果前面沒有定義該變數,則賦當前值,否則使用前面定義的值 += 給變數追加值 2.makefile函式含義: wildcard:展開萬用字元。$(wildcard *.c) => 目錄下的所有.c檔案。 patsubst:模式字串替換。$(patsubst %.c,%.o,a.c b.c) => 將a.c b.c替換為a.o b.o。 addprefix:加頭。$(addprefix -I, a.h b.h) => 結果為-Ia.h -Ib.c notdir:去檔名。$(notdir xxx/a.c yyy/zzz/b.c) => 結果為a.c b.c參考:
http://blog.csdn.net/haoel/article/details/2886/
http://www.cnblogs.com/Anker/p/3242207.html
相關推薦
軟體工程通用makefile寫法學習總結
工程通用makefile簡單實現 最近學習了一下makefile,總結了一些經驗,自己試著寫了一套簡單通用的軟體工程makefile,總結下來以後可能會用到。 我的工程目錄是這樣的結構: 頂層目錄是app/,app/include/存放公共的標頭檔案,app/lib/
軟體工程第一個衝刺週期總結
此次任務我們進行了明確的分工,小組三人每天進行了各自的任務認領,王棟主要負責的是選單欄的編譯,陳浩東主要負責的是狀態列按鈕的編寫,楊洋主要負責的是整體介面編譯,這是成員各自進行的任務認領,不是任務分配。在這個衝刺週期中,我們按照之前的Sprint會議計劃表進行了規劃,每天完成每天的任務,並更新任務看板和燃
《逆向工程核心原理》學習總結(四)
介紹 PE檔案是windows作業系統的可執行檔案格式(包括.exe、.scr、.dll、.sys、.obj等檔案),PE檔案指32位的可執行檔案,也稱為PE32。64位可執行檔案稱為PE+或PE32+,是PE32檔案的一種擴充套件形式。 基本結構 P
【軟體工程師中級職稱】學習總結
計算機系統 & 程式設計語言 & 作業系統知識 計算機系統知識這一塊側重於底層,或者說是硬體。 1.我們需要對CPU內部的那些元器件都分別負責什麼瞭解清楚 2.掌握資料的原碼、反
學習總結:工程管理與makefile
管理 用法 ron 有效 第一個 可執行 多目錄 log 包含 工程管理與makefile 一、為什麽需要makefile和make 一個工程中的源文件可能很多,按照類型、功能、模塊分別放在若幹個目錄中,為了有效地管理軟件工程,更高效地編譯整個工程,需要用到makefile
軟體工程(C編碼實踐篇)學習總結
軟體工程(C編碼實踐篇)學習總結 班級:軟設三班,學號:SA17225363,姓名:王世卿,網易雲暱稱:王世卿 原創作品轉載請註明出處 Github地址:https://github.com/wsqat/gaoruan MOOC課程 : h
《高階軟體工程》學習總結
1.課程總結 《高階軟體工程》這門課程在軟體學院非常搶手,在選課開始的時候我特地去了網咖等待選課系統開放並在第一時間選了這門課程,所以才能有幸跟著孟寧老師學習這門課程。在此之前,我對軟體工程的理解非常淺顯,甚至並不具備基本的軟體工程的思想,遇到課程設計或者是畢業設計,我
《軟體工程》學習總結
劉洋 原創作品轉載請註明出處《軟體工程(C編碼實踐篇)》MOOC課程http://mooc.study.163.com/course/USTC-1000002006 ” 學習心得 首先,必須要宣告一件事,這是一門非常有用且實用的課程。說實話,本以為這門課
大型工程多個目錄下的Makefile寫法
qt5 pan ron 指定 com exec bsp 可執行文件 不同 1、前言 目前從事於linux下程序開發,涉及到多個文件,多個目錄,這時候編譯文件的任務量比較大,需要寫Makefile。關於Makefile的詳細內容可以參考網上流傳非常廣泛的《跟我一起寫Ma
軟件工程(C編碼實踐篇)學習總結
軟件工程 中國科大 軟件工程是一個把用戶需求轉化為實際軟件的過程,軟件工程師用具體的代碼來實現軟件,對代碼進行測試,並確認它可以投入使用的過程,在這個過程中的每個階段,都包含有相應的文檔來規範化每一個過程。 軟件開發過程當中,遵循著一定的流程,它可以細分為:可行性驗證需求分析概要設計詳細
軟件工程期末學習總結
git 高效 枯燥 pan 關於 nbsp 就是 bsp 感覺 計算機科學與技術專業 3班 趙又葦 201510411326 GitHub地址 :https://github.com/370950206/- 經過一個學期的軟件工程的學習,我在這門課程上學習到
Orleans學習總結(二)--創建工程
單機版 input cluster res isnull stp pre log hello 通過第一篇Orleans學習總結(一)--入門認識我們大致知道知道是幹嘛的了,下面我們來動手造一個傳說中的神秘的高並發集群Orleans程序。 一、創建四個C#工程 1、IG
20172302 《Java軟體結構與資料結構》第七週學習總結
2018年學習總結部落格總目錄:第一週 第二週 第三週 第四周 第五週 第六週 第七週 教材學習內容總結 第11章 二叉查詢樹 1.二叉查詢樹是一種含有附加屬性的二叉樹,該屬性即其左孩子小於父節點,而父節點又小於等於其右孩子。二叉查詢樹的一個示意圖: 在二叉查詢樹中: &nbs
2018-2019-20172329 《Java軟體結構與資料結構》第七週學習總結
2018-2019-20172329 《Java軟體結構與資料結構》第七週學習總結 教材學習內容總結 《Java軟體結構與資料結構》第十一章-二叉查詢樹 一、概述 1、什麼是二叉查詢樹:二叉查詢樹是一種帶有附加屬性的二叉樹,即對樹中的每個結點,其左孩子都要小於其父結點,而父結點又小於或等於其右孩
20172305 2018-2019-1 《Java軟體結構與資料結構》第七週學習總結
20172305 2018-2019-1 《Java軟體結構與資料結構》第七週學習總結 教材學習內容總結 本週內容主要為書第十一章內容: 二叉查詢樹(附加屬性的二叉樹) 二叉查詢樹是對樹中的每個結點,其左結點都要小於其父結點,而父結點又小於或等於其右結點。 二叉查詢樹的定義
現代軟體工程第二次結對程式設計(統計詞頻)總結
作業要求及Github連結 作業要求:文字檔案中英語單詞的頻率 專案原始碼:統計詞頻 合作方式 有了第一次結對程式設計的經驗,我們這次有意識的採取了多種合作方式: 結對程式設計,我和隊友共用一臺顯示器和電腦完成了最簡單的-c -f標籤的處理和輸入輸出統一。 各自獨立程式設計,我和隊友各自獨立
軟體工程學習筆記《三》程式碼優化和效能測試
如何在開源社群提問? 如果你提問沒有人回答!那麼是不是沒有人會呢?其實不然!可能你提問的方式本身就是不對的,我們來看看大牛是怎樣提問的?一起來學一下 https://github.com/seajs/seajs/issues/545 程式碼審查 程式碼優化
軟考總結---(五)軟體工程基礎知識
前言:下面和大家分享一下第五章的知識點,希望對大家有幫助。 (一)軟體工程概述 1.計算機軟體【分類】(十大類) 系統軟體、應用軟體(解決特定業務需要的獨立應用程式) 工程/科學軟體、嵌入式軟體(控制面向最終使用者和系統本身的特徵和功能) 產品線軟體(多個不同使用者的使用提供
軟體工程學習筆記《三》需求獲取
文章目錄 軟體工程學習筆記《目錄》 需求工程師 當代的需求工程師需要具備的能力 當代的需求工程師需要努力的方向 當代的需求工程師需要注意的錯誤 需求的定義 需求目標 需求分析的實質 需求分析的關鍵
2018-2019-20172329 《Java軟體結構與資料結構》第八週學習總結
2018-2019-20172329 《Java軟體結構與資料結構》第八週學習總結 現在對於我而言,最珍貴的是時間,感覺自己在時間飛逝的時候真的挽留不住什麼,只能怒髮衝冠的讓自己瘋狂的學習啦,新的一週要加油!❤️ 教材學習內容總結 《Java軟體結構與資料結構》第十二章-優先佇列與堆 一、概