Repo makefile builds all the targets in the repo

Builds buildroot image and host binaries, the linux kernel, and
kvm-unit-tests.

Runs the unit tests.

Signed-off-by: Fuad Tabba <tabba@google.com>
diff --git a/Makefile b/Makefile
index af8298d..2115f98 100644
--- a/Makefile
+++ b/Makefile
@@ -1,27 +1,58 @@
-# Folders
+##
+## Folders
+##
 ROOT_DIR := $(CURDIR)
 OUT_DIR := $(ROOT_DIR)/out
+CCACHE_DIR := $(ROOT_DIR)/.ccache
+TEST_SCRIPTS_DIR := $(ROOT_DIR)/build/aarch64-unit-tests
 
-# Commands
-MAKE ?= make
+##
+## Common options
+##
+VERBOSE ?= 0
+CROSS_PREFIX ?= "aarch64-linux-gnu-"
+CCACHE ?= ""
+
 
 ##
 ## Common targets
 ##
 
 .PHONY: clean
-clean: buildroot_clean
+clean: buildroot_clean kvmunittests_clean linux_clean
 
-.PHONE: distclean
-distclean:
-	rm -rf $(OUT_DIR)
+.PHONY: distclean
+distclean: kvmunittests_clean
+	- rm -rf $(OUT_DIR)
+
+.PHONY: all
+all: buildroot kvmunittests linux
+
+.PHONY: help
+help:
+	@echo 'Generic Targets:'
+	@echo '   all                  - builds alli generic targetst'
+	@echo '   buildroot            - the buildroot rootfs image as well as the host qemu'
+	@echo '   kvmunittests         - the kvm-unit-tests'
+	@echo '   linux                - the linux kernel'
+	@echo ''
+	@echo 'Clean Targets:'
+	@echo '   clean                - cleans all, but keeps the prebuilts'
+	@echo '   distclean            - distclean for all targets'
+	@echo '   buildroot_clean      - the buildroot rootfs image as well as the host qemu'
+	@echo '   kvmunittests_clean   - the kvm-unit-tests'
+	@echo '   linux_clean          - the linux kernel'
+	@echo ''
+	@echo 'Misc Targets:'
+	@echo '   unittests            - runs the kvm unit tests in the qemu-aarch64 simulated environment'
+
 
 ##
 ## Buildroot
 ##
 
-BR_DEFCONFIG ?= kvm_qemu_aarch64_defconfig
-BR_VERBOSE ?= 0
+BR_DEFCONFIG ?= qemu_aarch64_virt_kvmunittests_defconfig
+BR_VERBOSE ?= $(VERBOSE)
 
 BR_SRC := $(ROOT_DIR)/buildroot
 BR_OUT := $(OUT_DIR)/buildroot
@@ -29,10 +60,75 @@
 
 .PHONY: buildroot
 buildroot:
-	$(BR_MAKE) $(BR_DEFCONFIG)
-	$(BR_MAKE) all
+	+ $(BR_MAKE) $(BR_DEFCONFIG)
+	+ $(BR_MAKE) all
 
 .PHONY: buildroot_clean
 buildroot_clean:
-	$(BR_MAKE) clean
+	+ $(BR_MAKE) clean
+
+
+##
+## kvmunittests
+##
+KUT_CROSS_PREFIX ?= $(CROSS_PREFIX)
+
+KUT_ARCH := "arm64"
+KUT_SRC := $(ROOT_DIR)/kvm-unit-tests
+KUT_OUT := $(OUT_DIR)/kvm-unit-tests
+
+.PHONY: kvmunittests
+kvmunittests:
+	cd $(KUT_SRC) && \
+		./configure --prefix=$(KUT_OUT) --arch=$(KUT_ARCH) \
+			--cross-prefix=$(KUT_CROSS_PREFIX)
+	+ cd $(KUT_SRC) && $(MAKE) install
+
+.PHONY: kvmunittests_clean
+kvmunittests_clean:
+	+ cd $(KUT_SRC) && $(MAKE) clean
+
+
+##
+## Linux kernel
+##
+LINUX_DEFCONFIG ?= defconfig
+LINUX_VERBOSE ?= $(VERBOSE)
+LINUX_CROSS_PREFIX ?= $(CROSS_PREFIX)
+
+LINUX_ARCH := arm64
+LINUX_SRC := $(ROOT_DIR)/linux
+LINUX_OUT := $(OUT_DIR)/linux
+LINUX_MAKE := $(MAKE) ARCH=$(LINUX_ARCH) CROSS_COMPILE=$(LINUX_CROSS_PREFIX) \
+	-C $(LINUX_SRC) V=$(LINUX_VERBOSE) O=$(LINUX_OUT)
+
+.PHONY: linux
+linux:
+	+ $(LINUX_MAKE) defconfig && $(LINUX_MAKE)
+
+
+.PHONY: linux_clean
+linux_clean:
+	+ $(LINUX_MAKE) clean
+	+ $(LINUX_MAKE) mrproper
+
+
+##
+## Run unit tests
+##
+
+MAKE_PID := $(shell echo $$PPID)
+JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))
+JOBS     := $(subst -j,,$(JOB_FLAG))
+ifeq ($(JOBS),)
+	JOBS := "1"
+endif
+
+# Exclude tests that require user interaction or are known to fail.
+KUT_EXCLUDE := "(.+migrat.+)|(pmu-event-introspection)"
+
+.PHONY: unittests
+unittests: buildroot kvmunittests linux
+	@ VERBOSE=$(VERBOSE) $(TEST_SCRIPTS_DIR)/run_tests.sh -j $(JOBS) -t $(KUT_OUT)/share/kvm-unit-tests/ -x $(KUT_EXCLUDE) -l $(LINUX_OUT)/arch/arm64/boot/Image -r $(BR_OUT)/images/rootfs.ext4 -e $(BR_OUT)/host/bin/qemu-system-aarch64
+