1. 程式人生 > >變量與函數的綜合示例(九)

變量與函數的綜合示例(九)

PE == build 怎樣 綜合 pan bsp fun 程序

之前我們學習了 makefile 中的變量及函數的相關語法知識,那麽我們今天就來以實際需求為例來進行實際編寫。實戰需求:1、自動生成 target 文件夾存放可執行文件;2、自動生成 objs 文件夾存放編譯生成的目標文件(*.o);3、支持調試版本的編譯選項;4、考慮代碼的擴展性。

那麽在進行今天的 makefile 編寫之前,我們還需要了解下幾個知識點:a> $(wildcard _pattern),它的作用是獲取當前工作目錄中滿足 _pattern 的文件或目錄列表;b> $(addprefix _prefix,_names),它的作用是給名字列表 _names 中的每一個名字增加前綴 _prefix。

其中的關鍵技巧:1、自動獲取當前目錄下的源文件列表(函數調用):SRCS := $(wildcard *.c);2、根據源文件列表生成目標文件列表(變量的值替換):OBJS := $(SRCS:.c=.o);3、對每一個目標列表加上路徑前綴(函數調用):OBJS := $(addprefix path/, $(OBJS))。

我們來看看規則中的模式替換(目錄結構),如下

技術分享圖片

看看編譯規則的依賴,如下

技術分享圖片

下來我們來看看具體的 makefile 是怎樣編寫的,還是以之前的那三個 .c 文件為源文件。

CC := gcc
MKDIR := mkdir
RM := rm -rf

DIR_OBJS := objs
DIR_TARGET := target

DIRS := $(DIR_OBJS) $(DIR_TARGET)

TARGET := $(DIR_TARGET)/hello-makefile.out

# main.c func.c const.c
SRCS := $(wildcard *.c)

# main.o func.o const.o
OBJS := $(SRCS:.c=.o)

# objs/main.o objs/func.o objs/const.o
OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))


.PHONY : rebuild clean all

$(TARGET) : $(DIRS) $(OBJS)
    $(CC) -o $@ $(OBJS)
    @echo "Target File ==> $@"

$(DIRS) :
    $(MKDIR) $@

$(DIR_OBJS)/%.o : %.c
    ifeq ($(DEBUG),true)
        $(CC) -o $@ -g -c $^
    else
        $(CC) -o $@ -c $^
    endif

rebuild : clean all

all : $(TARGET)

clean :
    $(RM) $(DIRS)

我們來看看編譯效果

技術分享圖片

我們看到已經正確執行了,在當前目錄下自動生成兩個文件夾 objs target。在 objs 文件夾裏生成三個 .o 文件,在 target 文件夾中生成 hello-makefile.out 文件,執行這個可執行文件,結果也是我們之前定義的。下來我們來看看能不能定義 DEBUG 版的程序,這時便要用到一個命令了 objdump -S target,它用於來查看程序是否為調試版。下來我們來看看結果,圖 a 為普通版的,圖 b 為 DEBUG 版的

技術分享圖片

圖 a 普通版

技術分享圖片

圖 b DEBUG 版

我們看到 DEBUG 版本相對於普通版來說,多了一些東西,比如我們在裏面寫的 printf 語句,而且多了函數調用的語句。普通版則是只執行程序就 OK 了。通過今天的綜合示例的編寫,總結如下:1、目錄是可以成為目標的依賴的,在規則中創建目錄;2、預定義函數是 makefile實戰時不可或缺的部分;3、規則中的模式匹配可以直接針對目錄中的文件;4、可以使用命令行變量編譯特殊的目標版本。


歡迎大家一起來學習 makefile 語言,可以加我QQ:243343083

變量與函數的綜合示例(九)