gaddin
gaddin

Reputation: 3

Make doesn't make target correctly

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

Answers (1)

Andreas
Andreas

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

Related Questions