g++编译C++时Makefile的CFLAGS等编译选项不生效如何解决
问题根因
你的编译选项全程不生效,是几个Makefile写法错误叠出来的:
- 变量适用场景搞混了:
CFLAGS是C编译器的配置变量,g编译C代码时默认读取的编译选项变量是CXXFLAGS,预处理相关选项读CPPFLAGS。另外make不会自动把编译阶段的选项透传给链接阶段,你硬编码写死的链接命令没带变量,自然拿不到配置。 - 模式规则写法完全错误:你写的
%.o: %.cpp %h既没有指定编译执行命令,依赖项里的%h也是非法写法——%作为通配符只能单独出现在段中,%h不会被解析成对应同名的.h头文件,相当于这条规则只声明了依赖,没有任何实际执行逻辑,编译.o的时候走的全是make内置的默认C++编译规则,你看到的-O2是内置规则带的,和你自己配的参数没关系。 - 冗余的
compile伪目标没有任何实际编译逻辑:它只是挂了三个.o文件的依赖,没有绑定任何执行命令,你就算把选项加在这个目标上也不会生效。 - 开头写的
Make: tp2目标完全无效:Makefile默认把第一个出现的目标作为最终构建目标,你写了个叫Make的无意义目标,不会触发正常的构建流程。
修正方案
直接把你的Makefile替换成下面的内容即可:
.PHONY: all clean # C++编译选项统一放在CXXFLAGS中 CXXFLAGS := -O2 -Wall # 第一个目标设为all,作为默认构建入口 all: tp2 # 明确每个目标文件的依赖,头文件依赖写全 coordonnees.o: coordonnees.cpp coordonnees.h personne.o: personne.cpp personne.h tp2.o: tp2.cpp # 链接阶段直接依赖所有需要的.o文件,不需要额外的compile中转目标 tp2: coordonnees.o personne.o tp2.o $(CXX) $(CXXFLAGS) $^ -o $@ clean: rm -rf tp2 *~ *.o
要点说明
- 删掉多余的
compile伪目标即可,make会自动根据依赖关系,先编译所有需要的.o文件,再执行链接动作,不需要手动加中转目标。 - 尽量用make内置变量:
$(CXX)默认就是g++,$^会自动展开成当前目标的所有依赖项(也就是上面列的三个.o文件),$@会自动展开成当前目标名(这里就是tp2),比你硬编码写*.o靠谱,不会把目录下其他无关的.o文件链接进来。 - 后续如果需要加头文件搜索路径、全局宏定义这类预处理参数,单独定义
CPPFLAGS变量即可,编译阶段make会自动把这个变量加到编译命令参数里。
内容的提问来源于stack exchange,提问作者Olivia22
相关产品推荐
相关产品推荐

