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
[bewerken]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.
|
Hoofdmap makefile
[bewerken]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
[bewerken]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. |