| ## |
| ## Folders |
| ## |
| ROOT_DIR := $(CURDIR) |
| OUT_DIR := $(ROOT_DIR)/out |
| LINUX_OUT := $(OUT_DIR)/linux |
| CCACHE_DIR := $(OUT_DIR)/.ccache |
| TEST_SCRIPTS_DIR := $(ROOT_DIR)/build/aarch64-unit-tests |
| |
| ## |
| ## Common options |
| ## |
| VERBOSE ?= 0 |
| CCACHE ?= "" |
| |
| # Find toolchain for current OS |
| UNNAME_S := $(shell uname -s | tr '[:upper:]' '[:lower:]') |
| TOOLCHAIN_CLANG := $(ROOT_DIR)/toolchains/$(UNNAME_S)-x86/clang/clang-r383902 |
| TOOLCHAIN_BINUTILS := $(ROOT_DIR)/toolchains/$(UNNAME_S)-x86/gcc/aarch64-linux-android |
| |
| CUSTOM_KERNEL_IMAGE=0 |
| |
| # KERNEL_IMAGE can be set to use own custom kernel image. |
| ifdef KERNEL_IMAGE |
| CUSTOM_KERNEL_IMAGE=1 |
| else |
| KERNEL_IMAGE := $(LINUX_OUT)/arch/arm64/boot/Image |
| endif |
| |
| ## |
| ## Common targets |
| ## |
| |
| .DEFAULT_GOAL := default |
| |
| .PHONY: default |
| default: kvmunittests linux |
| |
| .PHONY: clean |
| clean: buildroot_clean kvmunittests_clean linux_clean |
| |
| .PHONY: distclean |
| distclean: kvmunittests_clean |
| - rm -rf $(OUT_DIR) |
| |
| .PHONY: all |
| all: buildroot kvmunittests linux |
| |
| .PHONY: help |
| help: |
| @echo 'Generic Targets:' |
| @echo ' default - builds all generic targets except for buildroot' |
| @echo ' all - builds all generic targets' |
| @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 ' test - runs the kvm unit tests in the qemu-aarch64 simulated environment' |
| @echo ' update-prebuilts - generates/update the prebuilt rootfs image (aarch64) and the qemu host (aarch64)' |
| |
| |
| ## |
| ## Buildroot |
| ## |
| |
| BR_DEFCONFIG ?= qemu_aarch64_virt_kvmunittests_defconfig |
| BR_VERBOSE ?= $(VERBOSE) |
| |
| BR_SRC := $(ROOT_DIR)/buildroot |
| BR_OUT := $(OUT_DIR)/buildroot |
| BR_MAKE := $(MAKE) -C $(BR_SRC) V=$(BR_VERBOSE) O=$(BR_OUT) |
| |
| .PHONY: buildroot |
| buildroot: |
| + $(BR_MAKE) $(BR_DEFCONFIG) |
| + $(BR_MAKE) all |
| |
| .PHONY: buildroot_clean |
| buildroot_clean: |
| + $(BR_MAKE) clean |
| |
| |
| ## |
| ## kvmunittests |
| ## |
| KUT_CROSS_PREFIX ?= "aarch64-linux-android-" |
| |
| KUT_ARCH := "arm64" |
| KUT_SRC := $(ROOT_DIR)/kvm-unit-tests |
| KUT_OUT := $(OUT_DIR)/kvm-unit-tests |
| KUT_CC := $(TOOLCHAIN_CLANG)/bin/clang |
| KUT_LD := $(TOOLCHAIN_CLANG)/bin/ld.lld |
| KUT_OBJCOPY := $(TOOLCHAIN_CLANG)/bin/llvm-objcopy |
| KUT_OBJDUMP := $(TOOLCHAIN_CLANG)/bin/llvm-objdump |
| KUT_COMMON_CFLAGS := "-Qunused-arguments -target aarch64-linux-gnueabi -fno-integrated-as -Wno-asm-operand-widths -fpic --gcc-toolchain=$(TOOLCHAIN_BINUTILS)" |
| KUT_PATH := $(TOOLCHAIN_CLANG)/bin:$(TOOLCHAIN_BINUTILS)/bin:$(PATH) |
| |
| |
| .PHONY: kvmunittests |
| kvmunittests: |
| cd $(KUT_SRC) && \ |
| ./configure --prefix=$(KUT_OUT) --arch=$(KUT_ARCH) \ |
| --cc=$(KUT_CC) --ld=$(KUT_LD) \ |
| --objcopy=$(KUT_OBJCOPY) --objdump=$(KUT_OBJDUMP) |
| PATH=$(KUT_PATH) COMMON_CFLAGS=$(KUT_COMMON_CFLAGS) $(MAKE) -C $(KUT_SRC) install |
| |
| .PHONY: kvmunittests_clean |
| kvmunittests_clean: |
| - $(MAKE) -C $(KUT_SRC) clean |
| |
| |
| ## |
| ## Linux kernel |
| ## |
| LINUX_DEFCONFIG ?= defconfig |
| LINUX_VERBOSE ?= $(VERBOSE) |
| LINUX_CROSS_COMPILE ?= "aarch64-linux-gnu-" |
| LINUX_SRC ?= $(ROOT_DIR)/linux |
| |
| LINUX_ARCH := arm64 |
| LINUX_PATH := $(TOOLCHAIN_CLANG)/bin:$(PATH) |
| LINUX_MAKE := \ |
| PATH=$(LINUX_PATH) \ |
| ARCH=$(LINUX_ARCH) \ |
| CROSS_COMPILE=$(LINUX_CROSS_COMPILE) \ |
| $(MAKE) \ |
| LLVM=1 \ |
| GCC_TOOLCHAIN_DIR=$(TOOLCHAIN_BINUTILS)/bin \ |
| -C $(LINUX_SRC) \ |
| V=$(LINUX_VERBOSE) \ |
| O=$(LINUX_OUT) |
| |
| .PHONY: linux |
| linux: |
| + $(LINUX_MAKE) $(LINUX_DEFCONFIG) |
| + $(LINUX_MAKE) |
| |
| .PHONY: linux_image |
| linux_image: |
| # If using own kernel image (KERNEL_IMAGE is set in the environment), then skip. |
| ifeq ($(CUSTOM_KERNEL_IMAGE), 0) |
| echo $(CUSTOM_KERNEL_IMAGE) |
| + $(LINUX_MAKE) $(LINUX_DEFCONFIG) |
| + $(LINUX_MAKE) Image.gz |
| endif |
| |
| .PHONY: linux_clean |
| linux_clean: |
| + $(LINUX_MAKE) clean |
| + $(LINUX_MAKE) mrproper |
| |
| |
| ## |
| ## Generating/Updating prebuilts |
| ## |
| |
| update-prebuilts: \ |
| prebuilts/linux-aarch64/images \ |
| prebuilts/linux-x86/qemu |
| |
| # The rootfs and rom images for qemu |
| prebuilts/linux-aarch64/images: buildroot |
| - rm -rf $@ |
| mkdir -p $@ |
| cp $(BR_OUT)/images/rootfs.ext4 $@ |
| cp $(BR_OUT)/per-package/host-qemu/host/share/qemu/efi-virtio.rom $@ |
| |
| # The qemu binary and the libraries it requires |
| prebuilts/linux-x86/qemu: buildroot |
| - rm -rf $@ |
| mkdir -p $@/bin |
| cp $(BR_OUT)/host/bin/qemu-system-aarch64 $@/bin |
| mkdir -p $@/lib |
| cp $(BR_OUT)/host/lib/lib* $@/lib |
| |
| |
| ## |
| ## 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 |
| |
| KUT_QEMU_BIN := $(ROOT_DIR)/prebuilts/linux-x86/qemu/bin/qemu-system-aarch64 |
| KUT_QEMU_LIB := $(ROOT_DIR)/prebuilts/linux-x86/qemu/lib |
| KUT_ROOTFS_IMAGE := $(ROOT_DIR)/prebuilts/linux-aarch64/images/rootfs.ext4 |
| |
| # Exclude tests that require user interaction or are known to fail. |
| KUT_EXCLUDE := "(.+migrat.+)|(gicv2-.+)|(pmu-event-introspection)|(micro-bench)" |
| |
| .PHONY: test |
| test: kvmunittests linux_image |
| @LD_LIBRARY_PATH=$(KUT_QEMU_LIB):$(LD_LIBRARY_PATH) VERBOSE=$(VERBOSE) \ |
| $(TEST_SCRIPTS_DIR)/run_tests.sh \ |
| -j $(JOBS) \ |
| -t $(KUT_OUT)/share/kvm-unit-tests/ \ |
| -x $(KUT_EXCLUDE) \ |
| -l $(KERNEL_IMAGE) \ |
| -r $(KUT_ROOTFS_IMAGE) \ |
| -e $(KUT_QEMU_BIN) |