變量與函數(shù)的綜合示例
1.項目需求
- 自動生成target文件夾存放可執(zhí)行文件
- 自動生成objs文件夾存放編譯生成的目標文件(*.o)
- 支持調(diào)試版本的編譯選項
- 考慮代碼的擴展性
2. 關鍵語法
- $(wildcard _pattern)
獲取當前工作目錄中滿足_pattern的文件或目錄列表 - $(addprefix _prefix,_names)
給名字列表_names中的每一個名字增加前綴_prefix
3. 關鍵技巧
- 自動獲取當前目錄下的源文件列表(函數(shù)調(diào)用)
SRCS += $(wildcard *.c)
- 根據(jù)源文件列表生成目標文件列表(變量的值替換)
OBJS := $(SRCS:.c=.o)
- 對每一個目標文件列表加上路徑前綴(函數(shù)調(diào)用)
OBJS := $(addprefix path/,$(OBJS))
4. 規(guī)則中的模式替換(目錄結構)
本質(zhì):匹配當前目錄下的文件看峻,然后根據(jù)模式將當前目錄下的文件進行特定替換
前提:工作目錄中存在func.c main.c
說明:
- %.c用于模式匹配當前目錄下的文件
- %.o用于將%.c匹配成功的文件名進行模式替換衙吩,.c替換.o
%.o : %.c
gcc -o $@ -c $^
與變量的值替換的區(qū)別:
變量值替換是從給定的列表中將文件一一進行匹配互妓,然后放入指定的依賴中;變量值替換如下所示:
OBJS := func.o main.o
$(OBJS) : %.o : %.c
gcc -o $@ -c $^
編譯規(guī)則的依賴如下:
![10-1.PNG](https://upload-images.jianshu.io/upload_images/10834716-2f45145c35635422.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
示例代碼--變量與函數(shù)的綜合應用
源代碼如下:
const.c
const char* g_hello = "hello-makefile";
func.c
#include "stdio.h"
extern char* g_hello;
void foo()
{
printf("void foo():%s\n".g_hello);
}
main.c
extern void foo();
int main()
{
foo();
return 0;
}
makefile
CC := gcc
MKDIR := mkdir
RM := rm -rf
DIR_OBJS := objs
DIR_TARGET := target
DIRS := $(DIR_OBJS) $(DIR_TARGET)
#target/hello-makefile.out
TARGET := $(DIR_TARGET/hello-makefile.out
#SRCS = {const.c func.c main.c}
SRCS := $(wildcard *.c)
#OBJS = {const.o func.o main.o}
OBJS := $(SRCS:.c=.o)
#OBJS ={objs/const.o objs/func.o objs/main.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)
10-1.PNG
執(zhí)行結果如下:
10-2.PNG
下列左圖為命令行執(zhí)行make DEBUG:=true的結果坤塞;右圖為命令行執(zhí)行make的結果车猬;可以看到,當命令行指定DEUBG值之后尺锚,進入target文件夾后命令行執(zhí)行objdump -S hello-makefile.out可以看到匯編調(diào)試代碼中出現(xiàn)了源文件中的代碼珠闰,方便進行調(diào)試。而右圖僅僅只有匯編部分代碼瘫辩。
10-3.PNG
小結:
- 目錄可以成為目標的依賴,在規(guī)則中創(chuàng)建目錄
- 預定義函數(shù)是makefile實戰(zhàn)時不可或缺的部分
- 規(guī)則中的模式匹配可以直接針對目錄中的文件
- 可以使用命令行變量編譯特殊的目標版本