xref: /aosp_15_r20/external/crosvm/e2e_tests/guest_under_test/Makefile (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1# Copyright 2020 The ChromiumOS Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5# Builds the kernel and rootfs for the guest used in integration testing.
6#
7# The main artifacts are:
8# target/guest_under_test/bzImage
9# target/guest_under_test/rootfs
10
11ARCH ?= $(shell arch)
12ifeq ($(ARCH), x86_64)
13  KERNEL_ARCH=x86
14  KERNEL_BINARY=bzImage
15  DOCKER_ARCH=amd64
16  CROSS_COMPILE=
17  RUSTFLAGS=
18else ifeq ($(ARCH), aarch64)
19  KERNEL_ARCH=arm64
20  KERNEL_BINARY=Image
21  DOCKER_ARCH=arm64v8
22  CROSS_COMPILE=aarch64-linux-gnu-
23  RUSTFLAGS="-Clinker=aarch64-linux-gnu-ld"
24else
25  $(error Only x86_64 or aarch64 are supported)
26endif
27
28# Build against the musl toolchain, which will produce a statically linked,
29# portable binary that we can run on the alpine linux guest without needing
30# libc at runtime
31RUST_TARGET ?= $(ARCH)-unknown-linux-musl
32
33# We are building everything in target/guest_under_test
34CARGO_TARGET ?= $(shell cargo metadata --no-deps --format-version 1 | \
35	jq -r ".target_directory")
36TARGET ?= $(CARGO_TARGET)/guest_under_test/$(ARCH)
37$(shell mkdir -p $(TARGET))
38
39# Parameteters for building the kernel locally
40KERNEL_REPO ?= https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
41KERNEL_BRANCH ?= v6.1.59
42KERNEL_SRC_BASE ?= $(TARGET)/kernel-source-$(KERNEL_BRANCH)
43KERNEL_SRC_PATCHED ?= $(KERNEL_SRC_BASE)-patched
44KERNEL_BUILD ?= $(TARGET)/kernel-build
45KERNEL_PATCHES ?= "`readlink -f ./kernel/patches`"
46
47################################################################################
48# Main targets
49
50all: $(TARGET)/rootfs $(TARGET)/bzImage
51
52# Clean all local build artifacts, but not downloaded sources.
53clean:
54	rm -rf $(TARGET)/kernel-build $(TARGET)/rootfs-build $(TARGET)/initramfs-build $(TARGET)/rootfs $(TARGET)/bzImage $(TARGET)/initramfs.cpio.gz
55
56clean-all:
57	rm -rf $(TARGET)
58
59x86_64_initramfs: $(TARGET)/initramfs
60
61delegate: $(TARGET)/rootfs-build/delegate
62
63readclock: $(TARGET)/rootfs-build/readclock
64
65################################################################################
66# Build rootfs
67rootfs : ${TARGET}/rootfs
68
69# Build rootfs from Dockerfile and export into squashfs
70$(TARGET)/rootfs: $(TARGET)/rootfs-build/delegate $(TARGET)/rootfs-build/readclock rootfs/Dockerfile
71	# Build image from Dockerfile
72	DOCKER_BUILDKIT=1 docker build -t crosvm_e2e_test_guest $(TARGET)/rootfs-build \
73		-f rootfs/Dockerfile --build-arg ARCH=$(DOCKER_ARCH)
74	# Make sure tar2sqfs is available. If not, print a help message.
75	tar2sqfs --help > /dev/null || \
76		{ \
77			echo 'tar2sqfs is not found. To install, run: `sudo apt install -y squashfs-tools-ng` or something equivalent.' ; \
78			exit 1 ; \
79		}
80	# Create container and export into squashfs, and don't forget to clean up
81	# the container afterwards.
82	set -x && \
83		CONTAINER=$$(docker create crosvm_e2e_test_guest) && \
84		docker export $$CONTAINER | tar2sqfs -c gzip -f $@ && \
85		docker rm $$CONTAINER
86
87# Build and copy delegate binary into rootfs build directory
88$(TARGET)/rootfs-build/delegate: rootfs/delegate/Cargo.toml rootfs/delegate/src/main.rs rootfs/delegate/src/wire_format.rs
89	rustup target add $(RUST_TARGET)
90	CARGO_TARGET_DIR=$(TARGET) RUSTFLAGS=$(RUSTFLAGS) cargo build --target $(RUST_TARGET) --release --manifest-path=rootfs/delegate/Cargo.toml
91	mkdir -p $(TARGET)/rootfs-build
92	cp $(TARGET)/$(RUST_TARGET)/release/delegate $(TARGET)/rootfs-build/delegate
93
94# Build and copy readclock binary into rootfs build directory
95$(TARGET)/rootfs-build/readclock: rootfs/readclock/Cargo.toml rootfs/readclock/src/main.rs rootfs/readclock/src/lib.rs
96	rustup target add $(RUST_TARGET)
97	CARGO_TARGET_DIR=$(TARGET) RUSTFLAGS=$(RUSTFLAGS) cargo build --target $(RUST_TARGET) --release --manifest-path=rootfs/readclock/Cargo.toml
98	mkdir -p $(TARGET)/rootfs-build
99	cp $(TARGET)/$(RUST_TARGET)/release/readclock $(TARGET)/rootfs-build/readclock
100
101################################################################################
102# Build initramfs
103
104# Build initramfs from Containerfile and package as cpio archive
105$(TARGET)/initramfs: $(TARGET)/rootfs-build/delegate initramfs/Containerfile initramfs/init.sh
106	-mkdir -p $(TARGET)/initramfs-build
107	cp initramfs/init.sh $(TARGET)/initramfs-build/init.sh
108	cp $(TARGET)/rootfs-build/delegate $(TARGET)/initramfs-build/delegate
109	podman build -t crosvm_e2e_test_guest_initramfs $(TARGET)/initramfs-build -f initramfs/Containerfile
110	-mkdir -p $(TARGET)/initramfs-build/cpio-base
111	# Create container and export into squashfs, and don't forget to clean up
112	# the container afterwards.
113	set -x; \
114		CONTAINER=$$(podman create crosvm_e2e_test_guest_initramfs); \
115		podman export $$CONTAINER | tar -xf - -C $(TARGET)/initramfs-build/cpio-base; \
116		podman rm $$CONTAINER; \
117		cd $(TARGET)/initramfs-build/cpio-base; \
118		find . -print0 | cpio --null --create --verbose --format=newc | gzip --best > $(TARGET)/initramfs.cpio.gz
119
120################################################################################
121# Build kernel
122
123kernel: $(TARGET)/bzImage
124
125# Make this target PHONY to make sure everything is up to date with the kernel's make recipe.
126# You can use custom kernel source by running:
127# make kernel KERNEL_SRC_PATCHED=${PATH_TO_YOUR_KERNEL}
128# (Note: you have to manually apply the patches applied in %-patched recipe to pass all the tests.)
129.PHONY : $(TARGET)/bzImage
130$(TARGET)/bzImage : $(KERNEL_SRC_PATCHED)
131	mkdir -p $(KERNEL_BUILD)
132	cat kernel/common.config kernel/$(KERNEL_ARCH).config > $(KERNEL_BUILD)/.config
133	make -C $(KERNEL_SRC_PATCHED) O=$(KERNEL_BUILD) \
134		ARCH=$(KERNEL_ARCH) \
135		CROSS_COMPILE=$(CROSS_COMPILE) \
136		-j$(shell nproc)\
137		olddefconfig \
138		$(KERNEL_BINARY)
139	cp $(KERNEL_BUILD)/arch/${KERNEL_ARCH}/boot/$(KERNEL_BINARY) $@
140
141$(KERNEL_SRC_PATCHED): $(KERNEL_SRC_BASE)
142	rm -rf $@.tmp ; true # ignore failure
143	cp -r $(KERNEL_SRC_BASE) $@.tmp
144	git -C $@.tmp am $(KERNEL_PATCHES)/virtio_pvclock.patch
145	mv $@.tmp $@
146
147$(KERNEL_SRC_BASE):
148	rm -rf $@
149	git clone --depth 1 --branch $(KERNEL_BRANCH) $(KERNEL_REPO) $@
150
151.PHONY: clean all update-prebuilts
152