不知什么原因,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.
最佳答案
问题在于以下规则:
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',我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47552127/