如何用GCC和Make生成模块、头单元预编译文件及依赖列表?
解决方案与步骤
1. 生成依赖列表的正确命令
你遇到的-MG报错是因为该选项仅能与-M或-MM配合使用(用于生成依赖关系到标准输出),不能和-MMD(同时生成.d文件并编译目标文件)混用。要生成包含缺失头单元/模块的依赖列表,执行:
/usr/local/bin/g++ -MM -MG -std=c++23 -fmodules-ts test400.cc > test400.d
这条命令会忽略.gcm文件不存在的问题,直接生成依赖关系到test400.d中。
2. 预编译标准库头单元
GCC的模块TS要求导入的头单元必须先编译为.gcm(GCC Compiled Module)文件。对于标准库头文件,用以下命令预编译:
- 预编译
<iostream>:/usr/local/bin/g++ -std=c++23 -fmodules-ts -xc++-system-header iostream - 预编译
<array>:/usr/local/bin/g++ -std=c++23 -fmodules-ts -xc++-system-header array
编译后的.gcm文件会默认存放在当前目录的gcm.cache子目录下,对应错误提示中的路径。
3. 编译自定义模块modA
假设modA的接口单元文件为modA.cc(内容需包含export module modA;声明),编译模块接口:
/usr/local/bin/g++ -std=c++23 -fmodules-ts -c modA.cc -o modA.o
GCC会自动生成modA对应的.gcm文件到缓存目录,后续编译主文件时会自动识别。
4. 用Make自动化流程
以下是完整的Makefile示例,可自动处理头单元预编译、模块编译、主文件编译及依赖管理:
CC = /usr/local/bin/g++ CXXFLAGS = -std=c++23 -fconcepts -fmodules-ts # 需预编译的标准库头单元 HEAD_UNITS = iostream array HEAD_UNIT_GCMS = $(foreach hu,$(HEAD_UNITS),gcm.cache/./usr/local/include/c++/14.0.0/$(hu).gcm) # 自定义模块 MODULE_OBJS = modA.o all: test400 # 预编译标准库头单元 $(HEAD_UNIT_GCMS): $(CC) $(CXXFLAGS) -xc++-system-header $(notdir $(basename $(@F))) # 编译自定义模块 modA.o: modA.cc $(CC) $(CXXFLAGS) -c $< -o $@ # 编译主程序,依赖头单元和模块 test400: test400.cc $(HEAD_UNIT_GCMS) $(MODULE_OBJS) $(CC) $(CXXFLAGS) $< $(MODULE_OBJS) -o $@ # 生成依赖文件 test400.d: test400.cc $(CC) -MM -MG $(CXXFLAGS) $< > $@ include test400.d clean: rm -f test400 *.o *.d rm -rf gcm.cache
执行make即可完成全部编译流程,make clean可清理生成的文件。
内容的提问来源于stack exchange,提问作者wimalopaan
相关产品推荐
相关产品推荐

