Search code examples
makefile

Makefile Doesn't Recompile File After Source Changes


I am writing a small OS, but when I try to edit the stage1 bootloader source file it doesn't get recompiled. Here is the main Makefile:

# Tools
ASM = nasm

# Directories
SRC_DIR = src
TARGET_DIR = build
TARGET = $(TARGET_DIR)/OS.img
OBJ_DIR = $(TARGET_DIR)/obj

.PHONY: all image bootloader run clean 

all: image

image: $(TARGET)

$(TARGET): $(TARGET_DIR) bootloader
    
bootloader: stage1 stage2

stage1: $(TARGET_DIR)/bl_stage1.bin
$(TARGET_DIR)/bl_stage1.bin:
    @echo "Building bl_stage1.bin"
    $(MAKE) -C $(SRC_DIR)/bootloader/stage1 TARGET_DIR=$(abspath $(TARGET_DIR))

stage2: $(TARGET_DIR)/bl_stage2.bin
$(TARGET_DIR)/bl_stage2.bin:
    @echo "Building bl_stage2.bin"
    $(MAKE) -C $(SRC_DIR)/bootloader/stage2 TARGET_DIR=$(abspath $(TARGET_DIR))

$(TARGET_DIR):
    mkdir -p $(TARGET_DIR)

$(OBJ_DIR):
    mkdir -p $(OBJ_DIR)

run: $(TARGET)
    qemu-system-i386 -fda $(TARGET)

clean: $(TARGET_DIR)
    rm -rf $(TARGET_DIR)

And here is the stage1 Makefile:

TARGET_DIR?=build/
ASM?=nasm

.PHONY: all

all: stage1

stage1: $(TARGET_DIR)/bl_stage1.bin

$(TARGET_DIR)/bl_stage1.bin: ./bootloader.asm
    $(ASM) ./bootloader.asm -f bin -o $(TARGET_DIR)/bl_stage1.bin

When I try to run the Makefile:

Building bl_stage2.bin
make -C src/bootloader/stage2 TARGET_DIR=/home/setorano/dev/CentralOS/build
make[1]: Entering directory '/home/setorano/dev/CentralOS/src/bootloader/stage2'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/setorano/dev/CentralOS/src/bootloader/stage2'

So Make doesn't even run stage1.


Solution

  • The line

    $(TARGET_DIR)/bl_stage1.bin:
    

    says that bl_stage1.bin has no dependencies, so it will never be rebuilt.

    Instead you could replace that line and the line before by simply

    stage1:
    

    and make stage1 a phony target, that way it will always rerun the make command that goes into the stage1 directory.