# config
-include Make.config
include mk/Variables.mk

initdir	:=  $(DESTDIR)/etc/rc.d/init.d

CFLAGS  += -Wno-pointer-arith
CFLAGS  += -I include -D__XEN_INTERFACE_VERSION__=0x00030205
CFLAGS  += -DLIB='"$(LIB)"'
CFLAGS  += -DVERSION='"$(VERSION)"'
CFLAGS	+= -DQEMU_TOOL=1 -D_GNU_SOURCE=1
CFLAGS  += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64

ifeq ($(HARCH),x86_64)
  EMU   := emu32.elf emu64.elf hvm32.bin hvm64.bin
else
  EMU   := emu32.elf hvm32.bin
endif

TARGETS := xenner xenner-stats xenner-cleanup evtchnd blkbackd netbackd
TARGETS += libxenctrl.so $(EMU)

all: $(TARGETS)

##############################################################################
# poor man's autoconf ;-)

include mk/Autoconf.mk
define make-config
LIB                  := $(LIB)
HARCH                := $(call ac_uname_arch)
HAVE_LIBAIO          := $(call ac_lib,io_setup,aio)
HAVE_EVTCHN_ERROR    := $(call ac_grep,evtchn_port_or_error_t,/usr/include/xenctrl.h)
HAVE_SYS_EVTCHN_H    := $(call ac_header,xen/sys/evtchn.h)
CFLAGS_NO_BUILD_ID   := $(call ac_cflag,-Xlinker --build-id=none)
endef

AIO_LDLIBS           := -laio

CFLAGS               += $(call ac_inc_cflags,EVTCHN_ERROR SYS_EVTCHN_H)
CFLAGS               += $(call ac_lib_cflags,AIO)
blkbackd  :  LDLIBS  += $(call ac_lib_mkvar,AIO,LDLIBS)

# try picking up soname version from xen upstream
UPSTREAM_LIB := $(wildcard /usr/$(LIB)/libxenctrl.so.?.?)
UPSTREAM_VER := $(patsubst /usr/$(LIB)/libxenctrl.so.%,%,$(UPSTREAM_LIB))
XEN_SO_MAJOR ?= $(firstword $(UPSTREAM_VER) 3.0)
XEN_SO_MINOR := $(XEN_SO_MAJOR).0
CFLAGS       += -D'XEN_SO_MAJOR="$(XEN_SO_MAJOR)"'

##############################################################################

xenner         : LDLIBS  += -lxenguest -lxenstore -luuid
xenner-cleanup : LDLIBS  += -lxenstore
blkbackd       : LDLIBS  += -lxenctrl -lxenstore -lpthread -lz -lrt
netbackd       : LDLIBS  += -lxenctrl -lxenstore -lpthread
vfbbackd       : LDLIBS  += -lxenstore
tsctest        : CFLAGS  += -DSTANDALONE=1

libxenctrl.so  : LDFLAGS += -Wl,-soname,libxenctrl.so.$(XEN_SO_MAJOR) -shared -ldl

##############################################################################

clean:
	rm -f *.elf *.log
	rm -f xen/names.h xen/names.c xen/x86_32.h xen/x86_64.h
	rm -f *.o qemu/*.o *.opic *.o32 *.o64
	rm -f *~ qemu/*~ xen/*~ mk/*~
	rm -f core*
	rm -f mk/*.dep

distclean: clean
	rm -f $(TARGETS) vfbbackd
	rm -f lib*.a libxenctrl.so.3*
	rm -f Make.config

realclean: distclean qemuclean
	rm -f $(libxc)

install:
	$(INSTALL_DIR) $(bindir) $(sbindir) $(libdir)/xenner $(initdir)
	$(INSTALL_BINARY) xenner xenner-stats $(bindir)
	$(INSTALL_BINARY) evtchnd blkbackd netbackd $(sbindir)
	$(INSTALL) $(EMU) libxenctrl.so.$(XEN_SO_MINOR) $(libdir)/xenner
	ln -s libxenctrl.so.$(XEN_SO_MINOR) $(libdir)/xenner/libxenctrl.so.$(XEN_SO_MAJOR)
	$(INSTALL_SCRIPT) xenner.init $(initdir)/xenner

check:
	$(CC) -Wall -Iinclude -m32 -ocheck32 check.c
	$(CC) -Wall -Iinclude -m64 -ocheck64 check.c
	@./check32
	@./check64
	rm -f check32 check64

##############################################################################
# qemu block drivers

qemu-dir := $(HOME)/tmp/kvm-54/qemu
qemu-hdr := block_int.h osdep.h bswap.h aes.h vl.h
qemu-src := block.c cutils.c osdep.c aes.c
qemu-src += block-bochs.c block-cloop.c block-cow.c block-dmg.c block-parallels.c block-qcow.c block-qcow2.c block-raw.c block-vmdk.c block-vpc.c block-vvfat.c
qemu-obj := $(patsubst %.c,qemu/%.o,$(qemu-src))
qemu-cps := $(patsubst %,qemu/%,$(qemu-src))
qemu-cph := $(patsubst %,qemu/%,$(qemu-hdr))

libqemublock.a : $(qemu-obj)
	@$(echo_ar_lib)
	@$(ar_lib)

$(qemu-cps) $(qemu-cph):
	cp $(qemu-dir)/$(@F) qemu/

$(qemu-cps) : $(qemu-cph)

qemuclean:
	rm -f $(qemu-cps) $(qemu-cph)


##############################################################################

xenner: xenner.o kvmbits.o build.o hypercalls.o mm.o log.o \
	cpuid.o debug.o vmcore.o tsctest.o xen-emudev.o \
	console.o xenbus.o evtchn.o hexdump.o statistics.o \
	xen/names.o libkvm.a libxenctrl.a

xenner-stats: xenner-stats.o statistics.o log.o xen/names.o libxenctrl.a
xenner-cleanup: xenner-cleanup.o libxenctrl.a

evtchnd: evtchnd.o daemon.o
blkbackd: blkbackd.o xenbackd.o daemon.o libqemublock.a
netbackd: netbackd.o xenbackd.o daemon.o checksum.o hexdump.o
vfbbackd: vfbbackd.o xenbackd.o daemon.o libxenctrl.a


libxenctrl.so: libxenctrl.so.$(XEN_SO_MAJOR)
	ln -sf $< $@

libxenctrl.so.$(XEN_SO_MAJOR): libxenctrl.so.$(XEN_SO_MINOR)
	ln -sf $< $@

libxenctrl.so.$(XEN_SO_MINOR): libxc.opic libxc-evtchn.opic libxc-gnttab.opic libxc-vmcore.opic libxc-shlib.opic
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) 

libxenctrl.a: libxc.o libxc-evtchn.o libxc-gnttab.o libxc-vmcore.o
	@$(echo_ar_lib)
	@$(ar_lib)

libkvm.a: libkvm.o libkvm-x86.o
	@$(echo_ar_lib)
	@$(ar_lib)


build.o: build.c
hypercalls.o: hypercalls.c xen/names.h
emu-main32.o: emu-main32.c xen/names.h
emu-main64.o: emu-main64.c xen/names.h
xenner.o: xenner.c xen/x86_32.h xen/x86_64.h

##############################################################################

EMUXX_OBJS := emu-hcall.o emu-data.o emu-instr.o emu-pv.o emu-lapic.o \
		printk.o xen/names.o
EMU32_OBJS := emu32.o emu-main32.o emu-hcall32.o emu-mm32.o \
		$(patsubst %,%32,$(EMUXX_OBJS))
EMU64_OBJS := emu64.o emu-main64.o emu-hcall64.o emu-mm64.o \
		$(patsubst %,%64,$(EMUXX_OBJS))
HVM32_OBJS := hvm32.o hvm.o32
HVM64_OBJS := hvm64.o hvm.o64

emu32.elf           : CFLAGS  += -m32 -ffreestanding
hvm32.elf           : CFLAGS  += -m32 -ffreestanding -fpic
emu32.elf hvm32.elf : ASFLAGS += -m32

emu64.elf hvm64.elf : CFLAGS  += -m64 -ffreestanding -fpic -mno-red-zone
emu64.elf hvm64.elf : ASFLAGS += -m64

emu32.elf: $(EMU32_OBJS)
emu64.elf: $(EMU64_OBJS)
hvm32.elf: $(HVM32_OBJS)
hvm64.elf: $(HVM64_OBJS)

hvm32.bin hvm64.bin : CFLAGS += $(CFLAGS_NO_BUILD_ID)

##############################################################################

%.o32: %.c
	@$(cc_makedirs)
	@$(echo_compile_c)
	@$(compile_c)
	@$(fixup_deps)

%.o64: %.c
	@$(cc_makedirs)
	@$(echo_compile_c)
	@$(compile_c)
	@$(fixup_deps)

%.elf: %.o
	$(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-N -Wl,-T,$*.lds $^

%.bin: %.elf
	objcopy -O binary $< $@

##############################################################################

xenco := xen.h memory.h callback.h grant_table.h
xen32 := arch-x86/xen-x86_32.h arch-x86/xen.h $(xenco)
xen64 := arch-x86/xen-x86_64.h arch-x86/xen.h $(xenco)
xenpy := $(wildcard xen/*.py)

xen/x86_32.h: $(patsubst %,/usr/include/xen/%,$(xen32)) $(xenpy)
	(cd xen; python mkheader.py x86_32 x86_32.h $(filter %.h,$^))

xen/x86_64.h: $(patsubst %,/usr/include/xen/%,$(xen64)) $(xenpy)
	(cd xen; python mkheader.py x86_64 x86_64.h $(filter %.h,$^))

xen/names.h xen/names.c: xen/nametable.sh
	sh $< xen/names.h xen/names.c

##############################################################################

include mk/Compile.mk
include mk/Maintainer.mk
-include $(depfiles)

.PHONY: sync.hg
sync.hg:
	$(HOME)/bin/xenner-sync
	(cd $(HOME)/tailor/xenner-sync.hg; hg push)
