执行make main时自动生成g++编译命令的原因及禁用方法
问题原因分析
执行make main时自动生成g++ -c -o hhh.mk.o hhh.mk.cc命令,核心原因是Make的读取阶段优先执行逻辑和隐式规则推导机制共同作用的结果:
- Make的执行流程分为读取阶段和执行阶段:读取阶段会先处理所有
include指令,此时pre目标还未执行,hhh.mk文件不存在。 - 对于
-include指定的不存在文件,Make不会直接报错,而是会尝试通过隐式规则自动推导生成该文件的路径。 - 你的Makefile中定义了
%.cc:的模式规则,允许生成任意.cc文件(仅输出内容,实际不生成实体文件);同时Make默认内置了%.o: %.cc的隐式编译规则。当Make尝试推导生成hhh.mk的可能路径时,错误触发了生成hhh.mk.o的需求,进而调用g++编译不存在的hhh.mk.cc(同时触发你的%.cc:规则尝试生成该文件)。
解决方法
以下几种方式可以禁用该自动生成的命令:
方法一:确保读取阶段就存在
hhh.mk
把生成hhh.mk的逻辑放在Make读取阶段执行,替代pre目标:$(shell touch hhh.mk) -include hhh.mk %.cc: echo $* main: test.cc echo main利用
$(shell)函数在Make读取配置时就创建hhh.mk,避免-include时因文件不存在触发隐式规则推导。方法二:明确
hhh.mk的生成规则
在Makefile中添加hhh.mk对pre的依赖,让Make明确知道hhh.mk的生成方式,无需触发隐式规则:pre: sh touch.sh hhh.mk: pre -include hhh.mk %.cc: echo $* main: pre test.cc echo main这样Make在读取到
-include hhh.mk时,会先执行pre目标生成文件,不会再去尝试其他隐式规则。方法三:禁用所有隐式规则
执行make时添加-r参数,或在Makefile开头添加MAKEFLAGS += -r,彻底禁用Make的所有默认隐式规则:MAKEFLAGS += -r pre: sh touch.sh -include hhh.mk %.cc: echo $* main: pre test.cc echo main注意:此方法会影响所有依赖默认隐式规则的操作,仅当你不需要默认编译规则时使用。
内容的提问来源于stack exchange,提问作者zcfh
相关产品推荐
相关产品推荐

