一個自動管理項目的Makefile(C語言)

Linux 是全部嵌入式軟件工程師繞不過去的坎,shell

makefile 是在Linux系統中繞不過去的坎。編程

花了幾天時間初步學習和了解了makefile 的做用以及功能,而且製做了一個通用型的makefile 用於管理後續可能的在Linux上獨立開發的項目。網絡

在此用筆記的方式記下。怕本身之後忘了。編程語言

 

makefile 思想: makefile 核心公式     ide

<target_file> : <source_file>學習

  command....優化

若是目標文件不存在或者 源文件中有 比目標文件修改日期還要新的,那麼執行command 命令 ;spa

command命令的功能使用來更新生成目標文件code

同時上一個 公式中的 源文件 又能夠嵌套成爲下一個公式的 目標文件。周而復始。blog

上述公式中,若是目標文件和源文件都是最新的,那麼command命令就不會被執行。這樣在不少大型項目中,會被更新的就只有修改了的文件和最終的輸出文件大幅的下降的編譯的時間

 

同時makefile中支持豐富的邏輯、變換等。深刻研究徹底能夠做爲一門新的編程語言進行開發。

如下分享本身藉助網絡大牛的力量優化編寫的一個makefile文件。

此makefile放置在項目的根目錄下。

  例如:Pro文件夾中有 Inc、Res、Img文件夾;

        裏面有 頭文件、源碼文件、圖片文件、項目文件等;

        全部關於Pro項目的文件都在Pro文件下,makefile文件應該被放置在Pro文件夾中

注意事項:獲取絕對路徑功能只適用於 GUN編譯器

功能:  會將Pro文件中全部的*.c *.h 文件視爲一個項目,總體編譯、連接;

     遞歸掃描各文件夾

     只編譯未編譯的文件或者更新後與其相關的文件

     clean命令   刪除全部makefile會生成的文件

       cleanO命令(大寫字母 O) 刪除除可執行文件外,makefile生成的文件。

     des命令     打印當前項目中的絕對路徑以及 全部源文件的絕對路徑。

 

 

  1 #此項目源文件後綴類型
  2 PROJECTTYPE = .c
  3 
  4 #您想要生成可執行文件的名字
  5 BinName :=obj.out
  6 
  7 
  8 #獲取當前makefile絕對路徑
  9 pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST))
 10 pes_parent_dir:=$(shell dirname $(pes_parent_dir))
 11 
 12 #首先跳轉到makefile目錄下,而後獲取該目錄下全部子目錄
 13 AllDirs := $(shell cd $(pes_parent_dir); ls -R | grep '^\./.*:$$' | awk '{gsub(":","");print}') .
 14 
 15 #添加成爲絕對路徑
 16 AllDirs := $(foreach n,$(AllDirs),$(subst .,$(pes_parent_dir),$(n)))
 17 
 18 #獲取全部 .c/.cpp文件路徑
 19 Sources := $(foreach n,$(AllDirs) , $(wildcard $(n)/*$(PROJECTTYPE)))
 20 
 21 #處理獲得*.o 後綴文件名
 22 OBJS = $(patsubst %$(PROJECTTYPE),%.o, $(Sources))
 23 
 24 #同理獲得 *.d文件名
 25 Deps := $(patsubst %$(PROJECTTYPE),%.d, $(Sources))
 26 
 27 #須要用到的第三方靜態庫
 28 StaticLib :=
 29 
 30 #須要用到的第三方動態連接庫
 31 DynamicLib :=
 32 
 33 #真實二進制文件輸出路徑(絕對)
 34 Bin :=$(pes_parent_dir)/$(BinName)
 35 
 36 #C語言編譯器
 37 CC = gcc
 38 
 39 #C++編譯器
 40 CXX = g++
 41 
 42 #簡化rm -f
 43 RM = -rm -f
 44 
 45 #C語言配置參數
 46 CFLAGS = -g  -pedantic -std=c99 -Wall -o
 47 
 48 #C++配置參數
 49 CXXFLAGS = -g -Wall -std=c11
 50 
 51 #頭文件搜索路徑
 52 INCLUDE_PATH = $(foreach n,$(AllDirs) , -I$(n))
 53 
 54 
 55 LDFLAGS =
 56 
 57 #指定AllLibs爲終極目標 即:最新的Bin
 58 AllLibs:$(Bin)
 59 
 60 #聲明這個標籤 des 用於觀察當前的路徑是否正確
 61 .PHONY:des
 62 des:
 63         @echo OBJS =  $(OBJS)
 64         @echo cur_makefile_path = $(pes_parent_dir)
 65         @echo AllDirs = $(AllDirs)
 66         @echo Sources = $(Sources)
 67         @echo Deps = $(Deps)
 68 
 69 #對應關係 在本makefile中以空格隔開的後綴爲.c 都會爲其生成一個新的.d文件 意圖爲更新全部*.c文件的include依賴關係
 70 %.d : %.c
 71            @echo 'finding $< depending head file'
 72            @$(CC) -MT"$(<:.c=.o) $@" -MM $(INCLUDE_PATH) $(CPPFLAGS) $< > $@
 73 
 74 #對於include中的*.d文件,只要裏面任意有一個文件被修改,那麼就會觸發此規則生成一個新的*.o文件
 75 %.o: %.d
 76         @echo compile $(<:d=c)
 77         @$(CC) -c $(<:.d=.c) $(INCLUDE_PATH) $(CFLAGS) $@
 78 
 79 sinclude $(Sources:.c=.d)
 80 
 81 $(Bin) : $(OBJS)
 82         @echo bulding....
 83         @$(CC) $(OBJS)  $(CFLAGS) $(Bin)
 84         @echo created file: $(BinName)
 85 
 86 .PHONY : clean
 87 clean:
 88             @echo '清理全部文件'
 89             @$(RM) $(OBJS) $(Deps) $(Bin)
 90 
 91 .PHONY : cleanO
 92 cleanO:
 93             @echo '清理Obj && Dep'
 94             @$(RM) $(OBJS) $(Deps)
 95 #    #########################################################################
 96 #    單獨的 < 符號表明 依存源文件(即冒號: 的左邊) $< 表明將源文件展開成爲字符
 97 #   單獨的 @ 符號表明 目標文件   (冒號 : 的右邊)  $@ 表明將目標文件名稱展開成爲字符
 98 #    符號 @ 後接命令則表示:此語句執行,但並不現實 
 99 #        例如:@$(CC) $(OBJS)  $(CFLAGS) $(Bin)   
100 #        只執行連接命令,可是不將此字符串打印至終端
101 #   關鍵字:@echo  表示該行後的命令只顯示 不執行。 
102 #        注意:雖然只顯示,可是他依舊會以執行命令的要求的解析文本,
103 #             只是不執行而已,若是須要輸出字符串使用‘  ’將內容引用便可
104 #   重點符號 $ : 表示轉義,在makefile中不管在哪裏都會被識別爲轉義字符,
105 #                若是想表示 $符號,那麼須要使用 $$ 
106 #        例如:@echo ‘$$$$’  終端將會輸入 : "$$" 
107 #    其他makefile 知識參考  《跟我一塊兒寫 MakeFile》 ----陳皓  
108 #    #########################################################################
109                                   
View Code
相關文章
相關標籤/搜索