Makefile仅使用wildcard首个条目编译.o文件的解决方法
问题根因
你当前写的目标文件编译规则存在逻辑错误:
$(OBJECTS): $(SOURCES)
这行写法会让每一个.o目标文件都依赖全部的.cpp源文件,Make展开后实际等价于:
bin/obj/main.o: src/main.cpp src/random_graph.cpp src/word_graph.cpp bin/obj/random_graph.o: src/main.cpp src/random_graph.cpp src/word_graph.cpp bin/obj/word_graph.o: src/main.cpp src/random_graph.cpp src/word_graph.cpp
而编译命令里用的$<是自动变量,只会取依赖列表的第一个文件,也就是排序最靠前的src/main.cpp,因此不管编译哪个.o目标,输入永远是main.cpp,最终生成三份完全相同的目标文件。
修复方案
把原有的批量生成.o的规则替换为模式匹配规则,实现源文件到目标文件的一一对应绑定即可:
# 模式规则:obj目录下的%.o 对应 src目录下的同名%.cpp $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp mkdir -p $(@D) $(CXX) $(CXXFLAGS) -I$(ICD_DIR) -c $< -o $@
注:你配置里定义了
ICD_DIR头文件目录,编译时记得加-I$(ICD_DIR)参数引入头文件搜索路径,避免编译时找不到自定义头文件报错。
规则逻辑说明
- 模式规则中的
%是通配符,会自动匹配文件名的公共部分,比如匹配目标bin/obj/random_graph.o时,会自动定位到对应的依赖文件src/random_graph.cpp,实现一一对应 - 此时
$<会正确读取当前目标对应的单个cpp源文件,不会再固定取第一个源文件 $(@D)是Make内置自动变量,代表当前目标文件的所在目录,mkdir -p会在编译前自动创建不存在的obj目录,避免路径不存在报错
内容的提问来源于stack exchange,提问作者hellohelo
相关产品推荐
相关产品推荐

