课程项目Makefile遇gcc生成.h.gch文件及编译错误问题求助
解决avr-gcc自动生成.h.gch预编译头的问题
首先咱们直接揪出问题的核心:你遇到的编译错误和.h.gch文件自动生成,本质是你的编译命令错误地把.h头文件当成源文件传给了avr-gcc。看你贴的编译命令:
avr-gcc -I. -MMD -g -mmcu=atmega324pa -Os -fpack-struct -fshort-enums -funsigned-bitfields -funsigned-char -Wall -fno-exceptions -c pwm.cpp pwm.h interruptNormal.h
这里把pwm.h和interruptNormal.h作为编译输入了——gcc只要编译.h文件,就会自动生成对应的.h.gch预编译头。而且更糟的是,你用的是avr-gcc(C语言编译器)去编译包含C++class语法的头文件,自然会报语法错误。
接下来给你两个彻底解决的方案,从根源上阻止.h.gch生成:
1. 修复Makefile的编译规则(最优先)
你的.o生成规则里用了$^,这个变量代表所有依赖文件。如果通过-MMD生成的依赖文件(.d)被包含进Makefile后,.o的依赖会自动加上它引用的.h文件,此时$^就会把.cpp和.h一起传给gcc,导致编译.h文件。
把规则里的$^改成$<(代表第一个依赖文件,也就是对应的.cpp源文件):
%.o: %.cpp $(CC) $(CFLAGS) $(CXXFLAGS) -c $<
这样编译命令只会处理.cpp文件,根本不会碰.h,自然就不会生成.h.gch了。
另外,注意你用的是$(CC)(默认是C编译器avr-gcc),但你的代码是C++(有class、继承语法),建议把编译器换成avr-g++,避免C/C++编译模式混淆的问题——可以在Makefile开头加CC=avr-g++。
2. 直接禁用预编译头功能(兜底方案)
如果担心后续还有其他情况触发预编译头生成,可以给编译选项加上-fno-precompiled-headers,彻底禁用gcc的预编译头功能:
CFLAGS += -fno-precompiled-headers
这样不管有没有误传.h文件,gcc都不会生成.h.gch文件。
最后,先执行make clean删掉已有的.h.gch和错误的.o文件,再重新编译,问题就彻底解决了。
内容的提问来源于stack exchange,提问作者qwerty_99




