Ontwerp en bouw een besturingssysteem/Organisatie/Makefiles

Uit Wikibooks
Naar navigatie springen Naar zoeken springen

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


InformatieCross-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[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.
Informatie afkomstig van http://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.