# Contributor: Sergei Lukin <sergej.lukin@gmail.com>
# Contributor: Valery Kartel <valery.kartel@gmail.com>
# Contributor: Jakub Jirutka <jakub@jirutka.cz>
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=qemu
pkgver=10.0.0
pkgrel=1
pkgdesc="QEMU is a generic machine emulator and virtualizer"
url="https://qemu.org/"
arch="all"
license="GPL-2.0-only AND LGPL-2.1-only"
makedepends="
	alsa-lib-dev
	bash
	bison
	capstone-dev
	curl-dev
	flex
	glib-dev
	glib-static
	gnutls-dev
	gtk+3.0-dev
	libaio-dev
	libbpf-dev
	libcap-dev
	libcap-ng-dev
	libjpeg-turbo-dev
	libnfs-dev
	libpng-dev
	libseccomp-dev
	libslirp-dev
	libssh-dev
	liburing-dev
	libusb-dev
	libxml2-dev
	linux-headers
	lzo-dev
	meson
	ncurses-dev
	numactl-dev
	pcre2-static
	perl
	pipewire-dev
	pulseaudio-dev
	py3-sphinx
	py3-sphinx_rtd_theme
	python3
	sdl2-dev
	snappy-dev
	spice-dev
	texinfo
	usbredir-dev
	util-linux-dev
	vde2-dev
	virglrenderer-dev
	vte3-dev
	xfsprogs-dev
	zlib-dev
	zlib-static
	zstd-dev
	"
pkggroups="qemu"
install="$pkgname.pre-install $pkgname.post-install $pkgname.pre-upgrade"

# suid needed for qemu-bridge-helper
# strip fails on .img files
# some tests does not run on our builders
options="suid !strip !check textrels"

subpackages="
	$pkgname-dev
	$pkgname-doc
	$pkgname-lang
	$pkgname-guest-agent:guest
	$pkgname-guest-agent-openrc
	$pkgname-tools:_tools
	$pkgname-hppa-firmware:_hppa_firmware
	$pkgname-ppc-firmware:_ppc_firmware
	$pkgname-s390x-firmware:_s390x_firmware
	$pkgname-sparc-firmware:_sparc_firmware
	$pkgname-sparc64-firmware:_sparc64_firmware
	$pkgname-pr-helper:_pr_helper
	$pkgname-vhost-user-gpu:_vhost_user_gpu
	$pkgname-bridge-helper:bridgehelper
	"

_subsystems="
	arm
	armeb
	hexagon
	i386
	m68k
	microblaze
	microblazeel
	mips
	mipsel
	or1k
	ppc
	riscv32
	sh4
	sh4eb
	sparc
	system-arm
	system-avr
	system-i386
	system-m68k
	system-mips
	system-mipsel
	system-or1k
	system-ppc
	system-riscv32
	system-rx
	system-sh4
	system-sh4eb
	system-sparc
	system-tricore
	system-xtensa
	system-xtensaeb
	xtensa
	xtensaeb
"
case "$CARCH" in
	arm*|x86) ;;
	*) _subsystems="$_subsystems
		aarch64
		aarch64_be
		alpha
		hppa
		loongarch64
		mips64
		mips64el
		mipsn32
		mipsn32el
		ppc64
		ppc64le
		riscv64
		s390x
		sparc32plus
		sparc64
		system-aarch64
		system-alpha
		system-hppa
		system-loongarch64
		system-microblaze
		system-microblazeel
		system-mips64
		system-mips64el
		system-ppc64
		system-riscv64
		system-s390x
		system-sparc64
		system-x86_64
		x86_64
		"
		;;
esac

for _sub in $_subsystems; do
	subpackages="$subpackages $pkgname-$_sub:_subsys"
done

_modules="
	audio-alsa
	audio-oss
	audio-pa
	audio-pipewire
	audio-sdl
	audio-spice
	block-curl
	block-dmg-bz2
	block-nfs
	block-ssh
	chardev-spice
	hw-display-qxl
	hw-display-virtio-gpu
	hw-display-virtio-gpu-gl
	hw-display-virtio-gpu-pci
	hw-display-virtio-gpu-pci-gl
	hw-display-virtio-vga
	hw-display-virtio-vga-gl
	hw-uefi-vars
	hw-s390x-virtio-gpu-ccw
	hw-usb-host
	hw-usb-redirect
	ui-curses
	ui-egl-headless
	ui-gtk
	ui-opengl
	ui-sdl
	ui-spice-app
	ui-spice-core
	"

case "$CARCH" in
x86)
	# ui-dbus has textrels
	_configure_dbus=--disable-dbus-display
	;;
*)
	_modules="$_modules audio-dbus ui-dbus"
	_configure_dbus=--enable-dbus-display
	;;
esac

case "$CARCH" in
arm*|x86) ;;
*)
	makedepends="$makedepends ceph-dev"
	_modules="$_modules block-rbd"
	_configure_rbd="--enable-rbd"
	;;
esac

case "$CARCH" in
armv7|aarch64)
	makedepends="$makedepends xen-dev"
	_configure_xen="--enable-xen"
	;;
x86_64)
	makedepends="$makedepends xen-dev"
	_configure_xen="--enable-xen --enable-xen-pci-passthrough"
	;;
*)
	_configure_xen="--disable-xen"
	;;
esac


for _mod in $_modules; do
	subpackages="$subpackages $pkgname-$_mod:_module"
done
subpackages="$subpackages qemu-modules:_all_modules"

subpackages="$subpackages $pkgname-img"  # -img must be declared the last

source="https://download.qemu.org/qemu-$pkgver.tar.xz
	0006-linux-user-signal.c-define-__SIGRTMIN-MAX-for-non-GN.patch
	xattr_size_max.patch
	MAP_SYNC-fix.patch
	fix-sockios-header.patch
	guest-agent-shutdown.patch
	musl-initialise-msghdr.patch
	fix-strerrorname_np.patch
	liburing.patch

	$pkgname-guest-agent.confd
	$pkgname-guest-agent.initd
	80-kvm.rules
	bridge.conf
	"

# secfixes:
#   8.0.2-r1:
#     - CVE-2023-2861
#   8.0.0-r6:
#     - CVE-2023-0330
#   7.1.0-r4:
#     - CVE-2022-2962
#     - CVE-2022-3165
#   7.0.0-r0:
#     - CVE-2021-4158
#   6.1.0-r0:
#     - CVE-2020-35503
#     - CVE-2021-3507
#     - CVE-2021-3544
#     - CVE-2021-3545
#     - CVE-2021-3546
#     - CVE-2021-3682
#   6.0.0-r2:
#     - CVE-2020-35504
#     - CVE-2020-35505
#     - CVE-2020-35506
#     - CVE-2021-3527
#   6.0.0-r1:
#     - CVE-2021-20181
#     - CVE-2021-20255
#     - CVE-2021-3392
#     - CVE-2021-3409
#     - CVE-2021-3416
#   5.2.0-r0:
#     - CVE-2020-24352
#     - CVE-2020-25723
#     - CVE-2020-25742
#     - CVE-2020-25743
#     - CVE-2020-27661
#     - CVE-2020-27821
#     - CVE-2020-29443
#     - CVE-2020-35517
#     - CVE-2021-20203
#   5.1.0-r1:
#     - CVE-2020-13361
#     - CVE-2020-13362
#     - CVE-2020-14364
#     - CVE-2020-15863
#     - CVE-2020-16092
#     - CVE-2020-17380
#     - CVE-2020-25084
#     - CVE-2020-25085
#     - CVE-2020-25624
#     - CVE-2020-25625
#     - CVE-2020-25741
#     - CVE-2020-28916
#   5.0.0-r0:
#     - CVE-2020-13659
#     - CVE-2020-13754
#     - CVE-2020-13791
#     - CVE-2020-13800
#     - CVE-2020-14415
#     - CVE-2020-15469
#     - CVE-2020-15859
#     - CVE-2020-27616
#     - CVE-2020-27617
#     - CVE-2021-20221
#   4.2.0-r0:
#     - CVE-2020-13765
#   2.8.1-r1:
#     - CVE-2016-7994
#     - CVE-2016-7995
#     - CVE-2016-8576
#     - CVE-2016-8577
#     - CVE-2016-8578
#     - CVE-2016-8668
#     - CVE-2016-8909
#     - CVE-2016-8910
#     - CVE-2016-9101
#     - CVE-2016-9102
#     - CVE-2016-9103
#     - CVE-2016-9104
#     - CVE-2016-9105
#     - CVE-2016-9106
#     - CVE-2017-2615
#     - CVE-2017-2620
#     - CVE-2017-5525
#     - CVE-2017-5552
#     - CVE-2017-5578
#     - CVE-2017-5579
#     - CVE-2017-5667
#     - CVE-2017-5856
#     - CVE-2017-5857
#     - CVE-2017-5898
#     - CVE-2017-5931

_compile_common() {
	"$builddir"/configure \
		--prefix=/usr \
		--localstatedir=/var \
		--sysconfdir=/etc \
		--libexecdir=/usr/lib/qemu \
		--python=/usr/bin/python3 \
		--disable-glusterfs \
		--disable-debug-info \
		--disable-bsd-user \
		--disable-werror \
		--enable-kvm \
		--enable-seccomp \
		--cc="${CC:-gcc}" \
		"$@"
	make ARFLAGS="rc"
}

build() {
	# it pretty much never makes sense to optimise qemu for disk size
	export CFLAGS="$CFLAGS -O2"
	export CXXFLAGS="$CXXFLAGS -O2"
	export CPPFLAGS="$CPPFLAGS -O2"

	mkdir -p "$builddir"/build \
		"$builddir"/build-static

	cd "$builddir"/build-static
	_compile_common \
		--enable-linux-user \
		--disable-system \
		--static \
		--disable-brlapi \
		--disable-bpf \
		--disable-cap-ng \
		--disable-capstone \
		--disable-curl \
		--disable-curses \
		--disable-docs \
		--disable-gcrypt \
		--disable-gnutls \
		--disable-gtk \
		--disable-guest-agent \
		--disable-guest-agent-msi \
		--disable-libnfs \
		--disable-mpath \
		--disable-nettle \
		--disable-numa \
		--disable-sdl \
		--disable-spice \
		--disable-tools

	cd "$builddir"/build
	_compile_common \
		--disable-linux-user \
		--audio-drv-list=oss,alsa,sdl,pa,pipewire \
		--enable-bpf \
		--enable-cap-ng \
		--enable-capstone \
		--enable-curl \
		--enable-curses \
		--enable-docs \
		--enable-gtk \
		--enable-guest-agent \
		--enable-libnfs \
		--enable-libssh \
		--enable-linux-aio \
		--enable-lzo \
		--enable-modules \
		--enable-numa \
		--enable-pie \
		--enable-sdl \
		--enable-snappy \
		--enable-spice \
		--enable-tpm \
		--enable-usb-redir \
		--enable-vde \
		--enable-vhost-net \
		--enable-virglrenderer \
		--enable-virtfs \
		--enable-vnc \
		--enable-vnc-jpeg \
		--enable-zstd \
		$_configure_rbd \
		$_configure_dbus \
		$_configure_xen
}

check() {
	cd "$builddir"/build

	# XXX: ESSIV crypto tests are disabled, see test-crypto-ivgen-skip-essiv.patch.
	make check V=1
}

package() {
	cd "$builddir"/build-static
	make DESTDIR="$pkgdir" install

	cd "$builddir"/build
	make DESTDIR="$pkgdir" install

	install -Dm640 -g qemu "$srcdir"/bridge.conf \
		"$pkgdir"/etc/qemu/bridge.conf

	install -Dm644 "$srcdir"/80-kvm.rules \
		"$pkgdir"/usr/lib/udev/rules.d/80-kvm.rules

	# qemu-bridge-helper needs suid to create tunX devices;
	# allow only users in the qemu group to run it.
	chmod 04710 "$pkgdir"/usr/lib/qemu/qemu-bridge-helper
	chgrp qemu "$pkgdir"/usr/lib/qemu/qemu-bridge-helper

	# Do not install HTML docs.
	rm -rf "$pkgdir"/usr/share/doc
	# remove accel-qtest-* modules, not needed for package
	rm -f "$pkgdir"/usr/lib/qemu/accel-qtest-*

	install -Dm755 "$srcdir"/$pkgname-guest-agent.initd \
		"$pkgdir"/etc/init.d/$pkgname-guest-agent
	install -Dm644 "$srcdir"/$pkgname-guest-agent.confd \
		"$pkgdir"/etc/conf.d/$pkgname-guest-agent
}

_subsys() {
	local name=${1:-"${subpkgname#"$pkgname"-}"}
	pkgdesc="Qemu ${name/-/ } emulator"
	options=""
	depends=""
	case "$name" in
		system*) depends="qemu";;
	esac

	amove usr/bin/qemu-$name

	local _arch=${name#system-}
	case "$name" in
		system-aarch64|system-arm|system-loongarch64)
			amove usr/share/qemu/edk2-$_arch-\*.fd
			;;
		system-riscv64)
			amove \
				usr/share/qemu/edk2-riscv-\*.fd \
				usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin
			;;
		system-riscv32)
			amove usr/share/qemu/opensbi-riscv32-generic-fw_dynamic.bin
			;;
		system-i386|system-x86_64)
			provides="qemu-accel-tcg-$_arch"
			amove usr/share/qemu/edk2-$_arch-\*.fd
			;;
		system-s390x|system-hppa|system-ppc|system-sparc*)
			depends="$pkgname-$_arch-firmware"
			;;
	esac
}

_tools() {
	pkgdesc="QEMU support tools"
	depends=""
	options=""
	amove usr/bin/qemu-edid \
		usr/bin/qemu-keymap \
		usr/bin/elf2dmp
}

_s390x_firmware() {
	pkgdesc="QEMU s390x boot devices"
	depends=""
	amove usr/share/qemu/s390-ccw.img
}

_hppa_firmware() {
	pkgdesc="QEMU hppa firmware"
	depends=""
	amove usr/share/qemu/hppa-firmware.img
}

_ppc_firmware() {
	pkgdesc="QEMU ppc firmware"
	depends=""
	amove usr/share/qemu/openbios-ppc
}

_sparc_firmware() {
	pkgdesc="QEMU sparc firmware"
	depends=""
	amove usr/share/qemu/openbios-sparc32
}

_sparc64_firmware() {
	pkgdesc="QEMU sparc firmware"
	depends=""
	amove usr/share/qemu/openbios-sparc64
}

_vhost_user_gpu() {
	pkgdesc="QEMU vhost user GPU device"
	depends=""
	options=""
	amove usr/lib/qemu/vhost-user-gpu \
		usr/share/qemu/vhost-user/50-qemu-gpu.json
}

_pr_helper() {
	pkgdesc="QEMU pr helper utility"
	amove usr/bin/qemu-pr-helper
}

img() {
	pkgdesc="QEMU command line tool for manipulating disk images"
	depends=""
	options=""

	mkdir -p "$subpkgdir"/usr/bin
	mv "$pkgdir"/usr/bin/qemu-img \
		"$pkgdir"/usr/bin/qemu-io \
		"$pkgdir"/usr/bin/qemu-nbd \
		"$pkgdir"/usr/bin/qemu-storage-daemon \
		"$subpkgdir"/usr/bin/

	# We exploit the fact that -img subpackage are created last
	# and check that we done have new systems that belongs in
	# subpackage.
	local path= retval=0
	for path in "$pkgdir"/usr/bin/qemu-system-* "$pkgdir"/usr/lib/qemu/*.so; do
		if [ -r "$path" ]; then
			error "Please create a subpackage for ${path##*/}"
			retval=1
		fi
	done
	return $retval
}

guest() {
	pkgdesc="QEMU guest agent"
	depends=""
	options=""

	mkdir -p "$subpkgdir"/usr/bin
	mv "$pkgdir"/usr/bin/qemu-ga "$subpkgdir"/usr/bin/
}

_module() {
	local _mod=${subpkgname#qemu-}
	local _class=${_mod%%-*}
	local _m=${_mod#*-}
	pkgdesc="Qemu $_m $_class module"
	case "$_mod" in
		# Keep in sync with module_dep() found in code
		audio-dbus) depends="qemu-ui-dbus" ;;
		ui-egl-headless|ui-gtk|ui-dbus|ui-sdl|ui-spice-core) depends="qemu-ui-opengl" ;;
		ui-spice-app) depends="qemu-ui-spice-core qemu-chardev-spice" ;;
		chardev-spice|chardev-spice|hw-display-qxl) depends="qemu-ui-spice-core" ;;
		hw-display-virtio-gpu-gl) depends="qemu-hw-display-virtio-gpu qemu-ui-opengl" ;;
		hw-display-virtio-vga-gl) depends="qemu-hw-display-virtio-vga" ;;
		# FIXME upstream is missing some module deps
		hw-display-virtio-gpu-pci-gl) depends="qemu-hw-display-virtio-gpu-pci qemu-hw-display-virtio-gpu-gl" ;;
		hw-display-virtio-vga|hw-s390x-virtio-gpu-ccw|hw-display-virtio-gpu-pci) depends="qemu-hw-display-virtio-gpu" ;;
	esac

	mkdir -p "$subpkgdir"/usr/lib/qemu
	mv "$pkgdir"/usr/lib/qemu/$_mod.so \
		"$subpkgdir"/usr/lib/qemu/
}

_all_modules() {
	pkgdesc="Meta package for all qemu modules"
	local _i
	for _i in $_modules; do
		depends="$depends qemu-$_i"
	done
	mkdir -p "$subpkgdir"
}

bridgehelper() {
	pkgdesc="QEMU SUID helper for bridged networking"
	install_if="$pkgname=$pkgver-r$pkgrel"

	amove usr/lib/qemu/qemu-bridge-helper \
		etc/qemu/bridge.conf
}

sha512sums="
2215458ed8be3ab0b0032fe2a96e79183f5fc2da323d927018412ea3d980b022a07ba87d4f446229eaaa7d1b19a577d438dbcaa3af3bd537c7720b56734a2d8b  qemu-10.0.0.tar.xz
b392f229e631d149d28eb952dcd507d9e5b6975cbba123fd3dab10860fa1936d5035d8e266926652acc1d7cde6874c440beccd33d729bf346769d2c138ebbc01  0006-linux-user-signal.c-define-__SIGRTMIN-MAX-for-non-GN.patch
2c6b3b22877674f870958bb0c74ad85c814f01c98fb123142b1ce77d89adf5c08626e6eade7f627090a53b48f5cebe2a535547804345648cff91dd66f90c2d5b  xattr_size_max.patch
7672a3518050f275219920f2cb088f6991ac810dba077856129d779fdf45a3e8c0302c8ca4aa58c0c38e44af80f56404006b3f250e4921fb364cd6fe7149e6ea  MAP_SYNC-fix.patch
54d26c3c44730fbd2a155431558fba6a1a3f25d8c057a8e5b8b0d802cb2b6c8a12545a16069fff1b9888a15d6cb087e9750d5e2c310dfc1a3fc756509d3d963e  fix-sockios-header.patch
3e36d752fc2d7eab65568b731c3a21ed534fbfeee43ff8faf4aff95bbe29b74cd9d7013c28f37b86cfbb3ec1e189d5deef36017c06f20b5c732ab50a36b39f51  guest-agent-shutdown.patch
7a6340df8aa28811af20cd23b98ba95fc8072d4d4d3a2d497604386396892cf26716d0755821e47d02c8eded203133d7dde100537c117e2a047179e4f93883cf  musl-initialise-msghdr.patch
7df4b0979d11fb0b7d2dbb073d7249677b0f51381dfbeb1bec2e44d29dd6e1d752468d7f9fb5b42deed6bdf184e81358e7b6dc54b36db326f3336cd6121a1a60  fix-strerrorname_np.patch
75979455abcd9d9f25a966d829d578a06691163e297247c045ce67f94ebc916850b7be1080024a9db6bba9e3f7b88a8cc486f364fb7b028804862bc8634f00e4  liburing.patch
d90c034cae3f9097466854ed1a9f32ab4b02089fcdf7320e8f4da13b2b1ff65067233f48809911485e4431d7ec1a22448b934121bc9522a2dc489009e87e2b1f  qemu-guest-agent.confd
1cd24c2444c5935a763c501af2b0da31635aad9cf62e55416d6477fcec153cddbe7de205d99616def11b085e0dd366ba22463d2270f831d884edbc307c7864a6  qemu-guest-agent.initd
9b7a89b20fcf737832cb7b4d5dc7d8301dd88169cbe5339eda69fbb51c2e537d8cb9ec7cf37600899e734209e63410d50d0821bce97e401421db39c294d97be2  80-kvm.rules
749efa2e764006555b4fd3a8e2f6d1118ad2ea4d45acf99104a41a93cfe66dc9685f72027c17d8211e5716246c2a52322c962cf4b73b27541b69393cd57f53bb  bridge.conf
"
