makefile专题:路径搜索的综合示例

1. 需求分析

1)工程项目中不希望源码文件夹在编译时被改动(只读文件夹)
2)在编译时自动创建文件夹(build)用于存放编译结果
3)编译过程中能够自动搜索需要的文件
4)makefile易于扩展,能够复用相同类型的项目
5)支持调试版本的编译选项

2. 项目类型分析

makefile专题:路径搜索的综合示例_第1张图片

3. 工具原料

  • $(wildcard $(DIR)/_pattern):获取$(DIR)文件夹中满足_pattern的文件
  • $(notdir _names):去除_names中每一个文件名的路径前缀
  • $(patsubst _pattern, replacement, _text):将_text中符合_pattern的部分替换为replacement

4. 关键技巧

1)自动获取源文件列表(函数调用):SRCS := $(wildcard src/*.c)
2)根据源文件列表生成目标文件列表(变量的值替换):OBJS := $(SRCS:.c=.o)
3)替换每一个目标文件的路径前缀(函数调用):OBJS := $(patsubst src/%, build/%, $(OBJS))

5. 编译规则的依赖

makefile专题:路径搜索的综合示例_第2张图片
.PHONY : all clean

DIR_BUILD := build
DIR_SRC := src
DIR_INC := inc

CC := gcc

CFLAGS := -I $(DIR_INC)

MKDIR := mkdir
RM := rm -rf

APP := $(DIR_BUILD)/app.out
HDRS := $(wildcard $(DIR_INC)/*.h)
HDRS := $(notdir $(HDRS))
OBJS := $(wildcard $(DIR_SRC)/*.c)
OBJS := $(OBJS:.c=.o)
OBJS := $(patsubst $(DIR_SRC)/%, $(DIR_BUILD)/%, $(OBJS))

vpath %.h $(DIR_INC)
vpath %.c $(DIR_SRC)

all : $(DIR_BUILD) $(APP)
    @echo "Target File ==> $(APP)"

$(DIR_BUILD) : 
    $(MKDIR) $@

$(APP) : $(OBJS)
    $(CC) -o $@ $^

$(DIR_BUILD)/%.o : %.c $(HDRS)
    $(CC) $(CFLAGS) -o $@ -c $<

clean:
    $(RM) $(DIR_BUILD)

提高扩展性,修改后:

.PHONY : all clean

DIR_BUILD := build
DIR_SRC := src
DIR_INC := inc

# 用变量表示后缀类型
TYPE_INC := .h
TYPE_SRC := .c
TYPE_OBJ := .o

CC := gcc
# 添加链接标签
LFLAGS :=
CFLAGS := -I $(DIR_INC)
# 添加DEBUG版本
ifeq ($(DEBUG), true)
CFLAGS += -g
endif

MKDIR := mkdir
RM := rm -rf

APP := $(DIR_BUILD)/app.out
HDRS := $(wildcard $(DIR_INC)/*$(TYPE_INC))
HDRS := $(notdir $(HDRS))
OBJS := $(wildcard $(DIR_SRC)/*$(TYPE_SRC))
OBJS := $(OBJS:$(TYPE_SRC)=$(TYPE_OBJ))
OBJS := $(patsubst $(DIR_SRC)/%, $(DIR_BUILD)/%, $(OBJS))

vpath %$(TYPE_INC) $(DIR_INC)
vpath %$(TYPE_SRC) $(DIR_SRC)

all : $(DIR_BUILD) $(APP)
    @echo "Target File ==> $(APP)"

$(DIR_BUILD) : 
    $(MKDIR) $@

$(APP) : $(OBJS)
    $(CC) $(LFLAGS) -o $@ $^

$(DIR_BUILD)/%$(TYPE_OBJ) : %$(TYPE_SRC) $(HDRS)
    $(CC) $(CFLAGS) -o $@ -c $<

clean:
    $(RM) $(DIR_BUILD)

6. 小结

  • 工程项目中不希望源码文件夹在编译时被改动
  • 模式规则的灵活运用使得makefile具有复用性
  • 变量的灵活运用使得makefile具有扩展性
  • 规模较小的项目没有必要使用自动生成依赖关系的解决方案
  • 规模较小的项目可以直接让源文件依赖于头文件(易于维护)

声明:此文章为本人在学习狄泰软件学院《十二月提升计划》所做的笔记,参考书籍《专业嵌入式软件开发》——李云,文章中包含狄泰软件资料内容和《专业嵌入式软件开发》资料内容,一切版权归狄泰软件《专业嵌入式软件开发》所有!

你可能感兴趣的:(makefile专题:路径搜索的综合示例)