Makefile自动生成依赖报undefined reference to `main'(混合conda通道)
Makefile自动依赖生成报错问题排查
问题描述
在为Makefile配置自动依赖生成功能时,期望实现修改头文件后对应编译单元自动重新编译,当前配置仅能识别源文件改动。运行最小可复现示例时输出undefined reference to 'main'报错,将编译步骤中的DEPFILES变量移除后代码即可编译成功。
相关代码
Makefile
CC = g++ EXEC = v1_beam.exe RM = rm -f BASEDIR := $(shell pwd) SRCDIR := src INCDIR := include DEPDIR := .deps DEPFLAGS = -M -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d DEBUG_LEVEL := -g -fdiagnostics-color=always EXTRA_CCFLAGS := -Wall -std=c++17 -O -pedantic -pedantic-errors CXXFLAGS = $(DEBUG_LEVEL) $(EXTRA_CCFLAGS) CCFLAGS = $(CXXFLAGS) SRCS := $(wildcard *.cc) \ $(wildcard $(SRCDIR)/*.cc) OBJS := $(patsubst %.cc, %.o, $(SRCS)) DEPFILES := $(patsubst %.cc, $(DEPDIR)/%.d, $(notdir $(SRCS))) .PHONY: all clean .DEFAULT_GOAL = all all: $(DEPDIR) $(EXEC) $(EXEC): $(OBJS) @echo 3 @echo Dependencies: $(wildcard $(DEPFILES)) $(CC) $(CCFLAGS) $^ -o $@ @echo Executable $(EXEC) created. %.o: %.cc %.o: %.cc Makefile @echo 1 $(CC) $(DEPFLAGS) $(CCFLAGS) -c $< -I$(BASEDIR) -o $@ $(SRCDIR)/%.o: $(SRCDIR)/%.cc $(DEPDIR)/%.d | $(DEPDIR) @echo 2 $(CC) $(DEPFLAGS) $(CCFLAGS) -c $< -I$(BASEDIR) -o $@ $(DEPDIR): mkdir -p $@ $(DEPFILES): clean: $(RM) $(OBJS) $(EXEC) include $(wildcard $(DEPFILES))
main.cc
#include <iostream> #include "include/dummy.h" int main() { MyClass obj; obj.print(); return 0; }
include/dummy.h
#ifndef DUMMY #define DUMMY #include <iostream> class MyClass { MyClass() { std::cout << "constructor" << std::endl; } void print(); }; #endif
src/dummy.cc
#include "include/dummy.h" void MyClass::print() { std::cout << "print" << std::endl; }
排查结论与解决方案
- Makefile配置优化建议:使用
-include替代原配置中的include,可避免首次干净编译时依赖文件尚未生成导致的报错。 - 问题根本原因:使用的conda环境同时混合了default和conda-forge两个通道的软件包。
- 验证方法:执行以下命令查询gcc、编译器相关包的来源通道,确认是否存在多通道混合情况:
conda list | grep gcc conda list | grep compiler
- 修复方案:执行以下命令,确保所有使用的软件包均来自conda-forge通道:
conda upgrade -c conda-forge --all
内容的提问来源于stack exchange,提问作者unvarnished
相关产品推荐
相关产品推荐

