代码之家  ›  专栏  ›  技术社区  ›  Cristián Romo

没有规则使目标consoleio.c

  •  1
  • Cristián Romo  · 技术社区  · 16 年前

    在一个 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: *** No rule to make target `consoleio.c', needed by `consoleio.o'.  Stop.

    我不明白的是为什么它要为.c文件寻找一个规则。据我所知,如果文件在那里,就应该使用它。如何使make不需要.c文件规则?

    3 回复  |  直到 16 年前
        1
  •  3
  •   CesarB    16 年前

    如果没有vpath,您所要做的将无法工作,而且由于您仍在学习makefiles,因此我将避免使用vpath。

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

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

    不过,你的做法和我看到的不一样。通常的方法是:

    • 创建一个隐式规则“%.o:%.c”(或在您的情况下“%.o:$(sources)/%.c”)。
    • explicit列出每个文件的依赖项:“foo.o:foo.c bar.h baz.h”(没有命令,隐式规则有命令)
        2
  •  2
  •   Jonathan Leffler    16 年前

    让我们尝试一个无评论的答案…

    可能性A:

    • 您的sfiles宏正在查找以' .s '.
    • 编译sobjs的规则是查找以' .asm '.

    可能性B:

    • 你对sobjs和cobjs的规则是一个我不认识的符号。
    • 根据GNU make手册,您可以将隐式规则编写为:

      %.O: %.C; 命令

    你似乎有一个目标美元(sobjs)的列表,这取决于' %.o : %.asm '. 我不知道Make如何解释这一点。

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

        3
  •  2
  •   JesperE    16 年前

    @塞萨尔似乎已经解决了这个问题,我将添加一些观察结果。

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

    2. 我还建议不要使用vpath,除非您(1)在单独的构建目录中构建,或者(2)将源文件分布在大量目录中。如果所有源都在一个目录中,那么使用vpath只会造成混淆。

    3. :=赋值形式通常只在变量计算需要很长时间时使用,例如使用$(shell…)。否则,首选“=”。

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