【问题标题】:No rule to make target consoleio.c没有规则来制作目标 consoleio.c
【发布时间】:2008-10-19 17:38:08
【问题描述】:

recent issue 中,我发现DJGPP 只能接受DOS 命令行字符限制。为了解决这个限制,我决定尝试编写一个makefile 来允许我pass longer strings。在编写一个makefile并对其进行测试的过程中,我遇到了一个奇怪的错误。生成文件如下:

AS  :=  nasm
CC  :=  gcc
LD  :=  ld

TARGET      :=  $(shell basename $(CURDIR))
BUILD       :=  build
SOURCES     :=  source

CFLAGS  :=  -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
            -nostdinc -fno-builtin -I./include
ASFLAGS :=  -f aout

export OUTPUT   :=  $(CURDIR)/$(TARGET)

CFILES      :=  $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES      :=  $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))

SOBJS   :=  $(SFILES:.s=.o)
COBJS   :=  $(CFILES:.c=.o)
OBJS    :=  $(SOBJS) $(COBJS)

build   :   $(TARGET).img

$(TARGET).img   :   $(TARGET).bin
    concat.py

$(TARGET).bin   :   $(OBJS)
    $(LD) -T link.ld -o $@ $^

$(SOBJS)    :   %.o :   %.asm
    $(AS) $(ASFLAGS) $< -o $@

$(COBJS)    :   %.o :   %.c
    $(CC) -c $< $(CFLAGS) -o $@

在尝试运行它时,我收到此错误:

make: *** 没有规则来制作目标 `consoleio.c',`consoleio.o' 需要。停止。

我不明白为什么它试图为 .c 文件寻找规则。据我了解,如果文件在那里,它应该只使用它。如何使 .c 文件不需要规则?

【问题讨论】:

  • (a) 是什么让您认为 makefile 可以绕过命令行限制? (b) consoleio.o 的源文件是什么? (c) 用汇编编码是不是有点古怪?
  • 继续:(d) 您使用 := 分配的目标是哪个版本的“make”?这是一个非标准的符号。
  • (a)delorie.com/djgpp/v2faq/faq16_4.html (b) consoleio.c (c) 它用于多重引导头文件,仅此而已。
  • 并且,为了保持一致性:$(shell ...) 和 $(foreach ...) 等符号也是非标准的。在这种情况下,标准是指 POSIX 标准。我相信您可能针对的是 GNU Make,但请注意,有许多 make 变体可供选择。
  • 是的,我正在使用 GNU 扩展。我不知道makefile,但我知道的很多。

标签: makefile


【解决方案1】:

如果没有 VPATH,您正在尝试做的事情将无法工作,并且由于您仍在学习 makefile,因此我会避免使用 VPATH。

规则正在寻找“consoleio.c”,如果我正确理解您的 makefile 不存在;存在的是“source/consoleio.c”。您可能应该将其更改为“$(SOURCES)/%.c”而不是“%c”。

但是,我没有检查您的语法是否符合该规则。如果不正确,将使用内置的 "%.o: %.c" 规则,这将有同样的问题。

但是,您的做法与我所见过的不同。通常的方法是:

  • 创建隐式规则“%.o: %.c”(或在您的情况下为“%.o: $(SOURCES)/%.c”)
  • 显式列出每个文件的依赖关系:“foo.o: foo.c bar.h baz.h”(没有命令,隐式规则有命令)

【讨论】:

  • 我什至不知道 VPATH 是什么,所以我可能不应该使用它。这就是我不知道如何编写 makefile 的结果......
  • 很多人不知道如何编写makefile,这并不丢人。幸运的是,有 automake、autoconf 等。 :-) 省去了很多麻烦。
【解决方案2】:

让我们尝试一个不评论的答案...

可能性A:

  • 您的 SFILES 宏正在查找以“.s”结尾的文件。
  • 您编译 SOBJS 的规则是查找以“.asm”结尾的文件。

可能性 B:

  • 您对 SOBJS 和 COBJS 的规则是我不认识的符号。
  • 根据 GNU Make 手册,您可以将隐式规则编写为:

    %.o : %.c ; 命令

您似乎有一个依赖于“%.o : %.asm”的目标 $(SOBJS) 列表。 我不确定 make 会如何解释它。

就我个人而言,我不会相信构建规则中的通配符。我宁愿花时间准确列出构建代码所需的源文件。因此,我并不经常遇到这个问题。

【讨论】:

    【解决方案3】:

    @CesarB 似乎已经解决了这个问题,我将补充几点意见。

    1. 我强烈建议不要在构建规则中使用通配符。构建规则应该清楚地定义要构建的内容,而不是依赖于目录中的文件。

    2. 我还建议不要使用 VPATH,除非您 (1) 在单独的构建目录中构建,或者 (2) 将源文件分布在大量目录中。如果您所有的源代码都在一个目录中,那么使用 VPATH 只会让人感到困惑。

    3. := 赋值形式通常仅在已知变量求值需要很长时间时使用,例如在使用 $(shell ...) 时。否则,最好使用“=”。

    4. 使用“export”将 OUTDIR 传播到 concat.py(我认为是这样,因为 concat.py 不带任何参数)是一种代码异味。如果可能,请将其作为参数传递。

    【讨论】:

    • 是的,concat.py 需要修改。它是一时兴起将特定文件拼凑起来的,所以我将在不久的将来修复它。
    猜你喜欢
    • 2013-04-11
    • 2014-03-10
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多