没有规则来制作目标consoleio.c

时间:2008-10-19 17:38:08

标签: makefile

recent issue中,我发现DJGPP只能接受DOS命令行字符限制。为了解决这个限制,我决定尝试编写一个makefile来允许我pass longer strings。在将makefile混合在一起并对其进行测试的过程中,我遇到了一个奇怪的错误。 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: *** No rule to make target `consoleio.c', needed by `consoleio.o'.  Stop.

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

3 个答案:

答案 0 :(得分:3)

如果没有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”(没有命令,隐式规则有命令)

答案 1 :(得分:2)

让我们试一下非评论答案......

可能性A:

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

可能性B:

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

    %。o:%。c; 命令

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

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

答案 2 :(得分:2)

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

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

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

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

  4. 使用“export”将OUTDIR传播到concat.py(我认为它是,因为concat.py不接受任何参数)是代码气味。如果可能,请将其作为参数传递。