export # export all variable to sub-Makefile
CC=mipsel-unknown-elf-gcc
AS=mipsel-unknown-elf-as
LD=mipsel-unknown-elf-ld
DU=mipsel-unknown-elf-objdump

SYS_OBJS     = build/sys/vm_handler.o \
		       build/sys/sys_handler.o \
               build/sys/giet.o \
       	       build/sys/switch.o \
               build/sys/common.o \
               build/sys/ctx_handler.o \
               build/sys/drivers.o \
               build/sys/exc_handler.o \
               build/sys/irq_handler.o \
               build/sys/kernel_init.o

BOOT_OBJS    = build/boot/reset.o \
               build/boot/boot_init.o 

DISPLAY_OBJS = build/display/main.o \
               build/libs/stdio.o \
               build/libs/utils.o

ROUTER_OBJS  = build/router/main.o \
               build/libs/mwmr_channel.o \
               build/libs/stdio.o \
               build/libs/utils.o

HELLO_OBJS   = build/hello/main.o \
               build/libs/stdio.o \
               build/libs/utils.o

PGCD_OBJS    = build/pgcd/main.o \
               build/libs/stdio.o \
               build/libs/utils.o

CFLAGS=-Wall -ffreestanding -mno-gpopt -mips32 -g

INCLUDE = -Iboot -Isys -Ixml -Ilibs -I.

TRASH= /dev/null||true

all: soft.elf
	
## merge all *.elf and map.bin to soft.elf
soft.elf: build/boot/boot.elf \
          build/sys/sys.elf \
          build/display/display.elf \
          build/router/router.elf \
          build/pgcd/pgcd.elf \
          build/hello/hello.elf \
          map.bin
	$(MAKE) -C memo
	memo/memo.x  map.bin 
	$(DU) -D $@ > build$@.txt

### mapping compilation
map.bin: map.xml
	$(MAKE) -C xml
	xml/xml2bin map.xml map.bin

### system compilation
build/sys/sys.elf: $(SYS_OBJS) sys/sys.ld
	$(LD) -o $@ -T sys/sys.ld $(SYS_OBJS)
	$(DU) -D $@ > $@.txt

build/sys/%.o: sys/%.c 
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

build/sys/%.o: sys/%.s
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

### boot compilation
build/boot/boot.elf: $(BOOT_OBJS) boot/boot.ld
	$(LD) -o $@ -T boot/boot.ld $(BOOT_OBJS)
	$(DU) -D $@ > $@.txt

build/boot/%.o: boot/%.c 
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

build/boot/%.o: boot/%.S
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

### display compilation
build/display/display.elf: $(DISPLAY_OBJS) display/display.ld
	$(LD) -o $@ -T display/display.ld $(DISPLAY_OBJS)
	$(DU) -D $@ > $@.txt

build/display/main.o: display/main.c
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

### router compilation
build/router/router.elf: $(ROUTER_OBJS) router/router.ld
	$(LD) -o $@ -T router/router.ld $(ROUTER_OBJS)
	$(DU) -D $@ > $@.txt

build/router/main.o: router/main.c
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

### hello compilation
build/hello/hello.elf: $(HELLO_OBJS) hello/hello.ld
	$(LD) -o $@ -T hello/hello.ld $(HELLO_OBJS)
	$(DU) -D $@ > $@.txt

build/hello/main.o: hello/main.c
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

### pgcd compilation
build/pgcd/pgcd.elf: $(PGCD_OBJS) pgcd/pgcd.ld
	$(LD) -o $@ -T pgcd/pgcd.ld $(PGCD_OBJS)
	$(DU) -D $@ > $@.txt

build/pgcd/main.o: pgcd/main.c
	$(CC) $(INCLUDE) $(CFLAGS)  -c -o $@ $<

### libs compilation
build/libs/utils.o: libs/utils.c
	$(CC) $(CFLAGS) $(INCLUDE)  -c -o $@ $<

build/libs/stdio.o: libs/stdio.c
	$(CC) $(CFLAGS) $(INCLUDE)  -c -o $@ $<

build/libs/mwmr_channel.o: libs/mwmr_channel.c
	$(CC) $(CFLAGS) $(INCLUDE)  -c -o $@ $<


### clean 
clean:
	rm -f *.o *.elf *.bin *.txt core *~	2>$(TRASH)
	$(MAKE) -s clean -C xml	2>$(TRASH)
	$(MAKE) -s clean -C memo 2>$(TRASH)
	rm -r build/boot/* 2>$(TRASH)
	rm -r build/sys/* 2>$(TRASH)
	rm -r build/libs/* 2>$(TRASH)
	rm -r build/pgcd/* 2>$(TRASH)
	rm -r build/hello/* 2>$(TRASH)
	rm -r build/display/* 2>$(TRASH)
	rm -r build/router/* 2>$(TRASH)
