19.路径搜索的综合示例

本文介绍了一个实用的Makefile模板,该模板支持只读源码文件夹,并在编译时自动创建用于存放结果的文件夹。此外,还介绍了如何通过变量和函数调用来自动获取源文件列表、生成目标文件列表及替换路径前缀,从而实现Makefile的高度复用性和扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.需求分析

2.项目类型分析

3.工具原料

4.关键技巧

5.编译规则的依赖

6.值得斟酌的问题

7.小结


1.需求分析

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

2.项目类型分析

3.工具原料

4.关键技巧

1.自动获取源文件列表(函数调用)

2.根据源文件列表生成目标文件列表(变量的值替换)

3.替换每一个目标文件的路径前缀(函数调用)

5.编译规则的依赖

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

如果是使用的c++编写的,那么复用性不好,目前只适用于C语言编写的

进一步的优化,再一次使用变量进行优化

.PHONY : all clean

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

TYPE_INC := .h
TYPE_SRC := .c
TYPE_OBJ := .o


CC := gcc

CFLAGS := -I $(DIR_INC)

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) -o $@ $^
$(DIR_BUILD)/%$(TYPE_OBJ) : %$(TYPE_SRC) $(HDRS)
        $(CC) $(CFLAGS) -o $@ -c $<
clean :
        $(RM) $(DIR_BUILD)

如果要增加扩展性,改进如下

1.定义LFLAGS变量,定义编译时需要的链接选项的,这个例子不需要,其他项目可能需要

比如使用了多线程就需要指定链接:-pthread

2.为了方便调试,需要加上if语句,来支持调试版本

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

ifeq ($(DEBUG),ture)
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中是否也需要使用自动生成依赖关系的解决方案?

7.小结

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

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值