【问题标题】:makefile error "No rule to make target" how to solve it?makefile错误“No rule to make target”如何解决?
【发布时间】:2025-12-24 07:10:11
【问题描述】:

我的 makefile 有什么问题?

CC = gcc
OBJS = main.o map.o extended_map.o election.o utilities.o
EXEC = election
DEBUG_FLAG = -DNDEBUG
COMP_FLAG = -std=c99 -Wall -pedantic-errors -Werror

$(EXEC) : $(OBJS)
    $(CC) $(DEBUG_FLAG) $(OBJS) -o $@
main.o: main.c map.h election.h test_utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
map.o: map.c map.h utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
extended_map.o: extended_map.c extended_map.h map.h utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
election.o: election.c election.h map.h extended_map.h utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
utilities.o: utilities.c utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
clean:
    rm -f $(OBJS) $(EXEC)

我在 linux 上运行以下命令:

-bash-4.2$ ls
election.c  extended_map.c  main.c  makefile  mtm_map           utilities.c
election.h  extended_map.h  main.o  map.h     test_utilities.h  utilities.h
-bash-4.2$ make
make: *** No rule to make target `map.c', needed by `map.o'.  Stop.
-bash-4.2$

map.c 存在于当前文件夹内名为mtm_map 的文件夹中

【问题讨论】:

  • makefile 要求 map.c 在当前文件夹中,而不是子目录中。
  • 我已回滚您的编辑。根据服务条款发布您的问题后,在此污损您的问题是不合适的。请不要再这样做了。
  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange (SE) 网络上发帖,您已根据 CC BY-SA license 授予 SE 分发内容的不可撤销权利(即无论您未来的选择如何)。根据 SE 政策,分发非破坏版本。因此,任何破坏行为都将被撤销。请参阅:How does deleting work? …。如果允许删除,则帖子下方左侧有一个“删除”按钮,但仅在浏览器中,而不是移动应用程序中。
  • mod 消息:帖子已锁定。请不要在锁定期后再回滚。

标签: c gcc makefile


【解决方案1】:

您告诉 make 如何从“map.c”构建“map.o”,但您没有“map.c”。你有“mtm_map/map.c”。

你可能想要类似的东西

CC = gcc
OBJS = main.o mtm_map/map.o extended_map.o election.o utilities.o
EXEC = election
DEBUG_FLAG = -DNDEBUG
COMP_FLAG = -std=c99 -Wall -pedantic-errors -Werror

$(EXEC) : $(OBJS)
    $(CC) $(DEBUG_FLAG) $(OBJS) -o $@
main.o: main.c map.h election.h test_utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
mtm_map/map.o: mtm_map/map.c map.h utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
extended_map.o: extended_map.c extended_map.h map.h utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
election.o: election.c election.h map.h extended_map.h utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
utilities.o: utilities.c utilities.h
    $(CC) -c $(DEBUG_FLAG) $(COMP_FLAG) $*.c
clean:
    rm -f $(OBJS) $(EXEC)

【讨论】:

  • 我不知道您所说的更改 $*.c 是什么意思,但是无法通过更改配方的内容来解决您的问题。 Make 不关心配方的内容;它只是将其交给外壳。为了解决您的问题,您必须更改目标和先决条件,如此处所示。
  • @Chad Miller 为您提供了针对您提出的问题的解决方案,并且该解决方案适用于该问题。现在你问了一个不同的问题,这与第一个问题无关。 SO 并非旨在成为“正在运行的教程会话”。它的目的是您首先尝试解决您的问题,然后如果您不能针对该特定问题发布一个问题,描述您尝试过的内容和无效的内容。例如,在您上面的评论中,您说“一个新错误”,但您没有告诉我们哪个源文件无法编译。
  • 您很可能需要将-I$(CURDIR) 添加到您的编译行(COMP_FLAG 变量),以便编译器可以找到您的头文件。
  • 他的代码DID 工作了,你之前遇到的No rule to make target 的问题现在消失了。问题解决了。现在你有一个 new 和不同的问题,这是你的编译失败,因为它找不到头文件。我们无法预见这个新问题,因为它取决于所有源文件的内容以及它们包含的内容以及方式。对于每个包含要包含的头文件的目录,您需要使用一次-I 编译器标志。如果它们都在一个目录中,您只需在该目录中使用一次。
  • 编译器不会在整个系统(甚至当前目录的子目录)中搜索文件。你必须告诉它他们在哪里。
最近更新 更多