【Makefile】编译 .h 头文件生成 .gch 预编译文件


目录

1、为什么要将 .h 编译生成 .gch 文件

2、工程示例

3、Makefile

(1)获取头文件

(2)引入头文件目录

(3)设置目标文件的保存位置

(4)开始编译 .h 和 .hpp 文件

4、脚本测试

5、完整脚本


1、为什么要将 .h 编译生成 .gch 文件

gch 文件,也称为预编译头文件(Precompiled Header,简称PCH),当多个源文件(如.cpp文件)包含同一个头文件(如.h文件)时,传统的编译方式会在每个源文件中都预编译这个头文件,这会导致大量的重复工作,从而浪费编译时间。

为了解决这个问题,可以使用预编译头文件技术。预编译头文件将头文件预编译为二进制代码(即GCH文件),然后在后续的编译过程中,编译器可以直接使用这个二进制代码,而不需要再次解析头文件。这样可以大大减少编译时间。

2、工程示例

这里使用一个简单的工程来将不同目录下的 .h 文件编译生成 .gch 文件,并保存到 build目录下。当前测试工程下 common 和 util 目录包含 .h 或 .hpp 文件。

3、Makefile

(1)获取头文件

ROOTDIR				= .
BUILD_DIR			= build

# 获取 common 和 util 下的所有头文件
C_INCLUDES			= $(wildcard $(ROOTDIR)/common/*.h $(ROOTDIR)/common/*.hpp)
C_INCLUDES			+= $(wildcard $(ROOTDIR)/util/*.h $(ROOTDIR)/util/*.hpp)

(2)引入头文件目录

头文件之间可能会相互包含,为了避免某个头文件找不到其他头文件,需要在编译时引入所有的头文件目录。

CFLAGS				= \
-I$(ROOTDIR)/common \
-I$(ROOTDIR)/util \

(3)设置目标文件的保存位置

C_INCLUDES 变量已经获取到了所有的头文件名称(包含路径),现在要将头文件保存到 build 目录下。

# 将 .h 后缀替换成 .gch,并加上前缀 build/,新的文件名保存到 C_PCHS_TMP
C_PCHS_TMP				= $(addprefix $(BUILD_DIR)/,$(notdir $(C_INCLUDES:.h=.gch)))
C_PCHS_TMP				+= $(addprefix $(BUILD_DIR)/,$(notdir $(C_INCLUDES:.hpp=.gch)))
# 避免 C_PCHS_TMP 中混入 .h 或 .hpp 文件
C_PCHS					= $(filter-out %.h %.hpp,$(C_PCHS_TMP))
# 后续使用 %.gch:%.h 进行编译时,方便编译器找到 .h 文件
vpath %.h $(sort $(dir $(C_INCLUDES)))
vpath %.hpp $(sort $(dir $(C_INCLUDES)))

 

(4)开始编译 .h 和 .hpp 文件

all: $(C_PCHS)

$(BUILD_DIR)/%.gch: %.h
	$(CC) -x c++-header $< -o $@

$(BUILD_DIR)/%.gch: %.hpp
	$(CC) -x c++-header $< -o $@

4、脚本测试

在终端输入 make 开始编译 

build 目录下会生成 .gch 文件

5、完整脚本

ROOTDIR				= .
BUILD_DIR			= build

C_INCLUDES			= $(wildcard $(ROOTDIR)/common/*.h $(ROOTDIR)/common/*.hpp)
C_INCLUDES			+= $(wildcard $(ROOTDIR)/util/*.h $(ROOTDIR)/util/*.hpp)

CFLAGS				= \
-I$(ROOTDIR)/common \
-I$(ROOTDIR)/util \

C_PCHS_TMP				= $(addprefix $(BUILD_DIR)/,$(notdir $(C_INCLUDES:.h=.gch)))
C_PCHS_TMP				+= $(addprefix $(BUILD_DIR)/,$(notdir $(C_INCLUDES:.hpp=.gch)))
C_PCHS					= $(filter-out %.h %.hpp,$(C_PCHS_TMP))
vpath %.h $(sort $(dir $(C_INCLUDES)))
vpath %.hpp $(sort $(dir $(C_INCLUDES)))

all: $(C_PCHS)

$(BUILD_DIR)/%.gch: %.h
	$(CC) -x c++-header $< -o $@

$(BUILD_DIR)/%.gch: %.hpp
	$(CC) -x c++-header $< -o $@

.PHONY:clean
clean:
	rm -rf $(BUILD_DIR)/*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值