如何优雅地将m4宏处理器加入GCC编译链?优先autotools方案
Autotools 下实现 m4 前置预编译的方案
下面提供两种不同场景的实现方式,都属于项目级配置,不会影响系统全局编译行为:
方案1:全局所有.c文件自动走m4处理
适合你确实需要给项目内所有C代码都过一遍m4的场景:
- 首先在
configure.ac中添加m4工具检测,放在AC_PROG_CC之后即可:
配置阶段如果找不到可用的m4程序会直接报错终止,避免后续编译失败。AC_PROG_M4 - 之后在项目根目录的
Makefile.am中覆盖默认的C语言编译隐式规则:
你可以在.c.o: $(M4) $< > $@.tmp.c $(COMPILE) -c $@.tmp.c -o $@ rm -f $@.tmp.c$(M4)后面加自己需要的参数,比如-I指定宏文件搜索目录、-D定义全局m4宏等。如果需要保留m4处理后的中间C文件调试,删掉最后一行rm命令即可。
方案2:仅指定文件走m4处理(更推荐)
这是更优雅的实现,不会误伤不需要m4处理的普通C文件,对现有构建流程侵入性更低:
- 第一步同样在
configure.ac添加AC_PROG_M4检测m4工具。 - 在
Makefile.am中注册自定义后缀规则:
这种方式下Automake可以自动识别依赖链,你修改# 声明可识别的后缀 SUFFIXES = .m4 .c # 定义.m4文件转.c文件的规则 .m4.c: $(M4) $< > $@ # 编译目标配置示例 bin_PROGRAMS = myapp # 把需要m4处理的文件后缀命名为.c.m4,直接加到源文件列表即可 myapp_SOURCES = main.c.m4 utils.c.m4 normal.c.c.m4文件或者引用的m4宏文件时,会自动触发对应C文件的重新生成和编译,完全兼容原生的自动依赖跟踪功能。
补充配置技巧
如果需要在配置阶段动态给m4传参,比如传递项目版本号、编译选项等,可以在configure.ac中添加如下配置:
M4_FLAGS="-DPROJECT_VERSION=\"$(PACKAGE_VERSION)\" -DMY_CUSTOM_MACRO=1" AC_SUBST(M4_FLAGS)
之后在Makefile.am的m4调用命令里直接使用$(M4) $(M4_FLAGS)即可。
不推荐直接修改GCC的spec文件实现全局替换,这种方式是系统级生效的,会影响所有调用GCC的编译任务,不属于项目级的合理实现。
内容的提问来源于stack exchange,提问作者psprint
相关产品推荐
相关产品推荐

