#!/usr/bin/make -f
SHELL = /bin/sh -e

# stop python from generating .pyc caches
export PYTHONDONTWRITEBYTECODE=1

# in order to keep output non-intermixed together, disable parallel building
# of different targets in this d/rules but allow running parallel submakes
.NOTPARALLEL:

# this includes pkg-info.mk and defines VENDOR (debian|ubuntu):
include debian/control.mk

ifeq ($(and ${DEB_HOST_MULTIARCH},${DEB_HOST_ARCH}),)
# Fast version of dpkg/architecture.mk defining all vars in one go
   $(foreach d, $(shell dpkg-architecture | sed 's/=/?=/'), $(eval export $d))
endif

# we build in a sub-subdir so strip that from file paths too
export DEB_CFLAGS_MAINT_APPEND = -ffile-prefix-map=../../=

# Disable LTO on non-amd64 builds, see:
# https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1921664
# https://issues.redhat.com/browse/RHEL-7385
ifneq ($(DEB_HOST_ARCH),amd64)
  export DEB_BUILD_MAINT_OPTIONS += optimize=-lto
endif

# get CFLAGS LDFLAGS etc (should come after DEB_*MAINT*)
include /usr/share/dpkg/buildflags.mk

# DEB_BUILD_OPTIONS=parallel=N
MAKEFLAGS += $(subst parallel=,-j,$(filter parallel=%,${DEB_BUILD_OPTIONS}))
NUMJOBS := $(lastword 1 $(subst -j,,$(filter -j%,${MAKEFLAGS})))
# verbose build
V := $(if $(filter terse, ${DEB_BUILD_OPTIONS}),,1)

NINJA = ninja $(if $V,-v) -j${NUMJOBS}
MESON = meson

# list of packages we're supposed to build
BUILD_PACKAGES := $(shell dh_listpackages)

enable-system = $(if $(filter qemu-system,${BUILD_PACKAGES}),y)
enable-user = $(if $(filter qemu-user,${BUILD_PACKAGES}),y)

QEMU_XEN = /usr/libexec/xen-qemu-system-i386
PKGVERSION = Debian ${DEB_VERSION}
sysdatadir = /usr/share/qemu
sysdataidir = debian/qemu-system-data${sysdatadir}
libdir = /usr/lib/${DEB_HOST_MULTIARCH}
mandir = /usr/share/man
man1dir = ${mandir}/man1
FIRMWAREPATH = /usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu

export cross_prefix_alpha = alpha-linux-gnu-
export cross_prefix_aarch64 = aarch64-linux-gnu-
export cross_prefix_arm = arm-linux-gnueabi-
export cross_prefix_hppa = hppa-linux-gnu-
export cross_prefix_hppa64 = hppa64-linux-gnu-
export cross_prefix_i386 = i686-linux-gnu-
export cross_prefix_loongarch64 = loongarch64-linux-gnu-
export cross_prefix_ppc = powerpc-linux-gnu-
export cross_prefix_ppc64 = powerpc64-linux-gnu-
export cross_prefix_riscv64 = riscv64-linux-gnu-
export cross_prefix_s390x = s390x-linux-gnu-

extra-cflags = ${CFLAGS} ${CPPFLAGS}
extra-ldflags = ${LDFLAGS} -Wl,--as-needed

# we add another set of configure options from debian/control
common_configure_opts = \
	--with-pkgversion="$(PKGVERSION)" \
	--prefix=/usr \
	--sysconfdir=/etc \
	--libdir=${libdir} \
	--libexecdir=/usr/lib/qemu \
	--firmwarepath=${FIRMWAREPATH} \
	--localstatedir=/var \
	--mandir=${mandir} \
	--disable-install-blobs \
	--disable-strip \
	--localstatedir=/var \
	--disable-download \
	--disable-containers \
	--disable-relocatable \
	--disable-docs \
	${empty}
# this disables building of qemu-keymap tool (!)
# qemu-keymap might be helpful for qemu-system -k <lang>
# but is -k flag useful these days?
common_configure_opts += --disable-xkbcommon

# Cross compiling support
ifneq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
common_configure_opts  += --cross-prefix=$(DEB_HOST_GNU_TYPE)-
endif

comma:=,

# system-packages, system-archlist-$pkg, system-alias-$arch, system-kvm
# are defined in d/control.mk

# qemu-system subpackages
define install-all-system
$(foreach p,${system-packages},\
  $(call install-system,qemu-system-$p,${system-archlist-$p}\
  ,$(strip $(foreach a,${system-archlist-$p},$(if $(filter $a ${system-alias-$a},${DEB_HOST_ARCH_CPU}),$a)))))
endef

# install-system qemu-system-$pkg, ${system-archlist-$pkg}, [native-qemu-arch]
# install qemu-arch-list binaries with manpages and aliases into pkg
# install kvm link to qemu-system-${kvm-link} if it is not empty
# fills in qemu:Provides and qemu:archlist substvars
define install-system
# ==== installing $1 ===
dh_installdirs -p $1 usr/bin ${man1dir}
mv -t debian/$1/usr/bin/ $(addprefix debian/tmp/usr/bin/qemu-system-, $2)
$(foreach q, $2,\
 echo ".so man1/qemu-system.1" > debian/$1${man1dir}/qemu-system-$q.1
)
dh_link -p $1 \
 $(foreach q, $2, \
   $(if $(filter $3,${system-kvm}), \
            usr/bin/qemu-system-$3 usr/bin/kvm \
            ${man1dir}/qemu-system-$3.1 ${man1dir}/kvm.1) \
   $(foreach a, ${system-alias-$q}, \
     usr/bin/qemu-system-$q usr/bin/qemu-system-$a \
     ${man1dir}/qemu-system-$q.1 ${man1dir}/qemu-system-$a.1 \
  ))
${# note: older make does not understand line-splitting inside $(functions ..)}
echo 'qemu:Provides=$(if $3,qemu-system-native (=${DEB_VERSION})${comma})\
 $(if $(filter $3,${system-kvm}),qemu-kvm (=${DEB_VERSION})${comma})\
 $(patsubst %,% (=${DEB_VERSION})${comma},$(filter-out $1, $(patsubst %, qemu-system-%, any $2 $(foreach q,$2,${system-alias-$q}))))' \
    | tr _ - >> debian/$1.substvars
echo 'qemu:Conflicts=$(if $(filter $3,${system-kvm}),qemu-kvm)' >> debian/$1.substvars
${# construct list `arch1 arch2 (alias) arch3..' for Description and word-wrap it}
echo 'qemu:archlist=$(foreach q,$2,$q$(if ${system-alias-$q}, (${system-alias-$q})))' \
    | sed -E 's/(.{37,45})\s([^(].{9})/\1\$${Newline}  \2/' >> debian/$1.substvars
dh_installdocs -p $1 --link-doc=qemu-system-common
${# keep empty line at the end }
endef

sysdata-components :=
qemu-builds :=

# several builds of qemu binaries:

##############################################
# main system and tools build
configure-qemu: b/qemu/configured
b/qemu/configured: configure
	rm -rf b/qemu; mkdir -p b/qemu
	cd b/qemu && \
	    ../../configure ${common_configure_opts} \
		--extra-cflags="${extra-cflags}" \
		--extra-ldflags="${extra-ldflags}" \
		--$(if ${enable-system},enable,disable)-system \
		--$(if $(filter qemu-guest-agent,${BUILD_PACKAGES}),enable,disable)-guest-agent \
		--disable-user --disable-linux-user \
		--enable-tools \
		--disable-xen \
		--enable-modules \
		$(if ${enable-system},--enable-module-upgrades) \
		$(shell sh debian/extract-config-opts \
		    $(DEB_HOST_ARCH_OS)-$(DEB_HOST_ARCH) debian/control) \
		${QEMU_CONFIGURE_OPTIONS} || \
	   { tail -n20 config.log meson-logs/meson-log.txt && false; }
	touch $@

build-qemu: b/qemu/built
b/qemu/built: b/qemu/configured
	${NINJA} -C b/qemu
	touch $@

ifeq (,$(findstring nocheck, ${DEB_BUILD_OPTIONS} ${DEB_BUILD_PROFILES}))
ifeq (${enable-system},y)
ifneq (sparc64,${DEB_HOST_ARCH}) # tests are broken on sparc64
build-qemu: b/qemu/tested
endif
endif
endif

test-qemu: b/qemu/tested
b/qemu/tested: b/qemu/built
	# ======== begin testing ========
	rm -rf b/qemu/qemu-bundle
	QEMU_MODULE_DIR=${CURDIR}/b/qemu \
	    ${MESON} test -C b/qemu --suite=block -t2 \
		--num-processes=${NUMJOBS} --no-rebuild --print-errorlogs
	# ========= end testing =========
	touch $@

install-qemu: build-qemu
	DESTDIR=${CURDIR}/debian/tmp \
	    ${NINJA} -C b/qemu install

# remove qtest "accel" modules
	rm -f debian/tmp${libdir}/qemu/accel-qtest-*.so

ifeq (${enable-system},y)

	$(call install-all-system)

ifneq ($(filter ${DEB_HOST_ARCH},amd64 i386),)
# qemu-vmsr-helper is x86-specific
	install -m0755 -D -t debian/qemu-system-common/usr/bin/ \
		debian/tmp/usr/bin/qemu-vmsr-helper
	rm debian/tmp/usr/bin/qemu-vmsr-helper
	install -m0644 -p -D -t debian/qemu-system-common/usr/lib/systemd/system/ \
		contrib/systemd/qemu-vmsr-helper.service \
		contrib/systemd/qemu-vmsr-helper.socket
endif

ifeq ($(DEB_HOST_ARCH_OS),linux)

ifeq (${VENDOR},ubuntu)
ifneq ($(filter ${DEB_HOST_ARCH},amd64 i386),)
# on ubuntu *-spice existed, may be used in libvirt xml and scripts - keep links for compatibility
# The sunset for this will be when Ubuntu-Bionic goes out of support which is expected to happen in 2028
	install -m0644 -p -t debian/qemu-system-x86/usr/bin debian/kvm-spice debian/qemu-system-x86_64-spice
	install -m0644 -p -t debian/qemu-system-x86/usr/share/man/man1/ debian/kvm-spice.1
	echo ".so man1/kvm-spice.1" > debian/qemu-system-x86/usr/share/man/man1/qemu-system-x86_64-spice.1
endif # x86
# apport hook is ubuntu-specific
	install -m0644 -p -D -t debian/qemu-system-common/usr/share/apport/package-hooks/ \
		 debian/source_qemu.py
endif # ubuntu

endif # linux

else  # !enable-system

# qemu-system manpage is built regardless of system target
	rm -fv debian/tmp/usr/share/man/man1/qemu.1
# vmsr-helper is built even if --disable-system
	rm -fv debian/tmp/usr/bin/qemu-vmsr-helper

endif # enable-system

ifneq (,$(filter qemu-block-supplemental,${BUILD_PACKAGES}))
	mkdir -p debian/qemu-block-supplemental/${libdir}/qemu
	mv \
	    debian/tmp/${libdir}/qemu/block-gluster.so \
	    debian/tmp/${libdir}/qemu/block-blkio.so \
	         debian/qemu-block-supplemental/${libdir}/qemu
ifeq (${enable-system},y)
	sh debian/gen-module-upgrade.sh qemu-block-supplemental "${PKGVERSION}" ${libdir}/qemu
endif
endif
ifneq (,$(filter qemu-block-extra,${BUILD_PACKAGES}))
	mkdir -p debian/qemu-block-extra/${libdir}/qemu
	mv debian/tmp/${libdir}/qemu/block-*.so \
	         debian/qemu-block-extra/${libdir}/qemu
ifeq (${enable-system},y)
	sh debian/gen-module-upgrade.sh qemu-block-extra "${PKGVERSION}" ${libdir}/qemu
endif
endif

qemu-builds += qemu

##############################################
# microvm build:
configure-microvm: b/microvm/configured
b/microvm/configured: configure debian/microvm-devices.mak
	rm -rf b/microvm; mkdir -p b/microvm
	cp -up debian/microvm-devices.mak configs/devices/x86_64-softmmu/microvm.mak
	cd b/microvm && \
		../../configure ${common_configure_opts} \
		--extra-cflags="${extra-cflags} -DCONFIG_MICROVM_DEFAULT=1" \
		--extra-ldflags="${extra-ldflags}" \
		--without-default-features \
		--target-list=x86_64-softmmu --enable-kvm --disable-tcg \
		--enable-pixman --enable-vnc \
		--enable-virtfs \
		--enable-linux-aio --enable-linux-io-uring \
		--enable-numa \
		--enable-attr \
		--enable-coroutine-pool \
		--audio-drv-list="" \
		--without-default-devices \
		--with-devices-x86_64=microvm \
		--enable-vhost-kernel --enable-vhost-net \
		--enable-vhost-vdpa \
		--enable-vhost-user --enable-vhost-user-blk-server \
		--enable-vhost-crypto \
		--enable-seccomp \
		${QEMU_MICROVM_CONFIGURE_OPTIONS}
	touch $@
build-microvm: b/microvm/qemu-system-x86_64
b/microvm/qemu-system-x86_64: b/microvm/configured
	${NINJA} -C b/microvm qemu-system-x86_64
install-microvm: b/microvm/qemu-system-x86_64
	cp b/microvm/qemu-system-x86_64 debian/qemu-system-x86/usr/bin/qemu-system-x86_64-microvm
	echo ".so man1/qemu-system.1" > debian/qemu-system-x86/usr/share/man/man1/qemu-system-x86_64-microvm.1
# build microvm on amd64 only if system build is enabled
qemu-builds += $(if $(filter ${DEB_HOST_ARCH}-${enable-system},amd64-y),microvm)

##############################################
# xen build (amd64 arch only, i386-softmmu target only)
configure-xen: b/xen/configured
b/xen/configured: configure
	# system build for qemu-system-xen
	rm -rf b/xen; mkdir -p b/xen
	cd b/xen && \
	    ../../configure ${common_configure_opts} \
		--extra-cflags="${extra-cflags}" \
		--extra-ldflags="${extra-ldflags}" \
		--disable-tools \
		--without-default-features \
		--enable-xen --target-list=i386-softmmu \
		--enable-xen-pci-passthrough \
		--disable-tcg --disable-kvm \
		--audio-drv-list= \
		--enable-libusb \
		--enable-pixman --enable-vnc --enable-vnc-jpeg \
		--enable-spice \
		--enable-virtfs --enable-attr --enable-cap-ng \
		${QEMU_XEN_CONFIGURE_OPTIONS}
	touch $@
build-xen: b/xen/built
b/xen/built: b/xen/configured
	${NINJA} -C b/xen qemu-system-i386
	touch $@
install-xen: b/xen/built
	install -m0755 -D b/xen/qemu-system-i386 \
	  debian/qemu-system-xen${QEMU_XEN}
qemu-builds += $(if $(filter qemu-system-xen,${BUILD_PACKAGES}),xen)

##############################################
# user build (static)
# user-targets is defined in d/control.mk
configure-user: b/user/configured
b/user/configured: configure
# do not use debian/configure-opts here, all optional stuff will be enabled
# automatically, dependencies are already verified in the main build
# See LP:#1908331 for --static-pie (the default in qemu) and #1053101
# See https://sourceware.org/bugzilla/show_bug.cgi?id=29514
# use --disable-pie on i386 for now due to #1056739
# (maybe also add arm64 here for gcc12)
	rm -rf b/user; mkdir -p b/user
	cd b/user && \
	    ../../configure ${common_configure_opts} \
		--extra-cflags="${extra-cflags} -DPROVIDE_STUBS_FOR_STATIC" \
		--extra-ldflags="${extra-ldflags} -Wl,-Map=%.map,--no-print-map-discarded" \
		--static \
		$(if $(filter i386,${DEB_HOST_ARCH}),--disable-pie) \
		--disable-plugins \
		--target-list="$(addsuffix -linux-user,${user-targets})"
	touch $@
build-user: b/user/built
b/user/built: b/user/configured
	# we use this invocation to build just the binaries
	${NINJA} -C b/user $(addprefix qemu-,${user-targets})
	touch $@

# aliases for missing ${DEB_HOST_ARCH} names in qemu-user:
user-alias-aarch64 = arm64
user-alias-arm = armel armhf
user-alias-loongarch64 = loong64
user-alias-ppc = powerpc
user-alias-ppc64le = ppc64el
user-alias-x86_64 = amd64

install-user: b/user/built
	install -m0755 -t debian/qemu-user/usr/bin/ -D \
	    $(patsubst %,b/user/qemu-%,${user-targets})
	dh_link -p qemu-user \
 $(foreach t,${user-targets},\
  ${man1dir}/qemu-user.1 ${man1dir}/qemu-$t.1 \
  $(foreach a,${user-alias-$t},\
    usr/bin/qemu-$t usr/bin/qemu-$a \
    ${man1dir}/qemu-$t.1 ${man1dir}/qemu-$a.1\
  ))
	dh_installdocs -p qemu-user-binfmt --link-doc=qemu-user
	./debian/binfmt-install ${user-targets}
# build a Built-Using substvar:
	echo "built-using=$$(\
	  grep -h ^/usr/lib b/user/qemu-*.map ${# all system libs} | \
	  cut -d'(' -f1 ${# strip trailing (file.o)} | \
	  sort -u ${# unique filenames} | \
	  xargs realpath ${# resolve ../} | \
	  xargs dpkg-query -S ${# get package names} | \
	  sed 's/: .*//' ${# strip trailing ': filename'} | \
	  sort -u ${# unique packages} | \
	  xargs dpkg-query -f '$${source:Package} (= $${source:Version}),' -W)" \
	  > debian/qemu-user.substvars
# compatibility symlinks for qemu-user-static (no manpage links for aliases):
	dh_link -p qemu-user-static \
 $(foreach t,${user-targets}, \
   usr/bin/qemu-$t usr/bin/qemu-$t-static \
   ${man1dir}/qemu-user-static.1 ${man1dir}/qemu-$t-static.1 \
   $(foreach a,${user-alias-$t}, \
     usr/bin/qemu-$t-static usr/bin/qemu-$a-static \
  ))

qemu-builds += $(if ${enable-user},user)

##############################################
# docs: build it with sphinx directly
# two sphinx should not run in parallel!
docdir := b/docs
sphinx-build = CONFDIR=/etc/qemu sphinx-build -j auto \
   -Dversion="$$(cat VERSION)" -Drelease="${PKGVERSION}" \
   -d ${docdir}/manual.p ${CURDIR}/docs ${docdir}
${docdir}/qemu-system.1:
	${sphinx-build} -b man
# fixup the q-s-d manpage
	sed -i 's/\\fBqemu(1)\\fP manual page/\\fBqemu-system(1)\\fP manual page (in qemu-system-common package)/' \
		${docdir}/qemu-storage-daemon.1
	mv ${docdir}/qemu.1 ${docdir}/qemu-system.1
${docdir}/html-built:
	${sphinx-build} -b html
# remove links to user/* from the main index
	sed -i '/href="user\//D' ${docdir}/index.html
	touch $@
build-html: ${docdir}/html-built
install-html: build-html
build-man: ${docdir}/qemu-system.1
install-man: build-man

##############################################
# qemu-system-for-host dep-only package
# find the qemu-system-foo package which contains the right binary:
#qemu-system-for-host=$(strip \
#    $(foreach p,${system-packages},\
#        $(if \
#            $(filter \
#                ${system-archlist-$p} $(foreach a,${system-archlist-$p},${system-alias-$a}),\
#                ${DEB_HOST_ARCH_CPU}),\
#            qemu-system-$p)))
install-qemu-system-for-host:
#	$(if ${qemu-system-for-host},,$(error no qemu-system-for-host found for ${DEB_HOST_ARCH_CPU}))
#	echo 'qemu-for-host=${qemu-system-for-host}'
	echo 'qemu:for-host=qemu-system-${DEB_HOST_ARCH_CPU}' \
	  >> debian/qemu-system-for-host.substvars
	dh_installdocs -p qemu-system-for-host --link-doc=qemu-system-common
configure-qemu-system-for-host:
build-qemu-system-for-host:
qemu-builds += $(filter ${BUILD_PACKAGES},qemu-system-for-host)

##############################################
# common rules

qemu-builds += man html

.PHONY: $(addprefix configure-, ${qemu-builds}) \
	$(addprefix build-, ${qemu-builds}) \
	$(addprefix install-, ${qemu-builds}) \
	configure-arch build-arch test-qemu \
	pre-install-arch install-arch binary-arch
configure-arch: $(addprefix configure-, ${qemu-builds})
build-arch: $(addprefix build-, ${qemu-builds})

pre-install-arch:
	dh_testroot
	dh_prep -a
	dh_installdirs -a
install-arch: pre-install-arch $(addprefix install-, ${qemu-builds})
	dh_install -a
	dh_missing -a
	dh_installdocs -a
	dh_installchangelogs -a
	dh_installman -a
	dh_link -a
	dh_installinit -pqemu-guest-agent
	dh_installsystemd -pqemu-guest-agent --no-enable
	dh_installudev -pqemu-guest-agent
	dh_lintian -a
	dh_strip_nondeterminism -a
	dh_compress -a
	dh_fixperms -a
	dh_dwz -a
	dh_strip -a
# qemu-user contains static binaries only, but they might be built
# as static-pie executables and dpkg-shlibdeps complains. Just omit it here.
	dh_shlibdeps -a -Nqemu-user
binary-arch: install-arch binary-helper
binary-arch: a=-a

##############################################
### firmware, qemu-user-data package

### main qemu arch-indep build
# we configure qemu in b/data with default options, so that various
# subcomponents can be built from the main qemu source
b/data/.configured: | b
	rm -rf b/data; mkdir -p b/data
	cd b/data && ../../configure --skip-meson
	touch $@

### linux-user vdso rules
# build vdso-archive containing all our vdso files and include it
# in qemu-user-data to be used when building arch-dependent packages,
# to avoid requiring all cross-compilers on every host architecture.
# Do not remove pre-built vdso files from .orig.tar.gz, because dak
# is picky about build-time deps on packages from the same source
# (we should be able to build without depending on ourselves).
# For this, pkg.qemu.use-upstream-vdso build profile is recognized
# (we do not rebuild or embed vdso files if it is enabled).
# Alternative is to enable pkg.qemu.omit-vdso-build-dep profile
# and build both arch and indep parts in one go, so that a rebuild
# of vdso files for arch-indep step is used in arch step too.
# ${vdso-files} are defined in d/control.mk
vdso-subdirs := $(sort $(dir ${vdso-files}))
vdso-archive = linux-user-vdso.tar.gz

build-vdso: b/${vdso-archive}
# build-vdso is to make multi-line expantion, not possible with inline $(foreach)
define build-vdso
	rm -f ${vdso-files}
	$(foreach d,${vdso-subdirs},\
	@echo == building vdso for $d:
	+${MAKE} -f $d/Makefile.vdso BUILD_DIR=b/data SRC_PATH=.
)
	tar -cvzf $@ --owner=0 --group=0 --numeric-owner ${vdso-files}
endef
b/${vdso-archive}: b/data/.configured
	$(call build-vdso)
install-vdso: b/${vdso-archive}
	install -m0644 -t ${sysdataidir} $<
ifneq (,$(filter $(patsubst %,% %-indep,build install binary), ${MAKECMDGOALS}))
# if we were asked to produce both indep and arch targets, use vdso from local build
b/vdso-updated: b/${vdso-archive}
	touch $@
else # else update vdso files from system
b/vdso-updated: ${sysdatadir}/${vdso-archive}
	rm -f ${vdso-files}
	tar -xvf $<
	touch $@
endif

ifeq (,$(filter pkg.qemu.use-upstream-vdso, ${DEB_BUILD_PROFILES}))
sysdata-components += vdso
vdso-clean = ${vdso-files}
b/user/configured: b/vdso-updated
endif # !pkg.qemu.use-upstream-vdso

### x86 optionrom
build-x86-optionrom: b/data/pc-bios/optionrom/.built
b/data/pc-bios/optionrom/.built: b/data/.configured
	env -u ELF_PACKAGE_METADATA \
	make -C ${@D}
	touch $@
install-x86-optionrom: b/data/pc-bios/optionrom/.built
	install -m0644 -t ${sysdataidir} ${<D}/*.bin
sysdata-components += x86-optionrom

### s390x firmware in pc-bios/s390-ccw
build-s390x-fw: b/data/pc-bios/s390-ccw/.built
b/data/pc-bios/s390-ccw/.built: b/data/.configured
	env -u ELF_PACKAGE_METADATA \
	make -C ${@D} V=$V
	touch $@
install-s390x-fw: b/data/pc-bios/s390-ccw/.built
	install -m0644 -t ${sysdataidir} ${<D}/s390*.img
sysdata-components += s390x-fw

### vof.bin
build-vof: b/data/pc-bios/vof/vof.bin
b/data/pc-bios/vof/vof.bin: b/data/.configured
	env -u ELF_PACKAGE_METADATA \
	${MAKE} -C ${@D} V=$V ${@F}
install-vof: b/data/pc-bios/vof/vof.bin
	install -m0644 -t ${sysdataidir} $<
sysdata-components += vof

### openbios rules
b/openbios/config-host.mak:
	mkdir -p b/openbios
	cd b/openbios && ../../roms/openbios/config/scripts/switch-arch builtin-ppc builtin-sparc32 builtin-sparc64
build-openbios: $(patsubst %,b/openbios/obj-%/.built, ppc sparc32 sparc64)
b/openbios/obj-%/.built: b/openbios/config-host.mak
	env -u ELF_PACKAGE_METADATA \
	${MAKE} -C ${@D} V=${V} EXTRACFLAGS="-ffreestanding -fno-pic -fno-stack-protector"
	@touch $@

install-openbios: build-openbios
	install -m0644 b/openbios/obj-ppc/openbios-qemu.elf ${sysdataidir}/openbios-ppc
	install -m0644 b/openbios/obj-sparc32/openbios-builtin.elf ${sysdataidir}/openbios-sparc32
	install -m0644 b/openbios/obj-sparc64/openbios-builtin.elf ${sysdataidir}/openbios-sparc64
	install -m0644 -t ${sysdataidir} \
		b/openbios/obj-sparc32/QEMU,tcx.bin \
		b/openbios/obj-sparc32/QEMU,cgthree.bin \
		b/openbios/obj-sparc64/QEMU,VGA.bin
sysdata-components += openbios

### powernv firmware in roms/skiboot
build-skiboot: b/skiboot/skiboot.lid
b/skiboot/skiboot.lid: | roms/skiboot/.version
	mkdir -p b/skiboot
# skiboot makefiles makes it difficult to *add* an option to CFLAGS.
# Abuse OPTS= for this, with the default being -Os.
	grep -q '^OPTS=-Os$$' roms/skiboot/Makefile.main || \
	  { echo "review OPTS= in skiboot/Makefile.main"; false; }
	env -u ELF_PACKAGE_METADATA \
	${MAKE} -C b/skiboot -f ${CURDIR}/roms/skiboot/Makefile \
	  SRC=${CURDIR}/roms/skiboot \
	  OPTS='-Os -ffile-prefix-map="${CURDIR}/roms/skiboot/"=' \
	  CROSS_COMPILE=${cross_prefix_ppc64} V=${V}
install-skiboot: b/skiboot/skiboot.lid
	install -m0644 -t ${sysdataidir} $<
sysdata-components += skiboot

### u-boot-e500 (u-boot.e500)
build-u-boot-e500: b/u-boot/build-e500/u-boot
b/u-boot/build-e500/u-boot: | b
	cp -alu roms/u-boot b/
	${MAKE} -C b/u-boot CROSS_COMPILE=${cross_prefix_ppc} O=build-e500 qemu-ppce500_config
	env -u ELF_PACKAGE_METADATA \
	${MAKE} -C b/u-boot CROSS_COMPILE=${cross_prefix_ppc} O=build-e500 V=$V
	${cross_prefix_ppc}strip $@
install-u-boot-e500: b/u-boot/build-e500/u-boot
	install -m0644 $< ${sysdataidir}/u-boot.e500
sysdata-components += u-boot-e500

### u-boot-sam460 (u-boot-sam460-20100605.bin)
build-u-boot-sam460: b/u-boot-sam460ex/u-boot.bin
b/u-boot-sam460ex/u-boot.bin: | b
	cp -alu roms/u-boot-sam460ex b/
	${MAKE} -C b/u-boot-sam460ex CROSS_COMPILE=${cross_prefix_ppc} Sam460ex_config
	env -u LDFLAGS -u OBJCFLAGS -u ELF_PACKAGE_METADATA \
	${MAKE} -C b/u-boot-sam460ex CROSS_COMPILE=${cross_prefix_ppc}
#	${cross_prefix_ppc}strip $@
install-u-boot-sam460: b/u-boot-sam460ex/u-boot.bin | ${sysdataidir}
	install -m0644 $< ${sysdataidir}/u-boot-sam460-20100605.bin
sysdata-components += u-boot-sam460

### qboot, aka bios-microvm
build-qboot: b/qboot/bios.bin
b/qboot/bios.bin: | b
	rm -rf b/qboot
	meson setup roms/qboot b/qboot
	env -u ELF_PACKAGE_METADATA \
	${NINJA} -C b/qboot
install-qboot: b/qboot/bios.bin
	install -m0644 $< ${sysdataidir}/qboot.rom
sysdata-components += qboot

### alpha firmware in roms/palcode-clipper
build-palcode-clipper: b/qemu-palcode/palcode-clipper
b/qemu-palcode/palcode-clipper: | b
	cp -al roms/qemu-palcode b/
#XXX #1019011 (remove OPT= alternative when fixed)
	env -u ELF_PACKAGE_METADATA \
	${MAKE} -C b/qemu-palcode CROSS=${cross_prefix_alpha} -k || \
	${MAKE} -C b/qemu-palcode CROSS=${cross_prefix_alpha} OPT=-O1
	${cross_prefix_alpha}strip b/qemu-palcode/palcode-clipper
install-palcode-clipper: b/qemu-palcode/palcode-clipper
	install -m0644 $< ${sysdataidir}/palcode-clipper
sysdata-components += palcode-clipper

### SLOF
build-slof: b/SLOF/boot_rom.bin
b/SLOF/boot_rom.bin: | b
	cp -al roms/SLOF b/
	env -u LDFLAGS -u CFLAGS -u ELF_PACKAGE_METADATA \
	$(MAKE) -C b/SLOF qemu CROSS=${cross_prefix_ppc64} V=${V}
install-slof: b/SLOF/boot_rom.bin
	install -m0644 $< ${sysdataidir}/slof.bin
sysdata-components += slof

### hppa-firmware (roms/seabios-hppa)
build-hppa-fw: b/hppa-fw/.built
b/hppa-fw/.built: | b
	rm -rf $(dir $@)
	cp -al roms/seabios-hppa $(dir $@)
	env -u ELF_PACKAGE_METADATA \
	${MAKE} PYTHON=python3 OUT=o32/ BITS=32 BIT_SUFFIX=   CROSS_PREFIX=${cross_prefix_hppa}   -C $(dir $@) -f Makefile.parisc all
	${cross_prefix_hppa}strip   -R.note -R.comment $(dir $@)o32/hppa-firmware.img
	env -u ELF_PACKAGE_METADATA \
	${MAKE} PYTHON=python3 OUT=o64/ BITS=64 BIT_SUFFIX=64 CROSS_PREFIX=${cross_prefix_hppa64} -C $(dir $@) -f Makefile.parisc all
	${cross_prefix_hppa64}strip -R.note -R.comment $(dir $@)o64/hppa-firmware64.img
	touch $@
install-hppa-fw: b/hppa-fw/.built
	install -m0644 -t ${sysdataidir} \
	    $(dir $<)o32/hppa-firmware.img \
	    $(dir $<)o64/hppa-firmware64.img
sysdata-components += hppa-fw

### vbootrom (npcm7xx, npcm8xx)
build-vbootrom: b/vbootrom/.built
b/vbootrom/.built: | b
	cp -pa roms/vbootrom b/
	env -u ELF_PACKAGE_METADATA \
	${MAKE} -C b/vbootrom/npcm7xx CROSS_COMPILE=${cross_prefix_arm}
	env -u ELF_PACKAGE_METADATA \
	${MAKE} -C b/vbootrom/npcm8xx CROSS_COMPILE=${cross_prefix_aarch64}
	touch $@
install-vbootrom: build-vbootrom
	install -m0644 \
	   b/vbootrom/npcm7xx/npcm7xx_bootrom.bin \
	   b/vbootrom/npcm8xx/npcm8xx_bootrom.bin \
		-t ${sysdataidir}/
sysdata-components += vbootrom

### misc firmware
build-misc: b/misc/.built
b/misc/.built:
	mkdir -p b/misc
	dtc -o b/misc/bamboo.dtb pc-bios/dtb/bamboo.dts
	dtc -o b/misc/canyonlands.dtb pc-bios/dtb/canyonlands.dts
	dtc -o b/misc/petalogix-ml605.dtb pc-bios/dtb/petalogix-ml605.dts
	dtc -o b/misc/petalogix-s3adsp1800.dtb pc-bios/dtb/petalogix-s3adsp1800.dts
	touch $@
install-misc: build-misc
	install -m0644 b/misc/bamboo.dtb b/misc/canyonlands.dtb \
		-D -t ${sysdataidir}
	install -m0644 b/misc/petalogix-ml605.dtb b/misc/petalogix-s3adsp1800.dtb \
		-D -t ${sysdataidir}
# icon for gtk ui
	install -Dp -m0644 ui/icons/qemu.svg \
	 -t debian/qemu-system-data/usr/share/icons/hicolor/scalable/apps/
	install -Dp -m0644 ui/qemu.desktop \
	  -t debian/qemu-system-data/usr/share/applications/
# icon for sdl2 ui (non-sdl-image version)
	install -Dp -m0644 ui/icons/qemu_32x32.bmp \
	 debian/qemu-system-data/usr/share/icons/hicolor/32x32/apps/qemu.bmp
	install -Dp -m0644 -t debian/qemu-system-data/usr/share/qemu/keymaps/ \
	 $$(ls -1 pc-bios/keymaps/* | fgrep -v /meson.build)
sysdata-components += misc

sysdata-components += html

${sysdataidir}:
	mkdir -p -m0755 $@
b:
	mkdir -p $@

.PHONY: $(addprefix build-  , ${sysdata-components}) \
	$(addprefix install-, ${sysdata-components}) \
	build-indep pre-install-indep install-indep binary-indep
$(addprefix build-  , ${sysdata-components}): | b
$(addprefix install-, ${sysdata-components}): | ${sysdataidir}
build-indep: $(addprefix build-, ${sysdata-components})
pre-install-indep:
	dh_testroot
# dh_prep might undo ${sysdataidir} creation, or even some install-foo?
	dh_prep -i -v
	mkdir -p -m0755 ${sysdataidir}
install-indep: pre-install-indep $(addprefix install-, ${sysdata-components})
	dh_install -i
	dh_installdocs -i
	dh_installchangelogs -i
	dh_lintian -i
	dh_compress -i -Xusr/share/doc/qemu-system-common/config
	dh_fixperms -i
binary-indep: install-indep binary-helper
binary-indep: a=-i

build: build-arch build-indep
install: install-arch install-indep
binary: install-arch install-indep binary-helper
binary: a=
binary-helper:
	dh_installdeb $a
	dh_gencontrol $a
	dh_md5sums $a
	dh_builddeb $a

clean:	debian/control
	dh_clean b/ ${vdso-clean} \
		configs/devices/x86_64-softmmu/microvm.mak \

.PHONY: build install binary binary-helper clean
