1. 程式人生 > >Linux下多資料夾編寫Makefile詳解

Linux下多資料夾編寫Makefile詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

-Werror     @Take warning as error handling 


子目錄下面的Makefile編寫是最簡單的,最重要的是編寫頂層目錄下的Makefile和Makefile.build。


本程式的Makefile分為3類:

1. 頂層目錄的Makefile
2. 頂層目錄的Makefile.build
3. 各級子目錄的Makefile


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



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

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

三、頂層目錄的Makefile.build:
   這是最複雜的部分,它的功能就是把某個目錄及它的所有子目錄中、需要編程序序去的檔案都編譯出來,打包為built-in.o
 
四、怎麼使用這套Makefile:
1.把頂層Makefile, Makefile.build放入程式的頂層目錄

2.修改頂層Makefile
2.1 修改工具鏈
2.2 修改編譯選項、連結選項
2.3 修改obj-y決定頂層目錄下哪些檔案、哪些子目錄被編程序序
2.4 修改TARGET,這是用來指定編譯出來的程式的名字

3. 在各一個子目錄下都建一個Makefile,形式為:
obj-y += file1.o
obj-y += file2.o
obj-y += subdir1/
obj-y += subdir2/

4. 執行"make"來編譯,執行"make clean"來清除,執行"make distclean"來徹底清除
   

下面我用一個簡單的事例來說明,在原始碼中我會解釋一些命令。   

我目錄下面有add,sub,input,include4個資料夾,分別實現求和,求差,輸入一個值,標頭檔案宣告。這四個資料夾下面的Makefile都按照obj-y += file.o  obj-y += subdir/格式寫的,這個非常簡單,下面重點介紹根目錄下面的Makefile和Makefile.build。

Makefile編寫如下


CROSS_COMPILE = arm-linux-                  /* 下面定義的是一些連結命令,方便使用 */
AS = $(CROSS_COMPILE)as   
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm


STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy    
OBJDUMP = $(CROSS_COMPILE)objdump


export AS LD CC CPP AR NM               /* 匯出這些變數方便使用,固定格式不用去深究它 */
export STRIP OBJCOPY OBJDUMP

CFLAGS := -Wall -O2 -g
CFLAGS += -I $(shell pwd)/include        /* 指定編譯過程中自己寫的標頭檔案路徑 */


LDFLAGS := -lm -lfreetype -lts -lpthread    /* 編譯過程所使用的連結選項,這個程式是用不到的,如果你編譯出錯就把這一行去掉,因為你沒有安裝這些庫檔案,寫出來是為了統一格式。 */

export CFLAGS LDFLAGS     /* 還是匯出變數 */

TOPDIR := $(shell pwd)     /* 頂層目錄的路徑 */
export TOPDIR
export CFLAGS LDFLAGS     


TARGET := exec  /* 指定輸出檔名上面都是固定格式,變化如下幾個檔案,或者改變上面的連結庫和標頭檔案路徑 */

obj-y += main.o   /* 底層目錄下的檔案 */
obj-y += add/       /* 子目錄的名字 */
obj-y += sub/
obj-y += input/


all : 
make -C ./ -f $(TOPDIR)/Makefile.build
$(CC) $(LDFLAGS) -o $(TARGET) built-in.o

clean:
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)

下面是Makefile.build檔案的編寫

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)
endif

PHONY += $(subdir-y)

__build : $(subdir-y) built-in.o

$(subdir-y):
make -C [email protected] -f $(TOPDIR)/Makefile.build  

built-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)


到此為止我們就講完了,我會把原始碼上傳上傳上來,當你要改變你的檔案的時候,你只需修改檔名字和連線口,標頭檔案路徑就可以了,基本格式是不變的。檔案下載路徑:請點選這裡!

如果提示找不到連線庫直接把那個找不到的連結庫選項去掉。


           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述