Reputation: 3
I am currently trying to automate my build system but for some odd reason Make gives me an error message:
make: *** No rule to make target 'tmpd/%.o', needed by 'tmpd/kernel.bin'. Stop.
I made sure that the Target $(TMP_D)%.o: is layed out correct and the dependencies seem to be right aswell but i still can't wrap my head around this. I've searched the Internet for a solution but i kinda just found the "you might have a typo or the file doesn't exist" thing. here is a listing of the files inside the dependency directories:
$ ls -R
.:
boot build kernel link.ld Makefile README.md Run tmpd
./boot:
boot.asm kernel_entry.c link.ld run.sh tmp.s tmpVga.s
./build:
./kernel:
drivers utils
./kernel/drivers:
VGA.c VGA.h
./kernel/utils:
cpu.c cpu.h hwio.c hwio.h
./tmpd:
boot.bin
build/:
kernel/:
drivers utils
kernel/drivers/:
VGA.c VGA.h
kernel/utils/:
cpu.c cpu.h hwio.c hwio.h
Here is my Makefile:
CC=/usr/local/x86_64elfgcc/bin/x86_64-elf-gcc
LD=/usr/local/x86_64elfgcc/bin/x86_64-elf-ld
KERNEL_FLAGS=-nostdlib -ffreestanding -Wall
LD_FLAGS=-m elf_i386 -o kernel.bin -Tlink.ld $(TMP_D)%.o
TMP_D=tmpd/
BUILD_D=build/
BOOT_D=boot/
DRIVER_D=kernel/drivers/
UTILS_D=kernel/utils/
KERNEL_SRC=$(UTILS_D)%.c $(DRIVER_D)%.c $(BOOT_D)kernel_entry.c
# **BUILD**
setup:
mkdir $(TMP_D)
all: $(BUILD_D)kernel.iso
@echo -e "making tmp dir\n\n"
mkdir $(TMP_D)
$(BUILD_D)kernel.iso: $(TMP_D)kernel.elf
@echo -e "creating iso\n\n"
sudo dd if=/dev/zero of=$@ bs=512 count=2880
sudo dd if=$^ of=$@ conv=notrunc bs=512 count=2048
$(TMP_D)kernel.elf: $(TMP_D)boot.bin $(TMP_D)kernel.bin
@echo -e "concatenating kernel with bootloader\n\n"
cat $^ > $@
$(TMP_D)boot.bin: $(BOOT_D)boot.asm
@echo -e "assembly\n\n"
nasm -f bin $^ -o $@
$(TMP_D)kernel.bin: $(TMP_D)%.o
@echo -e "kernel linkage\n\n"
$(LD)$(LD_FLAGS) -o $@
$(TMP_D)%.o: $(KERNEL_SRC)
@echo -e "compiling kernel\n\n"
$(CC) $^ $(KERNEL_FLAGS) -o $@
clean:
@echo -e "cleaing up!\n\n"
rm -rf $(TMP_D)
qemu: $(BUILD_D)kernel.iso
qemu-system-x86_64 kernel.iso -m 512 -enable-kvm -vga virtio -monitor stdio
I understand that this is much to look into and I am sorry but I am kinda desperate. An answer that explains this problem would be really appreciated. It could also be that I am just blind and the reason for the error is right in front of me.
Upvotes: 0
Views: 78
Reputation: 5301
Use of pattern in prerequiste makes no sense if the target has no pattern:
$(TMP_D)kernel.bin: $(TMP_D)%.o
Without it Make will try find the file named $(TMP_D)%.o, and when not found try find a recipe to make it, and finnally return the error you're looking at because no such recipe exists.
Patterns are only used in targets and prerequsites, so this makes no sense:
LD_FLAGS=-m elf_i386 -o kernel.bin -Tlink.ld $(TMP_D)%.o
It also makes no sense passing the output file name in the LD_FLAGS variable.
Overall there is little that makes sense in the makefile presented. Perhaps better start over from a single sequential script/recipe, then extract common elements into variables, recipes, and patterns.
Upvotes: 1