Ontwerp en bouw een besturingssysteem/Organisatie/Makefiles
Steeds weer voor elk bestand die compileeropdracht intypen, wordt een beetje vervelend. Gelukkig is er een oplossing die in de Linux wereld erg veel gebruikt wordt voor het compileren van applicaties. Die oplossing is make, een hulpmiddel dat zogenaamde makefile scripts kan uitvoeren en speciaal bedoeld is voor het compileren van applicaties, het genereren van documentatie en dat soort taken.
Het schrijven van goede makefiles is een kunst op zich, en in dit boek ligt de nadruk op het bouwen van een besturingssysteem, dus worden makefiles niet uitgebreid behandeld. Maar omdat ze zo onmisbaar zijn volgt hier een korte uitleg van makefiles zoals die direct voor het besturingssysteem gebruikt kunnen worden.
Basisbestand
Maak in de hoofdmap van het project (/) een nieuw Makefile.inc bestand aan. Dit is het basisbestand voor alle andere makefiles, en heeft de volgende inhoud:
/Makefile.inc
CC = gcc
CFLAGS = -Wall -O -fno-stack-protector -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdlib -nostdinc -fno-builtin -I./include
AS = nasm
ASFLAGS =
LD = ld
LDFLAGS =
RM = rm
ECHO = echo
# De naam van het uiteindelijke bestand:
KERNELFILE = kernel
.SILENT :
force_look :
true
![]() | Cross-platform toolchain? Gebruik je een cross-platform toolchain, pas dan de namen van de tools ld en gcc in dit bestand aan. gcc wordt dan bijvoorbeeld i586-elf-gcc. |
Hoofdmap makefile
Het vorige bestand is geen echte makefile, maar bevat alleen de basis ervan. Dat gebruiken we in de echte makefile die gemaakt moet worden in dezelfde map (/), Makefile genaamd, zonder extensie. Het bestand heeft de volgende inhoud:
/Makefile
include Makefile.inc
# Alle submappen waarin 'make' uitgevoerd kan worden.
DIRS = kernel
.PHONY: all clean
all : $(KERNELFILE)
# Kopieer dit en pas het aan voor elke submap waarin 'make' uitgevoerd kan worden.
$(KERNELFILE) : force_look
$(ECHO) "Entering directory 'kernel'..."
cd kernel; $(MAKE) -$(MAKEFLAGS) all
$(ECHO) "Leaving directory 'kernel'."
clean :
-for d in $(DIRS); do (cd $$d; $(MAKE) clean ); done
Kernel makefile
Omdat de voorgaande makefile make aanroept in de submappen (alleen kernel in dit geval), moeten al die submappen ook een Makefile bestand bevatten. In /kernel/Makefile gebeurt het echte werk, en staat dan het volgende:
/kernel/Makefile
include ../Makefile.inc
MAINFILE = ../$(KERNELFILE)
# Het bestand met de multiboot header (en het bijbehorende object-bestand)
BOOTFILE = src/boot.asm
BOOTOBJFILE = src/boot.obj
# Andere .asm bestanden
ASMFILES =
# De C bestanden
SRCFILES = \
src/system.c \
src/memory.c \
src/kernel.c
LINKFILE = link.ld
OBJFILES = $(BOOTOBJFILE) $(patsubst %.asm,%.obj,$(ASMFILES)) $(patsubst %.c,%.o,$(SRCFILES))
.PHONY: all clean
all : $(MAINFILE)
$(MAINFILE) : $(LINKFILE) $(OBJFILES)
$(LD) $(LDFLAGS) -o $(MAINFILE) -T $(LINKFILE) $(OBJFILES)
$(BOOTOBJFILE) : $(BOOTFILE)
$(AS) $(ASFLAGS) -I./src/ -o $(BOOTOBJFILE) -f elf $(BOOTFILE)
%.obj : %.asm
$(AS) $(ASFLAGS) -I./src/ -o $*.obj -f elf $*.asm
%.o : %.c
$(CC) $(CFLAGS) -c -o $*.o $*.c
clean:
-$(RM) ./src/*.o ./src/*.obj $(MAINFILE)
Mappenstructuur Deze makefiles gaan ervan uit dat je je aan de eerder genoemde mappenstructuur hebt gehouden. |