【问题标题】:No rule to make target '%.o'没有规则使目标'%.o'
【发布时间】:2017-11-29 11:49:36
【问题描述】:

不知为何,GNU Make 无法为我完成这项工作。我有这个 MAKE 文件,我确实确保每个食谱都使用制表符,而不是空格。但是我看着它,我只是找不到任何会导致错误消息的地方。

操作系统:Ubuntu 17.10 / GNU Make:4.1 / GCC:交叉编译到 i686-elf-gcc。

运行它:make(在同一目录中)给我

make: *** No rule to make target '%.o', needed by 'kernel.elf'.  Stop.

我有一个 bash 脚本,它做的事情完全一样,而且它的作用就像魅力一样。谁能告诉我我做错了什么?

生成文件:

NASM=nasm
QEMU=qemu-system-i386
GCC=~/opt/cross/bin/i686-elf-gcc
CFLAGS=-std=c11 -ffreestanding -Wall -Wextra -Werror -masm=intel -g -O0
ASFLAGS=-felf32 -g

.PHONY: all clean
all:boot.iso

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

%.so : %.asm
    $(NASM) $(ASFLAGS) -o $@ $<

kernel.elf : %.o
    $(GCC) -T link.ld -o $@ -ffreestanding -O0 -nostdlib -lgcc --verbose $^
    grub-file --is-x86-multiboot2 kernel.elf

boot.iso : kernel.elf grub.cfg
    mkdir -p ./iso/boot/grub
    cp kernel.elf ./iso/boot
    cp grub.cfg ./iso/boot/grub
    grub-mkrescue -o $@ ./iso

run: boot.iso
    $(QEMU) -cdrom $< -D log/qemu.log -d guest_errors -m 2048M -daemonize -serial file:log/boot.log

debug: boot.iso
    $(QEMU) -cdrom $< -D log/qemu.log -d guest_errors -m 2048M -daemonize -serial file:log/boot.log -s -S
    gdb ./kernel.elf -ex "target remote :1234" --tui

clean:
    rm -f ./*.o
    rm -f ./kernel.elf
    rm -rf ./iso

使用 -d 选项运行 make 输出:

GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
 Considering target file 'Makefile'.
  Looking for an implicit rule for 'Makefile'.

  ... a bunch of ...
  Trying pattern rule with stem 'Makefile'.
  Trying implicit prerequisite 'Makefile.o'. <-- last line
  ... end a bunch of ...

  Looking for a rule with intermediate file 'Makefile.o'.
   Avoiding implicit rule recursion.

   ... a bunch of ...
   Trying pattern rule with stem 'Makefile'.
   Trying implicit prerequisite 'Makefile.c'. <--- last line
   ... end a bunch of ...

   Looking for a rule with intermediate file 'Makefile.c'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.

    ... a bunch of ...
    Trying pattern rule with stem 'Makefile'.
    Trying implicit prerequisite 'Makefile.y'.
    ... end a bunch of ...

    Looking for a rule with intermediate file 'Makefile.y'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.

     ... a bunch of ...
     Trying pattern rule with stem 'Makefile.y'.
     Trying implicit prerequisite 'SCCS/s.Makefile.y'. <-- last line
     ... end a bunch of ...
     ... I'm too tired to clean it up ....
     ... is all the same thing for Makefile

Updating goal targets....
Considering target file 'all'.
 File 'all' does not exist.
  Considering target file 'boot.iso'.
   File 'boot.iso' does not exist.
    Considering target file 'kernel.elf'.
     File 'kernel.elf' does not exist.
      Considering target file '%.o'.
       File '%.o' does not exist.
       Looking for an implicit rule for '%.o'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.c'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.cc'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.C'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.cpp'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.p'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.f'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.F'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.m'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.r'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.s'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.S'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.mod'.
       Trying pattern rule with stem '%.o'.
       Trying implicit prerequisite '%.o,v'.
       Trying pattern rule with stem '%.o'.
       Trying implicit prerequisite 'RCS/%.o,v'.
       Trying pattern rule with stem '%.o'.
       Trying implicit prerequisite 'RCS/%.o'.
       Trying pattern rule with stem '%.o'.
       Trying implicit prerequisite 's.%.o'.
       Trying pattern rule with stem '%.o'.
       Trying implicit prerequisite 'SCCS/s.%.o'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.c'.
       Looking for a rule with intermediate file '%.c'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.y'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.l'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.w'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.w'.
        Trying pattern rule with stem '%.c'.
        Trying implicit prerequisite '%.c,v'.
        Trying pattern rule with stem '%.c'.
        Trying implicit prerequisite 'RCS/%.c,v'.
        Trying pattern rule with stem '%.c'.
        Trying implicit prerequisite 'RCS/%.c'.
        Trying pattern rule with stem '%.c'.
        Trying implicit prerequisite 's.%.c'.
        Trying pattern rule with stem '%.c'.
        Trying implicit prerequisite 'SCCS/s.%.c'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.y'.
        Looking for a rule with intermediate file '%.y'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%.y'.
         Trying implicit prerequisite '%.y,v'.
         Trying pattern rule with stem '%.y'.
         Trying implicit prerequisite 'RCS/%.y,v'.
         Trying pattern rule with stem '%.y'.
         Trying implicit prerequisite 'RCS/%.y'.
         Trying pattern rule with stem '%.y'.
         Trying implicit prerequisite 's.%.y'.
         Trying pattern rule with stem '%.y'.
         Trying implicit prerequisite 'SCCS/s.%.y'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.l'.
        Looking for a rule with intermediate file '%.l'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%.l'.
         Trying implicit prerequisite '%.l,v'.
         Trying pattern rule with stem '%.l'.
         Trying implicit prerequisite 'RCS/%.l,v'.
         Trying pattern rule with stem '%.l'.
         Trying implicit prerequisite 'RCS/%.l'.
         Trying pattern rule with stem '%.l'.
         Trying implicit prerequisite 's.%.l'.
         Trying pattern rule with stem '%.l'.
         Trying implicit prerequisite 'SCCS/s.%.l'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.w'.
        Looking for a rule with intermediate file '%.w'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%.w'.
         Trying implicit prerequisite '%.w,v'.
         Trying pattern rule with stem '%.w'.
         Trying implicit prerequisite 'RCS/%.w,v'.
         Trying pattern rule with stem '%.w'.
         Trying implicit prerequisite 'RCS/%.w'.
         Trying pattern rule with stem '%.w'.
         Trying implicit prerequisite 's.%.w'.
         Trying pattern rule with stem '%.w'.
         Trying implicit prerequisite 'SCCS/s.%.w'.
        Trying pattern rule with stem '%'.
        Rejecting impossible rule prerequisite '%.w'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.cc'.
       Looking for a rule with intermediate file '%.cc'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%.cc'.
        Trying implicit prerequisite '%.cc,v'.
        Trying pattern rule with stem '%.cc'.
        Trying implicit prerequisite 'RCS/%.cc,v'.
        Trying pattern rule with stem '%.cc'.
        Trying implicit prerequisite 'RCS/%.cc'.
        Trying pattern rule with stem '%.cc'.
        Trying implicit prerequisite 's.%.cc'.
        Trying pattern rule with stem '%.cc'.
        Trying implicit prerequisite 'SCCS/s.%.cc'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.C'.
       Looking for a rule with intermediate file '%.C'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%.C'.
        Trying implicit prerequisite '%.C,v'.
        Trying pattern rule with stem '%.C'.
        Trying implicit prerequisite 'RCS/%.C,v'.
        Trying pattern rule with stem '%.C'.
        Trying implicit prerequisite 'RCS/%.C'.
        Trying pattern rule with stem '%.C'.
        Trying implicit prerequisite 's.%.C'.
        Trying pattern rule with stem '%.C'.
        Trying implicit prerequisite 'SCCS/s.%.C'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.cpp'.
       Looking for a rule with intermediate file '%.cpp'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%.cpp'.
        Trying implicit prerequisite '%.cpp,v'.
        Trying pattern rule with stem '%.cpp'.
        Trying implicit prerequisite 'RCS/%.cpp,v'.
        Trying pattern rule with stem '%.cpp'.
        Trying implicit prerequisite 'RCS/%.cpp'.
        Trying pattern rule with stem '%.cpp'.
        Trying implicit prerequisite 's.%.cpp'.
        Trying pattern rule with stem '%.cpp'.
        Trying implicit prerequisite 'SCCS/s.%.cpp'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.p'.
       Looking for a rule with intermediate file '%.p'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.web'.
        Trying pattern rule with stem '%.p'.
        Trying implicit prerequisite '%.p,v'.
        Trying pattern rule with stem '%.p'.
        Trying implicit prerequisite 'RCS/%.p,v'.
        Trying pattern rule with stem '%.p'.
        Trying implicit prerequisite 'RCS/%.p'.
        Trying pattern rule with stem '%.p'.
        Trying implicit prerequisite 's.%.p'.
        Trying pattern rule with stem '%.p'.
        Trying implicit prerequisite 'SCCS/s.%.p'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.web'.
        Looking for a rule with intermediate file '%.web'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%.web'.
         Trying implicit prerequisite '%.web,v'.
         Trying pattern rule with stem '%.web'.
         Trying implicit prerequisite 'RCS/%.web,v'.
         Trying pattern rule with stem '%.web'.
         Trying implicit prerequisite 'RCS/%.web'.
         Trying pattern rule with stem '%.web'.
         Trying implicit prerequisite 's.%.web'.
         Trying pattern rule with stem '%.web'.
         Trying implicit prerequisite 'SCCS/s.%.web'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.f'.
       Looking for a rule with intermediate file '%.f'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.F'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.r'.
        Trying pattern rule with stem '%.f'.
        Trying implicit prerequisite '%.f,v'.
        Trying pattern rule with stem '%.f'.
        Trying implicit prerequisite 'RCS/%.f,v'.
        Trying pattern rule with stem '%.f'.
        Trying implicit prerequisite 'RCS/%.f'.
        Trying pattern rule with stem '%.f'.
        Trying implicit prerequisite 's.%.f'.
        Trying pattern rule with stem '%.f'.
        Trying implicit prerequisite 'SCCS/s.%.f'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.F'.
        Looking for a rule with intermediate file '%.F'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%.F'.
         Trying implicit prerequisite '%.F,v'.
         Trying pattern rule with stem '%.F'.
         Trying implicit prerequisite 'RCS/%.F,v'.
         Trying pattern rule with stem '%.F'.
         Trying implicit prerequisite 'RCS/%.F'.
         Trying pattern rule with stem '%.F'.
         Trying implicit prerequisite 's.%.F'.
         Trying pattern rule with stem '%.F'.
         Trying implicit prerequisite 'SCCS/s.%.F'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.r'.
        Looking for a rule with intermediate file '%.r'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%'.
         Rejecting impossible rule prerequisite '%.l'.
         Trying pattern rule with stem '%.r'.
         Trying implicit prerequisite '%.r,v'.
         Trying pattern rule with stem '%.r'.
         Trying implicit prerequisite 'RCS/%.r,v'.
         Trying pattern rule with stem '%.r'.
         Trying implicit prerequisite 'RCS/%.r'.
         Trying pattern rule with stem '%.r'.
         Trying implicit prerequisite 's.%.r'.
         Trying pattern rule with stem '%.r'.
         Trying implicit prerequisite 'SCCS/s.%.r'.
       Trying pattern rule with stem '%'.
       Rejecting impossible rule prerequisite '%.F'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.m'.
       Looking for a rule with intermediate file '%.m'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.ym'.
        Trying pattern rule with stem '%.m'.
        Trying implicit prerequisite '%.m,v'.
        Trying pattern rule with stem '%.m'.
        Trying implicit prerequisite 'RCS/%.m,v'.
        Trying pattern rule with stem '%.m'.
        Trying implicit prerequisite 'RCS/%.m'.
        Trying pattern rule with stem '%.m'.
        Trying implicit prerequisite 's.%.m'.
        Trying pattern rule with stem '%.m'.
        Trying implicit prerequisite 'SCCS/s.%.m'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.ym'.
        Looking for a rule with intermediate file '%.ym'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%.ym'.
         Trying implicit prerequisite '%.ym,v'.
         Trying pattern rule with stem '%.ym'.
         Trying implicit prerequisite 'RCS/%.ym,v'.
         Trying pattern rule with stem '%.ym'.
         Trying implicit prerequisite 'RCS/%.ym'.
         Trying pattern rule with stem '%.ym'.
         Trying implicit prerequisite 's.%.ym'.
         Trying pattern rule with stem '%.ym'.
         Trying implicit prerequisite 'SCCS/s.%.ym'.
       Trying pattern rule with stem '%'.
       Rejecting impossible rule prerequisite '%.r'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.s'.
       Looking for a rule with intermediate file '%.s'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.S'.
        Trying pattern rule with stem '%.s'.
        Trying implicit prerequisite '%.s,v'.
        Trying pattern rule with stem '%.s'.
        Trying implicit prerequisite 'RCS/%.s,v'.
        Trying pattern rule with stem '%.s'.
        Trying implicit prerequisite 'RCS/%.s'.
        Trying pattern rule with stem '%.s'.
        Trying implicit prerequisite 's.%.s'.
        Trying pattern rule with stem '%.s'.
        Trying implicit prerequisite 'SCCS/s.%.s'.
        Trying pattern rule with stem '%'.
        Trying rule prerequisite '%.S'.
        Looking for a rule with intermediate file '%.S'.
         Avoiding implicit rule recursion.
         Avoiding implicit rule recursion.
         Trying pattern rule with stem '%.S'.
         Trying implicit prerequisite '%.S,v'.
         Trying pattern rule with stem '%.S'.
         Trying implicit prerequisite 'RCS/%.S,v'.
         Trying pattern rule with stem '%.S'.
         Trying implicit prerequisite 'RCS/%.S'.
         Trying pattern rule with stem '%.S'.
         Trying implicit prerequisite 's.%.S'.
         Trying pattern rule with stem '%.S'.
         Trying implicit prerequisite 'SCCS/s.%.S'.
       Trying pattern rule with stem '%'.
       Rejecting impossible rule prerequisite '%.S'.
       Trying pattern rule with stem '%'.
       Trying rule prerequisite '%.mod'.
       Looking for a rule with intermediate file '%.mod'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem '%.mod'.
        Trying implicit prerequisite '%.mod,v'.
        Trying pattern rule with stem '%.mod'.
        Trying implicit prerequisite 'RCS/%.mod,v'.
        Trying pattern rule with stem '%.mod'.
        Trying implicit prerequisite 'RCS/%.mod'.
        Trying pattern rule with stem '%.mod'.
        Trying implicit prerequisite 's.%.mod'.
        Trying pattern rule with stem '%.mod'.
        Trying implicit prerequisite 'SCCS/s.%.mod'.
       No implicit rule found for '%.o'.
       Finished prerequisites of target file '%.o'.
      Must remake target '%.o'.
make: *** No rule to make target '%.o', needed by 'kernel.elf'.  Stop.

【问题讨论】:

  • $(GCC) -c $&lt; $(CFLAGS) -o $@ -->> $(GCC) $(CFLAGS) $&lt; -o $@
  • 我认为您需要删除冒号前的空格。不过不确定。
  • @Gaurav,我尝试了你的建议,但没有成功...
  • 我认为问题在于kernel.elf : %.o 这一行,即生成kernel.elf 的规则。 Make 寻找目标%.o,但由于它是通用的,它不知道要使用哪些文件。如果您使用kernel.elf : kernel.o 或任何您实际需要制作内核的.o-files,它应该可以工作。 (下面同时回答)
  • 另见How to place object files in separate subdirectory 和How to make specific binary from specific object file?,其中的答案似乎告诉您对目标文件使用通配符。也许 GNU Make 不理解 kernel.elf 中的 *.elf 扩展。

标签: c linux makefile gnu-make


【解决方案1】:

问题出在以下规则中:

kernel.elf : %.o

GNU Make 实际上将%.o 视为先决条件,而不是模式。

我建议您定义一个包含目标文件名称的obj 变量并将规则重写为:

kernel.elf: $(obj)

这种obj 变量的定义可以是:

obj := $(patsubst %.c,%.o,$(wildcard *.c))
obj += $(patsubst %.asm,%.so,$(wildcard *.asm))

【讨论】:

  • 有效!非常感谢!我整晚都在挠头!
  • 不应该是先决条件吗?否则,当 %.c 更新时,它如何知道编译适当的 .o 目标?
  • @Assimilater 我的意思是原来的先决条件字面上是%.o(即一个名为%.o的文件,不是一个模式对于.o 文件)。通过我的方法,$(obj) 扩展产生的文件列表成为kernel.elf 的先决条件。此列表由.o 文件组成,当它们对应的.c 更新时,将使用OP 的规则%.o: %.c。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 2012-02-20
  • 2014-11-04
  • 2013-06-14
相关资源
最近更新 更多