You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

src目录下多.cpp/.h文件Makefile构建报错,如何修正?

解决Makefile找不到源文件的问题

你遇到的错误提示很明确:

make: *** No rule to make target 'answer.cpp', needed by 'answer.o'. Stop.

这是因为你手动编写的单个目标依赖规则里,没有给源文件加上src/前缀,make会默认在当前目录找answer.cpp,但你的文件都在src目录下,自然找不到。结合你的需求(给src目录下的.cpp和.h写Makefile),我给你整理了具体的修改方案:

你的现有Makefile代码

CXX=g++ LD=g++ CXXFLAGS=-Wall -pedantic -std=c++14 -Wno-long-long -O0 -ggdb LDLIBS=-lncurses SRCDIR=src OBJECTS=answer.o handler.o main.o question.o quiz.o ui.o uiCreateQuiz.o uiImportExport.o uiPrinter.o uiSolveQuiz.o all: quiz run compile: quiz quiz: $(OBJECTS) $(LD) $^ $(LDLIBS) -o $@ %.o: $(SRCDIR)/%.cpp $(SRCDIR)/%.h $(CXX) $(CXXFLAGS) $(LDFLAGS) -c -o $@ $< run: valgrind ./quiz clean: rm -f $(OBJECTS) quiz answer.o: answer.cpp answer.h handler.o: handler.cpp handler.h quiz.h question.h answer.h main.o: main.cpp ui.h handler.h quiz.h question.h answer.h uiPrinter.h uiSolveQuiz.h uiCreateQuiz.h uiImportExport.h question.o: question.cpp question.h answer.h quiz.o: quiz.cpp quiz.h question.h answer.h ui.o: ui.cpp ui.h handler.h quiz.h question.h answer.h uiPrinter.h uiSolveQuiz.h uiCreateQuiz.h uiImportExport.h uiCreateQuiz.o: uiCreateQuiz.cpp uiCreateQuiz.h handler.h quiz.h question.h answer.h uiPrinter.h uiImportExport.o: uiImportExport.cpp uiImportExport.h handler.h quiz.h question.h answer.h uiPrinter.h uiPrinter.o: uiPrinter.cpp uiPrinter.h uiSolveQuiz.o: uiSolveQuiz.cpp uiSolveQuiz.h handler.h quiz.h question.h answer.h uiPrinter.h

具体修改步骤

  1. 删除所有手动编写的单个目标依赖规则
    你已经写了通用的模式规则%.o: $(SRCDIR)/%.cpp $(SRCDIR)/%.h,它会自动匹配src目录下的所有.cpp和对应的.h文件生成.o文件。但后面那些answer.o: answer.cpp answer.h之类的手动规则,会覆盖模式规则,而且没有加src/前缀,导致路径错误。把这些逐个写的依赖规则全部删掉就好。

  2. 优化模式规则(适配无对应.h的源文件)
    有些源文件比如main.cpp可能没有对应的main.h,原来的模式规则要求必须有.h文件才能编译,这会出问题。可以把模式规则拆成两部分:

    %.o: $(SRCDIR)/%.cpp
        $(CXX) $(CXXFLAGS) -c -o $@ $<
    # 可选:确保头文件更新时重新编译对应的.o
    %.o: $(SRCDIR)/%.h
    

    更省心的方式是用-MMD参数自动生成头文件依赖:
    修改CXXFLAGS,加上-MMD,然后在Makefile末尾添加-include $(OBJECTS:.o=.d),这样make会自动为每个.o生成.d文件,里面包含正确的头文件依赖,不用你手动维护。

  3. (可选)调整run目标
    如果valgrind不是每次运行都需要,可以简化run目标;如果需要保留,确保你的系统已经安装了valgrind:

    run: quiz
        ./quiz
    

修改后的完整Makefile示例

CXX=g++
LD=g++
CXXFLAGS=-Wall -pedantic -std=c++14 -Wno-long-long -O0 -ggdb -MMD
LDLIBS=-lncurses
SRCDIR=src
OBJECTS=answer.o handler.o main.o question.o quiz.o ui.o uiCreateQuiz.o uiImportExport.o uiPrinter.o uiSolveQuiz.o

all: quiz

run: quiz
    ./quiz

compile: quiz

quiz: $(OBJECTS)
    $(LD) $^ $(LDLIBS) -o $@

%.o: $(SRCDIR)/%.cpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

clean:
    rm -f $(OBJECTS) quiz $(OBJECTS:.o=.d)

# 自动包含生成的头文件依赖
-include $(OBJECTS:.o=.d)

这个版本的Makefile会自动从src目录读取所有源文件,自动处理头文件依赖,不会再出现找不到目标文件的错误。

内容的提问来源于stack exchange,提问作者skluzada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:09:10