#!/bin/sh
# $Id: qemu.SlackBuild,v 1.53 2022/05/28 00:19:17 root Exp root $
# Copyright 2007, 2008, 2009, 2010, 2012, 2016, 2017, 2019, 2020, 2021  Eric Hameleers, Eindhoven, Netherlands
# All rights reserved.
#
#   Permission to use, copy, modify, and distribute this software for
#   any purpose with or without fee is hereby granted, provided that
#   the above copyright notice and this permission notice appear in all
#   copies.
#
#   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
#   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#   IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# Copyright 2013-2015  Edward Koenig, Vancouver, USA <kingbe#   SUCH DAMAGE.

# Thanks to Edward Koenig <kingbeowulf@gmail.com> for inspiration.

# -----------------------------------------------------------------------------
#
# Slackware SlackBuild script 
# ===========================
# By:          Eric Hameleers <alien@slackware.com>
# For:         qemu
# Descr:       a generic machine emulator and virtualizer
# URL:         http://qemu.org/
# Build needs: 
# Needs:       device-tree-compiler, vde, virglrenderer
# Changelog:  
# 0.7.0-1:     02/may/2005 by Eric Hameleers <alien@slackware.com>
#              * Build the "stable" 0.7.0 release.
# 0.7.1-1:     28/jul/2005 by Eric Hameleers <alien@slackware.com>
#              * Build the "stable" 0.7.1 release.
# 0.7.1-2:     29/jul/2005 by Eric Hameleers <alien@slackware.com>
#              * Kqemu got bumped to 0.7.1-1 (linux 2.6 kernel bugfix
#                "kqemu: Unknown symbol __PAGE_KERNEL_EXEC").
# 0.7.1-3:     06/aug/2005 by Eric Hameleers <alien@slackware.com>
#              * Added adlib support (--enable-adlib).
# 0.7.2-1:     11/sep/2005 by Eric Hameleers <alien@slackware.com>
#              * Update to 0.7.2
# 0.8.0-1:     03/jan/2006 by Eric Hameleers <alien@slackware.com>
#              * Update to 0.8.0
# 0.8.0-2:     22/feb/2006 by Eric Hameleers <alien@slackware.com>
#              * Enable ALSA driver.
# 20060404-1:  04/apr/2006 by Eric Hameleers <alien@slackware.com>
#              * Updated CVS snapshot.
#                Kqemu now builds separately against pre-installed QEMU.
# 20060413-1:  14/apr/2006 by Eric Hameleers <alien@slackware.com>
#              * Updated CVS snapshot. Contains the new vnc frontend and a
#                usbtablet to use with the vnc frontend (absolute mouse pos.)
# 20060425-1:  25/apr/2006 by Eric Hameleers <alien@slackware.com>
#              * Updated CVS snapshot (PC speaker support was added).
# 20060425-2:  25/apr/2006 by Eric Hameleers <alien@slackware.com>
#              * Built against a new CVS snapshot of libvncserver (20060425)
# 20060426-1:  26/apr/2006 by Eric Hameleers <alien@slackware.com>
#              * Update in CVS, adds SSE3 support. Mainly updated because
#                kqemu-1.3.0pre6 is out and I was compiling anyway :-)
# 0.8.1-1:     08/may/2006 by Eric Hameleers <alien@slackware.com>
#              * A new official release. New since last CVS build: a built-in
#                VNC server, no more need for the external RFB patch.
# 0.8.1-2:     20/may/2006 by Eric Hameleers <alien@slackware.com>
#              * Patch the mouse problem experiencing an "invisible wall".
# 0.8.2-1:     22/jun/2006 by Eric Hameleers <alien@slackware.com>
#              * New release.
# 0.9.0-1:     06/feb/2007 by Eric Hameleers <alien@slackware.com>
#              * New release. Good news: the kqemu kernel module is released
#                under the GPL.
# 20070727-1:  27/jul/2007 by Eric Hameleers <alien@slackware.com>
#              * A CVS snapshot to try with Slackware 12.0
# 20070820-1:  20/aug/2007 by Eric Hameleers <alien@slackware.com>
#              * New CVS snapshot. Remember, on Slackware 12.0 you need to
#                install gcc3 to build this. Qemu can not be compiled with gcc4.
#                I have gcc3 packages that can be installed alongside gcc4, qemu
#                will find and use it: get them from
#                http://www.slackware.com/~alien/slackbuilds/gcc34/
#                Use another way to derive the VERSION for CVS snapshots.
# 20071122-1:  22/nov/2007 by Eric Hameleers <alien@slackware.com>
#              * New CVS snapshot, extracted right out of the repository since
#                the snapshot URL is dead.
#                Apply a patch to fix RGB -> BGR conversion when running in
#                a VNC client.
# 0.9.1-1:     07/jan/2008 by Eric Hameleers <alien@slackware.com>
#              * New release. 
# 20081201-1:  01/dec/2008 by Eric Hameleers <alien@slackware.com>
#              * Snapshot build
# 20090113-1:  13/jan/2009 by Eric Hameleers <alien@slackware.com>
#              * New snapshot
# 20090114-1:  14/jan/2009 by Eric Hameleers <alien@slackware.com>
#              * New snapshot - it turns out that the pre-packaged snapshots
#                are not up to date, so now the script checks out from SVN.
# 0.10.0-1:    10/mar/2009 by Eric Hameleers <alien@slackware.com>
#              * New release. 
# 0.12.4-1:    27/may/2010 by Eric Hameleers <alien@slackware.com>
#              * After a long hiatus, let's pick up this build once more.
# 1.0.1-1:     18/feb/2012 by Eric Hameleers <alien@slackware.com>
#              * After another long hiatus, let's pick up this build...
#                once more. This time to complement my qemu-kvm package which
#                I limited to KVM supported architecture exclusively.
# 1.2.0-1:     06/sep/2012 by Eric Hameleers <alien@slackware.com>
#              * New release.
# 1.3.0-1:     17/dec/2012 by Eric Hameleers <alien@slackware.com>
#              * New release, closing the gap between QEMU and its fork,
#                qemu-kvm.
#                Despite some remaining minor differences between qemu-kvm
#                and QEMU, it is possible to switch from qemu-kvm to QEMU
#                as soon as your guests can be rebooted.
# 2.5.0-1:     01/mar/2016 by Eric Hameleers <alien@slackware.com>
#              * New release, long overdue.  Add some provisions to pick up
#                additional functionality on newer Slackware releases.
# 2.9.0-1:     30/apr/2017 by Eric Hameleers <alien@slackware.com>
#              * New release, long overdue again... but this needed a rebuild
#                on -current.
# 3.1.0-1:     16/feb/2019 by Eric Hameleers <alien@slackware.com>
#              * New release, long overdue again... but this needed a rebuild
#                on -current.
# 4.2.0-1:     22/jan/2020 by Eric Hameleers <alien@slackware.com>
#              * New release, long overdue again... but this needed a rebuild
#                on -current.
# 5.0.0-1:     07/may/2020 by Eric Hameleers <alien@slackware.com>
#              * New release.
# 6.2.0-1:     21/dec/2021 by Eric Hameleers <alien@slackware.com>
#              * Update.
# 6.2.0-2:     27/may/2022 by Eric Hameleers <alien@slackware.com>
#              * Remove JACK support.
# 
# Run 'sh qemu.SlackBuild' to build a Slackware package.
# The package (.txz) plus descriptive .txt file are created in /tmp .
# Install using 'installpkg'. 
#
# -----------------------------------------------------------------------------

# Set initial variables:

PRGNAM=qemu
PRGNAM2=qemu-guest-agent
VERSION=${VERSION:-"6.2.0"}
BUILD=${BUILD:-2}
NUMJOBS=${NUMJOBS:-" -j$(nproc) "}
TAG=${TAG:-alien}

# The documentation:
DOCS="COPYING* Changelog LICENSE MAINTAINERS README* VERSION"

# Statically compiled into the package to enable USB redirection on
# Slackware before 14.2:
LIBUSB=${LIBUSB:-1.0.24}

# Support for the SPICE protocol is configured automatically by the script,
# If you want to _prevent_ support for SPICE even though the spice-server
# is installed on your computer, then set USE_SPICE="--disable-spice" here:
USE_SPICE=""

# Allow user to specify a specific set of supported audio backends:
AUDIO_DRV=${AUDIO_DRV:-""}

# Where do we look for sources?
SRCDIR=$(cd $(dirname $0); pwd)

# Place to build (TMP) package (PKG) and output (OUTPUT) the program:
TMP=${TMP:-/tmp/build}
PKG=$TMP/package-$PRGNAM
PKG2=$TMP/package-${PRGNAM2}
OUTPUT=${OUTPUT:-/tmp}

SOURCE[0]="$SRCDIR/${PRGNAM}-${VERSION}.tar.xz"
SRCURL[0]="https://download.qemu.org/${PRGNAM}-${VERSION}.tar.xz"

SOURCE[1]="$SRCDIR/libusb-${LIBUSB}.tar.bz2"
SRCURL[1]="https://github.com/libusb/libusb/releases/download/v${LIBUSB}/libusb-${LIBUSB}.tar.bz2"

##
## --- with a little luck, you won't have to edit below this point --- ##
##

# Automatically determine the architecture we're building on:
MARCH=$( uname -m )
if [ -z "$ARCH" ]; then
  case "$MARCH" in
    i?86)    export ARCH=i586 ;;
    armv7hl) export ARCH=$MARCH ;;
    arm*)    export ARCH=arm ;;
    # Unless $ARCH is already set, use uname -m for all other archs:
    *)       export ARCH=$MARCH ;;
  esac
fi
# Set CFLAGS/CXXFLAGS and LIBDIRSUFFIX:
case "$ARCH" in
  i?86)      SLKCFLAGS="-O2 -march=${ARCH} -mtune=i686"
             SLKLDFLAGS=""; LIBDIRSUFFIX=""
             KVMARCH="i386"
             ;;
  x86_64)    SLKCFLAGS="-O2 -fPIC"
             SLKLDFLAGS="-L/usr/lib64"; LIBDIRSUFFIX="64"
             KVMARCH="x86_64"
             ;;
  armv7hl)   SLKCFLAGS="-O2 -march=armv7-a -mfpu=vfpv3-d16"
             SLKLDFLAGS=""; LIBDIRSUFFIX=""
             KVMARCH=""
             ;;
  *)         SLKCFLAGS=${SLKCFLAGS:-"O2"}
             SLKLDFLAGS=${SLKLDFLAGS:-""}; LIBDIRSUFFIX=${LIBDIRSUFFIX:-""}
             KVMARCH=""
             ;;
esac

case "$ARCH" in
    arm*)    TARGET=$ARCH-slackware-linux-gnueabi ;;
    *)       TARGET=$ARCH-slackware-linux ;;
esac

# Exit the script on errors:
set -e
trap 'echo "$0 FAILED at line $LINENO!" | tee $OUTPUT/error-${PRGNAM}.log' ERR
# Catch unitialized variables:
set -u
P1=${1:-1}

# Save old umask and set to 0022:
_UMASK_=$(umask)
umask 0022

# Create working directories:
mkdir -p $OUTPUT          # place for the package to be saved
mkdir -p $TMP/tmp-$PRGNAM # location to build the source
mkdir -p $PKG $PKG2       # place for the packages to be built
rm -rf $PKG/* $PKG2/*     # always erase old package's contents
rm -rf $TMP/tmp-$PRGNAM/* # remove the remnants of previous build
rm -rf $OUTPUT/{configure,make,install,error,makepkg}-$PRGNAM.log
                          # remove old log files

# Source file availability:
for (( i = 0; i < ${#SOURCE[*]}; i++ )) ; do
  if ! [ -f ${SOURCE[$i]} ]; then
    echo "Source '$(basename ${SOURCE[$i]})' not available yet..."
    # Check if the $SRCDIR is writable at all - if not, download to $OUTPUT
    [ -w "$SRCDIR" ] || SOURCE[$i]="$OUTPUT/$(basename ${SOURCE[$i]})"
    if [ -f ${SOURCE[$i]} ]; then echo "Ah, found it!"; continue; fi
    if ! [ "x${SRCURL[$i]}" == "x" ]; then
      echo "Will download file to $(dirname $SOURCE[$i])"
      wget -nv -T 20 -O "${SOURCE[$i]}" "${SRCURL[$i]}" || true
      if [ $? -ne 0 -o ! -s "${SOURCE[$i]}" ]; then
        echo "Fail to download '$(basename ${SOURCE[$i]})'. Aborting the build."
        mv -f "${SOURCE[$i]}" "${SOURCE[$i]}".FAIL
        exit 1
      fi
    else
      echo "File '$(basename ${SOURCE[$i]})' not available. Aborting the build."
      exit 1
    fi
  fi
done

if [ "$P1" == "--download" ]; then
  echo "Download complete."
  exit 0
fi

# --- PACKAGE BUILDING ---

echo "++"
echo "|| $PRGNAM-$VERSION"
echo "++"

cd $TMP/tmp-$PRGNAM
echo "Extracting the source archive(s) for $PRGNAM..."
tar -xvf ${SOURCE[0]}
tar -xvf ${SOURCE[1]}
chown -R root:root *
chmod -R u+w,go+r-w,a+X-s *

echo "Building libusb (static lib)..."

# Statically compile libusb into qemu to enable USB passthrough
# on older Slackware releases:
# Thanks to SBo script for the idea
cd libusb-${LIBUSB}
  CFLAGS="$SLKCFLAGS" \
  LDFLAGS="$SLKLDFLAGS" \
  ./configure \
    --prefix=$TMP/tmp-$PRGNAM/qemudeps \
    --disable-shared \
    --enable-static \
    --build=$TARGET \
    2>&1 | tee $OUTPUT/configure-${PRGNAM}.log
  make $NUMJOBS 2>&1 | tee $OUTPUT/make-${PRGNAM}_libusb.log
  make install 2>&1 | tee $OUTPUT/install-${PRGNAM}_libusb.log
cd ..

echo "Building QEMU..."
cd ${PRGNAM}-${VERSION}

# Care for users who used "su" instead of "su -":
if ! which texi2html 1>/dev/null 2>/dev/null ; then
  export PATH=$PATH:/usr/share/texmf/bin
fi

# Create the list of audio backends this package will support:
if [ -z "$AUDIO_DRV" ]; then
  AUDIO_DRV="sdl,alsa,oss"
  # Support PulseAudio if it is installed on the computer:
  if pkg-config --exists libpulse 2>/dev/null ; then
    AUDIO_DRV="pa,${AUDIO_DRV}"
  fi
fi

# Support nettle if it is installed on the computer:
if pkg-config --exists nettle 2>/dev/null ; then
  USE_NETTLE="${USE_NETTLE:---enable-nettle}"
else
  USE_NETTLE="${USE_NETTLE:---disable-nettle}"
fi

# Support uring if it is installed on the computer:
if pkg-config --exists liburing 2>/dev/null ; then
  USE_URING="${USE_URING:---enable-linux-io-uring}"
else
  USE_URING="${USE_URING:---disable-linux-io-uring}"
fi

# Support the SPICE protocol if it is installed on the computer:
if pkg-config --exists spice-server 2>/dev/null ; then
  USE_SPICE="${USE_SPICE:---enable-spice}"
else
  USE_SPICE="${USE_SPICE:---disable-spice}"
fi

# If you want all the exotic target platforms, then you should remove
# the "--target-list" line from the 'configure' block below because we only
# build a relevant subset.

# Ensure that libusb static libs are used:
sed -i configure \
  -e 's/--cflags libusb-1.0/& --static/' \
  -e 's/--libs libusb-1.0/& --static/'

mkdir -p build-$PRGNAM
cd build-$PRGNAM
  PKG_CONFIG_PATH="$TMP/tmp-$PRGNAM/qemudeps/lib/pkgconfig" \
  LDFLAGS="$(pkg-config --libs libusb-1.0 --static) -latomic $SLKLDFLAGS" \
  CFLAGS="$SLKCFLAGS" \
  CXXFLAGS="$SLKCFLAGS" \
  ../configure \
    --prefix=/usr \
    --libdir=/usr/lib${LIBDIRSUFFIX} \
    --sysconfdir=/etc \
    --localstatedir=/var \
    --mandir=/usr/man \
    --docdir=/usr/doc/$PRGNAM-$VERSION \
    --enable-gtk \
    --enable-jemalloc \
    --enable-kvm \
    --enable-sdl \
    --enable-system \
    --enable-vde \
    --enable-virtfs \
    --enable-vnc --enable-vnc-sasl --enable-vnc-jpeg \
    --target-list=i386-softmmu,x86_64-softmmu,i386-linux-user,x86_64-linux-user,arm-softmmu,arm-linux-user,armeb-linux-user \
    --audio-drv-list=${AUDIO_DRV} \
    ${USE_NETTLE} \
    ${USE_SPICE} \
    ${USE_URING} \
    2>&1 | tee $OUTPUT/configure-${PRGNAM}.log

  # Compile and install into $PKG:
  ninja $NUMJOBS 2>&1 | tee $OUTPUT/make-${PRGNAM}.log
  DESTDIR=$PKG ninja install \
    2>&1 |tee $OUTPUT/install-${PRGNAM}.log
cd - 1>/dev/null

# Install udev rules for /dev/kvm - make sure that your user belongs to
# the "kvm" group; create that group first:
mkdir -p $PKG/lib/udev/rules.d/
install -m0644 $SRCDIR/65-kvm.rules $PKG/lib/udev/rules.d/65-kvm.rules

# Create "qemu-kvm" symlink. some 3rd party frontends look for it:
[ ! -z $KVMARCH ] && ln -s qemu-system-$KVMARCH $PKG/usr/bin/qemu-kvm

# Add documentation:
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
cp -a $DOCS $PKG/usr/doc/$PRGNAM-$VERSION || true
cat $SRCDIR/$(basename $0) > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
chown -R root:root $PKG/usr/doc/$PRGNAM-$VERSION
find $PKG/usr/doc -type f -exec chmod 644 {} \;

# Compress the man page(s):
if [ -d $PKG/usr/man ]; then
  find $PKG/usr/man -type f -name "*.?" -exec gzip -9f {} \;
  for i in $(find $PKG/usr/man -type l -name "*.?") ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
fi

# Strip binaries:
find $PKG | xargs file | grep -e "executable" -e "shared object" \
  | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true

# Clean up empty files and directories:
find $PKG/usr/share -type f -size 0 -exec rm -f {} \;
find $PKG -type d -delete 2>/dev/null || true # Errors on non-empty dirs...

# Add a package description:
mkdir -p $PKG/install
cat $SRCDIR/${PRGNAM}.slack-desc > $PKG/install/slack-desc
cat $SRCDIR/${PRGNAM}.slack-required > $PKG/install/slack-required

# Intermediate step: assemble the qemu-guest-agent package:

# Install the binary:
install -D -m0775 $PKG/usr/bin/qemu-ga $PKG2/usr/bin/qemu-ga
# Install helper script which gets called when the host issues a 'fsfreeze':
install -D -m0775 $TMP/tmp-$PRGNAM/$PRGNAM-$VERSION/scripts/$PRGNAM2/fsfreeze-hook $PKG2/etc/qemu/fsfreeze-hook
mkdir -p $PKG2/etc/qemu/fsfreeze-hook.d
# Install a boot script:
install -D -m0664 $SRCDIR/${PRGNAM2}.rc $PKG2/etc/rc.d/rc.qemu-ga.new
# Pachage metadata:
mkdir -p $PKG2/install
cat $SRCDIR/${PRGNAM2}.doinst.sh > $PKG2/install/doinst.sh
cat $SRCDIR/${PRGNAM2}.slack-desc > $PKG2/install/slack-desc
# And finally:
cd $PKG2
makepkg -l y -c n $OUTPUT/${PRGNAM2}-${VERSION}-${ARCH}-${BUILD}${TAG}.txz 2>&1 | tee $OUTPUT/makepkg-${PRGNAM2}.log
cd $OUTPUT
  md5sum ${PRGNAM2}-${VERSION}-${ARCH}-${BUILD}${TAG}.txz > ${PRGNAM2}-${VERSION}-${ARCH}-${BUILD}${TAG}.txz.md5
cd -
cat $PKG2/install/slack-desc | grep "^${PRGNAM2}" > $OUTPUT/${PRGNAM2}-${VERSION}-${ARCH}-${BUILD}${TAG}.txt

# Build the QEMU package:
cd $PKG
makepkg --linkadd y --chown n $OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.txz 2>&1 | tee $OUTPUT/makepkg-${PRGNAM}.log
cd $OUTPUT
md5sum ${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.txz > ${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.txz.md5
cd -
cat $PKG/install/slack-desc | grep "^${PRGNAM}" > $OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.txt
cat $PKG/install/slack-required > $OUTPUT/${PRGNAM}-${VERSION}-${ARCH}-${BUILD}${TAG}.dep

# Restore the original umask:
umask ${_UMASK_}

