編寫一個通用的Makefile檔案

來源:互聯網
上載者:User

標籤:flags   out   copy   gcc   測試   cpp   庫檔案   exp   使用   

1.1在這之前,我們需要瞭解程式的編譯過程

a.預先處理:檢查語法錯誤,展開宏,包含標頭檔等

b.編譯:*.c-->*.S

c.彙編:*.S-->*.o

d.連結:.o +庫檔案=*.exe

1.2體驗在VC下程式的編譯

a.先編譯,在連結

b.修改了哪個檔案,就單獨編譯此檔案,在連結

c.修改了哪個標頭檔,就單獨編譯使用該標頭檔的源檔案,在連結

1.3在linux下實現上述要求

2.編寫一個測試的Makefile

2.1直接編譯連結

 1 gcc -o test a.c b.c 

缺點:改變其中一個檔案,還需要重新編譯所有檔案,最後連結,效率低

2.2編寫一個通用的Makefile

核心:規則

 

目標:依賴1 依賴2...

  命令

 

命令的執行條件:

a.依賴檔案比目標檔案新

b.沒有目標檔案

2.2.1一個簡單的Makefile檔案

test:a.c b.c a.h    gcc -o test a.c b.c

缺點:當其中一個檔案發生改變時,另一個檔案又將從新編譯連結

2.2.2針對上述,改為如下

test:a.o b.o    gcc -o test a.o b.oa.o : a.c     gcc -c -o a.o a.c    b.o : b.c    gcc -c -o b.o b.c    

缺點:a.如果test依賴於多個檔案,將寫許多代碼。

b.修改a.h程式沒有反應。

2.2.3

針對上述a,可將其改為萬用字元;針對b,可增加“a.o:a.c a.h”這段代碼。

[email protected]:表示目標;$^:表示全部依賴;$<:第一個依賴。

test:a.o b.o    gcc -o test a.o b.oa.o:a.c a.h%.o : %.c     gcc -c -o [email protected] $<

缺點:如果一個檔案的標頭檔非常多,不可能一個一個列出來,應該產生一個依賴檔案。

2.2.4產生依賴檔案

wildcard:檢查檔案是否存在

-Wp,-MD:產生依賴檔案

objs := a.o b.otest:$(objs)    gcc -o test $^# .a.o.d .b.o.ddep_files := $(foreach f,$(objs),.$(f).d)//對於objs裡的每個檔案,產生對應的依賴檔案。eg:a.o-->.a.o.ddep_files := $(wildcard $(dep_files))ifneq ($(dep_files),)  include $(dep_files)endif%.o : %.c     gcc -Wp,-MD,[email protected] -c -o [email protected] $<clean:    rm *.o test

3.參照核心的Makefile和上述的test_Makefile,編寫一個通用的Makefile

3.1子目錄下的Makefile
   它最簡單,形式如下:
obj-y += file.o
obj-y += subdir/
   
   "obj-y += file.o"表示把目前的目錄下的file.c編進程式裡,
   "obj-y += subdir/"表示要進入subdir這個子目錄下去尋找檔案來編進程式裡,是哪些檔案由subdir目錄下的Makefile決定。

注意: "subdir/"中的斜杠"/"不可省略

3.2頂層目錄的Makefile:
   它除了定義obj-y來指定根目錄下要編進程式去的檔案、子目錄外,主要是定義工具鏈、編譯參數、連結參數──就是檔案中用export匯出的各變數。

CROSS_COMPILE = arm-linux-      //交叉編譯工具鏈AS        = $(CROSS_COMPILE)asLD        = $(CROSS_COMPILE)ldCC        = $(CROSS_COMPILE)gccCPP        = $(CC) -EAR        = $(CROSS_COMPILE)arNM        = $(CROSS_COMPILE)nmSTRIP        = $(CROSS_COMPILE)stripOBJCOPY        = $(CROSS_COMPILE)objcopyOBJDUMP        = $(CROSS_COMPILE)objdumpexport AS LD CC CPP AR NM     //匯出變數export STRIP OBJCOPY OBJDUMPCFLAGS := -Wall -O2 -g        //編譯選項CFLAGS += -I $(shell pwd)/includeLDFLAGS := -lm -lfreetype     //連結選項export CFLAGS LDFLAGSTOPDIR := $(shell pwd)export TOPDIRTARGET := show_fileobj-y += main.oobj-y += display/obj-y += draw/obj-y += encoding/obj-y += fonts/all :     make -C ./ -f $(TOPDIR)/Makefile.build       //開啟檔案,按照頂層目錄下的Makefile.build來編譯    $(CC) $(LDFLAGS) -o $(TARGET) built-in.o     //linkclean:    rm -f $(shell find -name "*.o")    rm -f $(TARGET)distclean:    rm -f $(shell find -name "*.o")    rm -f $(shell find -name "*.d")    rm -f $(TARGET)    

3.3頂層目錄的Makefile.build:
   這是最複雜的部分,它的功能就是把某個目錄及它的所有子目錄中、需要編進程式去的檔案都編譯出來,打包為built-in.o。

PHONY := __build__build:obj-y :=subdir-y :=include Makefile__subdir-y    := $(patsubst %/,%,$(filter %/, $(obj-y)))subdir-y    += $(__subdir-y)subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)cur_objs := $(filter-out %/, $(obj-y))dep_files := $(foreach f,$(cur_objs),.$(f).d)dep_files := $(wildcard $(dep_files))ifneq ($(dep_files),)  include $(dep_files)endifPHONY += $(subdir-y)__build : $(subdir-y) built-in.o$(subdir-y):    make -C [email protected] -f $(TOPDIR)/Makefile.buildbuilt-in.o : $(cur_objs) $(subdir_objs)    $(LD) -r -o [email protected] $^dep_file = [email protected]%.o : %.c    $(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o [email protected] $<    .PHONY : $(PHONY)

編寫一個通用的Makefile檔案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.