# -----------------------------------------------------------------------------
# 
#                              M A K E F I L E
# 
# zum Uebungsbetriebssystem OO-Stubs der Lehrveranstaltung 
# 'Betriebssysteme I' an der Uni-Magdeburg im SS 98.
# -----------------------------------------------------------------------------
#
# Durch Eingabe von 'make' werden die Quelltexte des Systems kompiliert.
# 'make bootdisk' schreibt das System-Image auf eine Diskette, von der das
# System dann gebootet werden kann. 'make depend' aktualisiert die Abhaegig-
# keiten der Quelltexte. Mit 'make clean' wird im Verzeichnis aufgeraeumt.
#
# -----------------------------------------------------------------------------

# Liste der Quelltexte:
# (Beim Hinzufuegen neuer Module erweitern!)

STARTUP_SOURCE = \
	startup.asm
	

C_SOURCES = \
	main.c \
	guard/guardian.c \
	guard/lock.c \
	guard/syscall.c \
	guard/sema.c \
	machine/screen.c \
	../objects/list.c \
	thread/sched.c \
	thread/process.c \
	machine/disp.c \
	../user/appl.c \
	fun.c \
	machine/timer.c \
	machine/keyctrl.c \
	machine/pic.c \
	machine/plug.c \
	device/watch.c \
	device/panic.c \
	device/keybd.c
	


ASM_SOURCES = \
	machine/ioport.asm \
	machine/screen.asm \
	machine/disp.asm \
	machine/cpu.asm \
	sphere.asm

# --------------------------------------------------------------------------

# Generierungssystem: Wahlweise 'Linux', 'DOS', 'Win95' oder 'WinNT'

GENSYS = Linux

# Einstellungen in Abhaengigkeit vom Generierungssystem:
#
#    ASMOBJFORMAT: Ausgabeformat fuer den Assembler. Das Format muss dem
#                  jeweiligen Format des verwendeten C++ Compilers angepasst
#                  werde, damit gemischte Objektdateien gelinkt werden koennen.
#    OBJDIR:       Verzeichnis, in dem die Objektdateien abgelegt werden
#                  sollen.
#    DRIVE:        Laufwerk, auf das das System-Image geschrieben wird.
#    DELETE:       Name des Kommandos zum Loeschen von Dateien
#    ASM:          Zu benutzender Assembler
#    CC/CXX:       Zu benutzender C/C++-Compiler.
#    CFLAGS:       Flags fuer den Compileraufruf.
#    LD:           Zu benutzender Linker.
#    LDFLAGS:      Flags fuer den Linkeraufruf
#    LDLIBS:       Dazuzulinkende Bibliotheken
#    LDHEAD:       Am Anfang zu linkende Dateien
#    LDTAIL:       Am Ende zu linkende Dateien

# Entwicklung mit DJGPP unter DOS/Windows 95/Windows NT
ifeq ($(GENSYS),DOS)
  OBJDIR = dos
  ASMOBJFORMAT = coff
  DRIVE = a:
  DELETE = del
  ASM = nasm
  CC = gcc
  CXX = gpp
  CFLAGS = -fno-exceptions
  LD = ld
  GCCLIB = c:/djgpp/lib/gcc-lib/djgpp/2.80/
  LDFLAGS = -L $(GCCLIB) -L c:/djgpp/lib
  LDLIBS = -lgcc -lc
  C_SOURCES := $(C_SOURCES) initfini.c
  RAWRITE = $(TOOLS)/rawrite2
endif

# Entwicklung mit Cygnus Gnu-Win32 unter Windows 95
ifeq ($(GENSYS),Win95)
  OBJDIR = win32
  ASMOBJFORMAT = win32
  DRIVE = a:
  DELETE = rm
  ASM = nasmw
  CC = gcc
  CXX = g++
  CFLAGS = -fno-exceptions
  LD = ld
  GCCLIB = /cygnus/b19/H-i386-cygwin32/lib/gcc-lib/i386-cygwin32/2.7-B19
  LDFLAGS = -L $(GCCLIB) -L /cygnus/b19/H-i386-cygwin32/i386-cygwin32/lib
  LDLIBS = -lgcc -lc
  C_SOURCES := $(C_SOURCES) initfini.c
  RAWRITE = $(TOOLS)/rawrite2
endif

# Entwicklung mit Cygnus Gnu-Win32 unter Windows NT
ifeq ($(GENSYS),WinNT)
  OBJDIR = win32
  ASMOBJFORMAT = win32
  DRIVE = /dev/fd0
  DELETE = rm
  ASM = nasmw
  CC = gcc
  CXX = g++
  CFLAGS = -fno-exceptions
  LD = ld
  GCCLIB = /cygnus/b19/H-i386-cygwin32/lib/gcc-lib/i386-cygwin32/2.7-B19
  LDFLAGS = -L $(GCCLIB) -L /cygnus/b19/H-i386-cygwin32/i386-cygwin32/lib
  LDLIBS = -lgcc -lc
  C_SOURCES := $(C_SOURCES) initfini.c
endif

# Entwicklung mit dem gcc unter Linux/PC
ifeq ($(GENSYS),Linux)
  OBJDIR = linux
  ASMOBJFORMAT = elf
  DRIVE = /dev/fd0
  DELETE = rm
  ASM = nasm
  CC = gcc
  CXX = g++
  LD = ld
# GCCLIB = /usr/lib/gcc-lib/i486-unknown-linux-gnulibc1/2.7.2.3
  LDHEAD = /usr/lib/crti.o $(GCCLIB)/crtbegin.o
  LDTAIL = $(GCCLIB)/crtend.o /usr/lib/crtn.o
endif

# Einstellungen, die von der jeweiligen Installation und dem geplanten
# Zielsystem abhaengen:
#
#    TOOLS:      Verzeichnis mit Hilfsprogrammen, die im Rahmen der LV zur
#                Verfuegung gestellt werden.
#    BOOT:       Zur Verfuegung gestelltes Verzeichnis mit Dateien, die
#                benoetigt werden, um eine Bootdiskette zu erzeugen.
#    BOOTDEVICE: Beschreibung des Geraetes von dem das System spaeter
#                gebootet wird. Beispiele:
#                0:80:2:18:0:0:1 - 3.5" Diskette im 1. Laufwerk (A)
#                1:80:2:15:0:0:1 - 5.25" Diskette im 2. Laufwerk (B)
#                Eine genauere Beschreibung erhaelt man durch Starten von
#                'build' (gehoert zu den Tools der LV) ohne Parameter.
#

BOOT       = ../boot
TOOLS      = ../tools/$(OBJDIR)
BOOTDEVICE = 0:80:2:18:0:0:1
 
# -------------------------------------------------------------------------

# Namen der Unterverzeichnisse mit den Quelltexten
# (wird automatisch aus den Quelltextdateien ermittelt und vom Compiler
# benutzt, um die Quelltexte zu finden.)

VPATH = $(sort $(dir $(STARTUP_SOURCE) $(CC_SOURCES) $(C_SOURCES) \
	$(ASM_SOURCES)))


# Listen mit den Objektdateien, die beim Kompilieren entstehen:
# (werden automatisch aus den Quelltextdateinamen ermittelt)

FIRST_OBJECT = $(patsubst %.asm,_%.o, $(notdir $(STARTUP_SOURCE)))

C_OBJECTS = $(notdir $(C_SOURCES:.c=.o))

CC_OBJECTS = $(notdir $(CC_SOURCES:.cc=.o))

ASM_OBJECTS = $(patsubst %.asm,_%.o, $(notdir $(ASM_SOURCES)))


OBJPRE = \
	$(addprefix $(OBJDIR)/,$(ASM_OBJECTS) $(C_OBJECTS) $(CC_OBJECTS))

# --------------------------------------------------------------------------

# Regeln zur Erzeugung der Objektdateien

CFLAGS := $(CFLAGS) -Wall -Iinclude

$(OBJDIR)/%.o : %.c
	$(CC) -c $(CFLAGS) -o $@ $<

$(OBJDIR)/%.o : %.cc
	$(CXX) -c $(CFLAGS) -o $@ $<

$(OBJDIR)/_%.o : %.asm
	$(ASM) -f $(ASMOBJFORMAT) -d$(GENSYS) -o $@ $<

# -------------------------------------------------
# Linken des Systems

$(OBJDIR)/system: $(OBJDIR) $(OBJDIR)/$(FIRST_OBJECT) $(OBJPRE)
	$(LD) -e startup -T sections -o $(OBJDIR)/system $(LDFLAGS) $(OBJDIR)/$(FIRST_OBJECT) $(OBJPRE)

# -------------------------------------------------
# Regel zur Erzeugung des Objektdateiverzeichnisses

$(OBJDIR) :
	mkdir $(OBJDIR)

# -------------------------------------------------------------------------

# Ab hier folgt die Definition der targets,
# die stark vom gewaehlten Generierungssystem abhaengen.

.PHONY: clean depend

# 'system.img' enthaelt die zu ladenden Sections des eigentlichen Systems

ifeq ($(GENSYS),DOS)
system.img : $(OBJDIR)/system
	$(TOOLS)/coff2bin $(OBJDIR)/system system.img
endif
ifeq ($(GENSYS),Win95)
system.img : $(OBJDIR)/system
	$(TOOLS)/bfd2bin $(OBJDIR)/system system.img
endif
ifeq ($(GENSYS),WinNT)
system.img : $(OBJDIR)/system
	$(TOOLS)/bfd2bin $(OBJDIR)/system system.img
endif
ifeq ($(GENSYS),Linux)
system.img : $(OBJDIR)/system
	objcopy -O binary $(OBJDIR)/system system.img
endif
ifeq ($(GENSYS),Linux_Alpha)
system.img : $(OBJDIR)/system
	objcopy -O binary $(OBJDIR)/system system.img
endif

# 'bootdisk.img' besteht aus dem 'system.img', das um den (parametrisierten)
# Bootblock und den Setup-Code erweitert wurde.

bootdisk.img : system.img
	$(TOOLS)/build $(BOOT)/bootsect $(BOOT)/setup system.img $(BOOTDEVICE) bootdisk.img

# 'make depend' unter DOS fuehrt zu folgenden Aktionen:
#    - Mit 'sed' wird das Makefile gelesen und alles nach der Zeile, die mit
#      "# DO NOT DELETE" beginnt, geloescht. Das resultierende Makefile wird
#      unter Makefile.cut gespeichert.
#    - Der Text "# DO NOT DELETE" wird an Makefile.cut angehaengt.
#    - In einer Schleife werden alle Objektdateien durchgegangen. Das Hilfs-
#      programm 'makedep' ermittelt fuer jede der Dateien die Abhaengigkeiten
#      von Quelltexten (*.c *.asm *.h) und fuegt eine entsprechende Zeile
#      an Makefile.cut an.
#    - Das urspruengliche Makefile wird geloescht.
#    - 'makefile.cut' wird in 'makefile' umbenannt.
# Mit diesen Aktionen wird das Verhalten von 'makedepend' unter Linux nachge-
# bildet.

ifeq ($(GENSYS),DOS)

depend:
	sed -e "/^# DO NOT DELETE/,$$d" makefile > makefile.cut
	echo # DO NOT DELETE >> makefile.cut
	$(CC) -MM $(CFLAGS) $(C_SOURCES) | sed -e s/.*:/$(OBJDIR)\/&/ >> makefile.cut
	$(CC) -MM $(CFLAGS) $(CC_SOURCES) | sed -e s/.*:/$(OBJDIR)\/&/ >> makefile.cut
	del makefile
	rename makefile.cut makefile

# 'make clean' loescht alle Objektdateien, das erzeugte System, Sicherheits-
# kopien des Editors und die Zwischendateien, die bei der Erzeugung von
# Objektdateien aus Assembler-Quelltexten temporaer entstehen.

clean:	
	@del $(OBJDIR)\*.o
	@del $(OBJDIR)\system
	@del *.bak
	@del *.asp
	@del *.img


else

# 'make depend' unter Linux, Win95 und WinNT

depend:
	sed -e "/^# DO NOT DELETE/,$$$$d" makefile > makefile.cut
	echo "# DO NOT DELETE" >> makefile.cut
	$(CC) -MM $(CFLAGS) $(C_SOURCES) | sed -e "s/.*:/$(OBJDIR)\/&/" >> makefile.cut
	$(CXX) -MM $(CFLAGS) $(CC_SOURCES) | sed -e "s/.*:/$(OBJDIR)\/&/" >> makefile.cut
	rm makefile
	mv makefile.cut makefile

# 'make clean' loescht alle Objektdateien, das erzeugte System, Sicherheits-
# kopien des Editors und die Zwischendateien, die bei der Erzeugung von
# Objektdateien aus Assembler-Quelltexten temporaer entstehen.

clean:	
	@rm -f $(OBJDIR)/*.[oO] $(OBJDIR)/system *~ *.asp *.img

endif

# 'make bootdisk' erzeugt zunaechst das System, falls das noch nicht geschehen
# ist. Danach wird eine Bootdiskette mit dem System erzeugt.

ifeq ($(GENSYS),DOS)

bootdisk: bootdisk.img
	$(RAWRITE) -f bootdisk.img -d $(DRIVE) -n

endif

ifeq ($(GENSYS),Win95)

bootdisk: bootdisk.img
	$(RAWRITE) -f bootdisk.img -d $(DRIVE) -n

endif

ifeq ($(GENSYS),WinNT)

bootdisk: bootdisk.img
	-cp bootdisk.img $(DRIVE)

endif

ifeq ($(GENSYS),Linux)

bootdisk: bootdisk.img
	-cp bootdisk.img $(DRIVE)

endif

# --------------------------------------------------------------------------
# Ab hier kommt die generierte Liste der Abhaengigkeiten der Objektdateien
# von den Quelltexten. Wenn z.B. eine Header-Datei (*.h) geaendert wird, kann
# make automatisch alle Quelltexte neu kompilieren, die diese Header-Datei
# benutzen.

# DO NOT DELETE
linux/main.o: main.c include/machine/screen.h include/machine/ioport.h \
 include/guard/sema.h include/objects/list.h include/thread/process.h \
 include/thread/sched.h include/machine/cpu.h include/machine/pic.h \
 include/machine/plug.h include/machine/timer.h include/device/keybd.h \
 include/device/watch.h include/user/appl.h include/guard/lock.h \
 include/guard/syscall.h include/fun.h
linux/guardian.o: guard/guardian.c include/machine/plug.h
linux/lock.o: guard/lock.c include/guard/lock.h include/objects/list.h \
 include/machine/cpu.h include/machine/screen.h \
 include/machine/ioport.h include/guard/sema.h \
 include/thread/process.h
linux/syscall.o: guard/syscall.c include/device/keybd.h \
 include/guard/syscall.h include/guard/sema.h include/objects/list.h \
 include/thread/process.h include/guard/lock.h include/thread/sched.h
linux/sema.o: guard/sema.c include/machine/pcb.h include/machine/register.h \
 include/objects/list.h include/guard/sema.h include/thread/process.h \
 include/thread/sched.h
linux/screen.o: machine/screen.c include/machine/screen.h \
 include/machine/ioport.h include/guard/sema.h include/objects/list.h \
 include/thread/process.h
linux/list.o: ../objects/list.c include/objects/list.h
linux/sched.o: thread/sched.c include/thread/sched.h include/objects/list.h \
 include/machine/pcb.h include/machine/register.h include/guard/sema.h \
 include/thread/process.h include/machine/disp.h include/machine/cpu.h
linux/process.o: thread/process.c include/thread/process.h \
 include/objects/list.h include/machine/pcb.h \
 include/machine/register.h include/guard/sema.h \
 include/machine/disp.h include/machine/cpu.h include/thread/sched.h
linux/disp.o: machine/disp.c include/machine/disp.h \
 include/machine/register.h
linux/appl.o: ../user/appl.c include/machine/screen.h \
 include/machine/ioport.h include/guard/sema.h include/objects/list.h \
 include/thread/process.h include/thread/sched.h include/machine/cpu.h \
 include/guard/syscall.h
linux/fun.o: fun.c include/machine/screen.h include/machine/ioport.h \
 include/guard/sema.h include/objects/list.h include/thread/process.h \
 sphere.inc
linux/timer.o: machine/timer.c include/machine/ioport.h \
 include/machine/timer.h include/machine/screen.h include/guard/sema.h \
 include/objects/list.h include/thread/process.h include/machine/pic.h
linux/keyctrl.o: machine/keyctrl.c include/machine/ioport.h \
 include/machine/pic.h include/machine/keyctrl.h
linux/pic.o: machine/pic.c include/machine/ioport.h include/machine/pic.h
linux/plug.o: machine/plug.c include/device/panic.h include/machine/plug.h
linux/watch.o: device/watch.c include/device/watch.h include/machine/timer.h \
 include/machine/plug.h include/machine/pic.h include/machine/cpu.h \
 include/machine/screen.h include/machine/ioport.h \
 include/guard/sema.h include/objects/list.h include/thread/process.h \
 include/thread/sched.h include/guard/lock.h
linux/panic.o: device/panic.c include/machine/screen.h \
 include/machine/ioport.h include/guard/sema.h include/objects/list.h \
 include/thread/process.h include/machine/cpu.h
linux/keybd.o: device/keybd.c include/objects/list.h include/device/keybd.h \
 include/machine/pic.h include/machine/keyctrl.h \
 include/machine/ioport.h include/machine/plug.h \
 include/machine/screen.h include/guard/sema.h \
 include/thread/process.h include/guard/lock.h include/guard/syscall.h
