#!/bin/sh
#
# qemu configure script (c) 2003 Fabrice Bellard
#

# Unset some variables known to interfere with behavior of common tools,
# just as autoconf does.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS

# Don't allow CCACHE, if present, to use cached results of compile tests!
export CCACHE_RECACHE=yes

# make source path absolute
source_path=$(cd "$(dirname -- "$0")"; pwd)

if test "$PWD" = "$source_path"
then
    echo "Using './build' as the directory for build output"

    MARKER=build/auto-created-by-configure

    if test -e build
    then
        if test -f $MARKER
        then
           rm -rf build
        else
            echo "ERROR: ./build dir already exists and was not previously created by configure"
            exit 1
        fi
    fi

    mkdir build
    touch $MARKER

    cat > GNUmakefile <<'EOF'
# This file is auto-generated by configure to support in-source tree
# 'make' command invocation

ifeq ($(MAKECMDGOALS),)
recurse: all
endif

.NOTPARALLEL: %
%: force
	@echo 'changing dir to build for $(MAKE) "$(MAKECMDGOALS)"...'
	@$(MAKE) -C build -f Makefile $(MAKECMDGOALS)
	@if test "$(MAKECMDGOALS)" = "distclean" && \
	    test -e build/auto-created-by-configure ; \
	then \
	    rm -rf build GNUmakefile ; \
	fi
force: ;
.PHONY: force
GNUmakefile: ;

EOF
    cd build
    exec $source_path/configure "$@"
fi

# Temporary directory used for files created while
# configure runs. Since it is in the build directory
# we can safely blow away any previous version of it
# (and we need not jump through hoops to try to delete
# it when configure exits.)
TMPDIR1="config-temp"
rm -rf "${TMPDIR1}"
mkdir -p "${TMPDIR1}"
if [ $? -ne 0 ]; then
    echo "ERROR: failed to create temporary directory"
    exit 1
fi

TMPB="qemu-conf"
TMPC="${TMPDIR1}/${TMPB}.c"
TMPO="${TMPDIR1}/${TMPB}.o"
TMPCXX="${TMPDIR1}/${TMPB}.cxx"
TMPE="${TMPDIR1}/${TMPB}.exe"
TMPTXT="${TMPDIR1}/${TMPB}.txt"

rm -f config.log

# Print a helpful header at the top of config.log
echo "# QEMU configure log $(date)" >> config.log
printf "# Configured with:" >> config.log
printf " '%s'" "$0" "$@" >> config.log
echo >> config.log
echo "#" >> config.log

print_error() {
    (echo
    echo "ERROR: $1"
    while test -n "$2"; do
        echo "       $2"
        shift
    done
    echo) >&2
}

error_exit() {
    print_error "$@"
    exit 1
}

do_compiler() {
    # Run the compiler, capturing its output to the log. First argument
    # is compiler binary to execute.
    local compiler="$1"
    shift
    if test -n "$BASH_VERSION"; then eval '
        echo >>config.log "
funcs: ${FUNCNAME[*]}
lines: ${BASH_LINENO[*]}"
    '; fi
    echo $compiler "$@" >> config.log
    $compiler "$@" >> config.log 2>&1 || return $?
    # Test passed. If this is an --enable-werror build, rerun
    # the test with -Werror and bail out if it fails. This
    # makes warning-generating-errors in configure test code
    # obvious to developers.
    if test "$werror" != "yes"; then
        return 0
    fi
    # Don't bother rerunning the compile if we were already using -Werror
    case "$*" in
        *-Werror*)
           return 0
        ;;
    esac
    echo $compiler -Werror "$@" >> config.log
    $compiler -Werror "$@" >> config.log 2>&1 && return $?
    error_exit "configure test passed without -Werror but failed with -Werror." \
        "This is probably a bug in the configure script. The failing command" \
        "will be at the bottom of config.log." \
        "You can run configure with --disable-werror to bypass this check."
}

do_cc() {
    do_compiler "$cc" "$@"
}

do_cxx() {
    do_compiler "$cxx" "$@"
}

# Append $2 to the variable named $1, with space separation
add_to() {
    eval $1=\${$1:+\"\$$1 \"}\$2
}

update_cxxflags() {
    # Set QEMU_CXXFLAGS from QEMU_CFLAGS by filtering out those
    # options which some versions of GCC's C++ compiler complain about
    # because they only make sense for C programs.
    QEMU_CXXFLAGS="$QEMU_CXXFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS"
    CONFIGURE_CXXFLAGS=$(echo "$CONFIGURE_CFLAGS" | sed s/-std=gnu99/-std=gnu++11/)
    for arg in $QEMU_CFLAGS; do
        case $arg in
            -Wstrict-prototypes|-Wmissing-prototypes|-Wnested-externs|\
            -Wold-style-declaration|-Wold-style-definition|-Wredundant-decls)
                ;;
            *)
                QEMU_CXXFLAGS=${QEMU_CXXFLAGS:+$QEMU_CXXFLAGS }$arg
                ;;
        esac
    done
}

compile_object() {
  local_cflags="$1"
  do_cc $CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
}

compile_prog() {
  local_cflags="$1"
  local_ldflags="$2"
  do_cc $CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC \
      $LDFLAGS $CONFIGURE_LDFLAGS $QEMU_LDFLAGS $local_ldflags
}

# symbolically link $1 to $2.  Portable version of "ln -sf".
symlink() {
  rm -rf "$2"
  mkdir -p "$(dirname "$2")"
  ln -s "$1" "$2"
}

# check whether a command is available to this shell (may be either an
# executable or a builtin)
has() {
    type "$1" >/dev/null 2>&1
}

version_ge () {
    local_ver1=`echo $1 | tr . ' '`
    local_ver2=`echo $2 | tr . ' '`
    while true; do
        set x $local_ver1
        local_first=${2-0}
        # 'shift 2' if $2 is set, or 'shift' if $2 is not set
        shift ${2:+2}
        local_ver1=$*
        set x $local_ver2
        # the second argument finished, the first must be greater or equal
        test $# = 1 && return 0
        test $local_first -lt $2 && return 1
        test $local_first -gt $2 && return 0
        shift ${2:+2}
        local_ver2=$*
    done
}

have_backend () {
    echo "$trace_backends" | grep "$1" >/dev/null
}

glob() {
    eval test -z '"${1#'"$2"'}"'
}

ld_has() {
    $ld --help 2>/dev/null | grep ".$1" >/dev/null 2>&1
}

if printf %s\\n "$source_path" "$PWD" | grep -q "[[:space:]:]";
then
  error_exit "main directory cannot contain spaces nor colons"
fi

# default parameters
cpu=""
iasl="iasl"
interp_prefix="/usr/gnemul/qemu-%M"
static="no"
cross_prefix=""
audio_drv_list=""
block_drv_rw_whitelist=""
block_drv_ro_whitelist=""
host_cc="cc"
audio_win_int=""
libs_qga=""
debug_info="yes"
stack_protector=""
safe_stack=""
use_containers="yes"
gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")

if test -e "$source_path/.git"
then
    git_update=yes
    git_submodules="ui/keycodemapdb"
    git_submodules="$git_submodules tests/fp/berkeley-testfloat-3"
    git_submodules="$git_submodules tests/fp/berkeley-softfloat-3"
else
    git_update=no
    git_submodules=""

    if ! test -f "$source_path/ui/keycodemapdb/README"
    then
        echo
        echo "ERROR: missing file $source_path/ui/keycodemapdb/README"
        echo
        echo "This is not a GIT checkout but module content appears to"
        echo "be missing. Do not use 'git archive' or GitHub download links"
        echo "to acquire QEMU source archives. Non-GIT builds are only"
        echo "supported with source archives linked from:"
        echo
        echo "  https://www.qemu.org/download/#source"
        echo
        echo "Developers working with GIT can use scripts/archive-source.sh"
        echo "if they need to create valid source archives."
        echo
        exit 1
    fi
fi
git="git"

# Don't accept a target_list environment variable.
unset target_list
unset target_list_exclude

# Default value for a variable defining feature "foo".
#  * foo="no"  feature will only be used if --enable-foo arg is given
#  * foo=""    feature will be searched for, and if found, will be used
#              unless --disable-foo is given
#  * foo="yes" this value will only be set by --enable-foo flag.
#              feature will searched for,
#              if not found, configure exits with error
#
# Always add --enable-foo and --disable-foo command line args.
# Distributions want to ensure that several features are compiled in, and it
# is impossible without a --enable-foo that exits if a feature is not found.

brlapi=""
curl=""
iconv="auto"
curses="auto"
docs="auto"
fdt="auto"
netmap="no"
sdl="auto"
sdl_image="auto"
virtiofsd="auto"
virtfs=""
libudev="auto"
mpath="auto"
vnc="enabled"
sparse="auto"
vde=""
vnc_sasl="auto"
vnc_jpeg="auto"
vnc_png="auto"
xkbcommon="auto"
xen=""
xen_ctrl_version=""
xen_pci_passthrough="auto"
linux_aio=""
linux_io_uring=""
cap_ng=""
attr=""
libattr=""
xfs=""
tcg="enabled"
membarrier=""
vhost_net=""
vhost_crypto=""
vhost_scsi=""
vhost_vsock=""
vhost_user="no"
vhost_user_blk_server="auto"
vhost_user_fs=""
kvm="auto"
hax="auto"
hvf="auto"
whpx="auto"
rdma=""
pvrdma=""
gprof="no"
debug_tcg="no"
debug="no"
sanitizers="no"
tsan="no"
fortify_source=""
strip_opt="yes"
tcg_interpreter="no"
bigendian="no"
mingw32="no"
gcov="no"
EXESUF=""
HOST_DSOSUF=".so"
modules="no"
module_upgrades="no"
prefix="/usr/local"
qemu_suffix="qemu"
slirp="auto"
oss_lib=""
bsd="no"
linux="no"
solaris="no"
profiler="no"
cocoa="auto"
softmmu="yes"
linux_user="no"
bsd_user="no"
blobs="true"
pkgversion=""
pie=""
qom_cast_debug="yes"
trace_backends="log"
trace_file="trace"
spice=""
rbd=""
smartcard=""
u2f="auto"
libusb=""
usb_redir=""
opengl=""
opengl_dmabuf="no"
cpuid_h="no"
avx2_opt=""
capstone="auto"
lzo=""
snappy=""
bzip2=""
lzfse=""
zstd=""
guest_agent=""
guest_agent_with_vss="no"
guest_agent_ntddscsi="no"
guest_agent_msi=""
vss_win32_sdk=""
win_sdk="no"
want_tools=""
libiscsi=""
libnfs=""
coroutine=""
coroutine_pool=""
debug_stack_usage="no"
crypto_afalg="no"
seccomp=""
glusterfs=""
glusterfs_xlator_opt="no"
glusterfs_discard="no"
glusterfs_fallocate="no"
glusterfs_zerofill="no"
glusterfs_ftruncate_has_stat="no"
glusterfs_iocb_has_stat="no"
gtk=""
gtk_gl="no"
tls_priority="NORMAL"
gnutls=""
nettle=""
nettle_xts="no"
gcrypt=""
gcrypt_hmac="no"
gcrypt_xts="no"
qemu_private_xts="yes"
auth_pam=""
vte=""
virglrenderer=""
tpm=""
libssh=""
live_block_migration="yes"
numa=""
tcmalloc="no"
jemalloc="no"
replication="yes"
bochs="yes"
cloop="yes"
dmg="yes"
qcow1="yes"
vdi="yes"
vvfat="yes"
qed="yes"
parallels="yes"
sheepdog="no"
libxml2=""
debug_mutex="no"
libpmem=""
default_devices="yes"
plugins="no"
fuzzing="no"
rng_none="no"
secret_keyring=""
libdaxctl=""
meson=""
ninja=""
skip_meson=no
gettext=""
fuse="auto"
fuse_lseek="auto"

bogus_os="no"
malloc_trim="auto"

# parse CC options first
for opt do
  optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
  case "$opt" in
  --cross-prefix=*) cross_prefix="$optarg"
  ;;
  --cc=*) CC="$optarg"
  ;;
  --cxx=*) CXX="$optarg"
  ;;
  --cpu=*) cpu="$optarg"
  ;;
  --extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
                    QEMU_LDFLAGS="$QEMU_LDFLAGS $optarg"
  ;;
  --extra-cxxflags=*) QEMU_CXXFLAGS="$QEMU_CXXFLAGS $optarg"
  ;;
  --extra-ldflags=*) QEMU_LDFLAGS="$QEMU_LDFLAGS $optarg"
                     EXTRA_LDFLAGS="$optarg"
  ;;
  --enable-debug-info) debug_info="yes"
  ;;
  --disable-debug-info) debug_info="no"
  ;;
  --cross-cc-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --cross-cc-FOO option"
  ;;
  --cross-cc-cflags-*) cc_arch=${opt#--cross-cc-flags-}; cc_arch=${cc_arch%%=*}
                      eval "cross_cc_cflags_${cc_arch}=\$optarg"
                      cross_cc_vars="$cross_cc_vars cross_cc_cflags_${cc_arch}"
  ;;
  --cross-cc-*) cc_arch=${opt#--cross-cc-}; cc_arch=${cc_arch%%=*}
                cc_archs="$cc_archs $cc_arch"
                eval "cross_cc_${cc_arch}=\$optarg"
                cross_cc_vars="$cross_cc_vars cross_cc_${cc_arch}"
  ;;
  esac
done
# OS specific
# Using uname is really, really broken.  Once we have the right set of checks
# we can eliminate its usage altogether.

# Preferred compiler:
#  ${CC} (if set)
#  ${cross_prefix}gcc (if cross-prefix specified)
#  system compiler
if test -z "${CC}${cross_prefix}"; then
  cc="$host_cc"
else
  cc="${CC-${cross_prefix}gcc}"
fi

if test -z "${CXX}${cross_prefix}"; then
  cxx="c++"
else
  cxx="${CXX-${cross_prefix}g++}"
fi

ar="${AR-${cross_prefix}ar}"
as="${AS-${cross_prefix}as}"
ccas="${CCAS-$cc}"
cpp="${CPP-$cc -E}"
objcopy="${OBJCOPY-${cross_prefix}objcopy}"
ld="${LD-${cross_prefix}ld}"
ranlib="${RANLIB-${cross_prefix}ranlib}"
nm="${NM-${cross_prefix}nm}"
strip="${STRIP-${cross_prefix}strip}"
windres="${WINDRES-${cross_prefix}windres}"
pkg_config_exe="${PKG_CONFIG-${cross_prefix}pkg-config}"
query_pkg_config() {
    "${pkg_config_exe}" ${QEMU_PKG_CONFIG_FLAGS} "$@"
}
pkg_config=query_pkg_config
sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"

# If the user hasn't specified ARFLAGS, default to 'rv', just as make does.
ARFLAGS="${ARFLAGS-rv}"

# default flags for all hosts
# We use -fwrapv to tell the compiler that we require a C dialect where
# left shift of signed integers is well defined and has the expected
# 2s-complement style results. (Both clang and gcc agree that it
# provides these semantics.)
QEMU_CFLAGS="-fno-strict-aliasing -fno-common -fwrapv $QEMU_CFLAGS"
QEMU_CFLAGS="-Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"

# Flags that are needed during configure but later taken care of by Meson
CONFIGURE_CFLAGS="-std=gnu99 -Wall"
CONFIGURE_LDFLAGS=


check_define() {
cat > $TMPC <<EOF
#if !defined($1)
#error $1 not defined
#endif
int main(void) { return 0; }
EOF
  compile_object
}

check_include() {
cat > $TMPC <<EOF
#include <$1>
int main(void) { return 0; }
EOF
  compile_object
}

write_c_skeleton() {
    cat > $TMPC <<EOF
int main(void) { return 0; }
EOF
}

write_c_fuzzer_skeleton() {
    cat > $TMPC <<EOF
#include <stdint.h>
#include <sys/types.h>
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
EOF
}

if check_define __linux__ ; then
  targetos="Linux"
elif check_define _WIN32 ; then
  targetos='MINGW32'
elif check_define __OpenBSD__ ; then
  targetos='OpenBSD'
elif check_define __sun__ ; then
  targetos='SunOS'
elif check_define __HAIKU__ ; then
  targetos='Haiku'
elif check_define __FreeBSD__ ; then
  targetos='FreeBSD'
elif check_define __FreeBSD_kernel__ && check_define __GLIBC__; then
  targetos='GNU/kFreeBSD'
elif check_define __DragonFly__ ; then
  targetos='DragonFly'
elif check_define __NetBSD__; then
  targetos='NetBSD'
elif check_define __APPLE__; then
  targetos='Darwin'
else
  # This is a fatal error, but don't report it yet, because we
  # might be going to just print the --help text, or it might
  # be the result of a missing compiler.
  targetos='bogus'
  bogus_os='yes'
fi

# Some host OSes need non-standard checks for which CPU to use.
# Note that these checks are broken for cross-compilation: if you're
# cross-compiling to one of these OSes then you'll need to specify
# the correct CPU with the --cpu option.
case $targetos in
Darwin)
  # on Leopard most of the system is 32-bit, so we have to ask the kernel if we can
  # run 64-bit userspace code.
  # If the user didn't specify a CPU explicitly and the kernel says this is
  # 64 bit hw, then assume x86_64. Otherwise fall through to the usual detection code.
  if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
    cpu="x86_64"
  fi
  HOST_DSOSUF=".dylib"
  ;;
SunOS)
  # $(uname -m) returns i86pc even on an x86_64 box, so default based on isainfo
  if test -z "$cpu" && test "$(isainfo -k)" = "amd64"; then
    cpu="x86_64"
  fi
esac

if test ! -z "$cpu" ; then
  # command line argument
  :
elif check_define __i386__ ; then
  cpu="i386"
elif check_define __x86_64__ ; then
  if check_define __ILP32__ ; then
    cpu="x32"
  else
    cpu="x86_64"
  fi
elif check_define __sparc__ ; then
  if check_define __arch64__ ; then
    cpu="sparc64"
  else
    cpu="sparc"
  fi
elif check_define _ARCH_PPC ; then
  if check_define _ARCH_PPC64 ; then
    if check_define _LITTLE_ENDIAN ; then
      cpu="ppc64le"
    else
      cpu="ppc64"
    fi
  else
    cpu="ppc"
  fi
elif check_define __mips__ ; then
  cpu="mips"
elif check_define __s390__ ; then
  if check_define __s390x__ ; then
    cpu="s390x"
  else
    cpu="s390"
  fi
elif check_define __riscv ; then
  if check_define _LP64 ; then
    cpu="riscv64"
  else
    cpu="riscv32"
  fi
elif check_define __arm__ ; then
  cpu="arm"
elif check_define __aarch64__ ; then
  cpu="aarch64"
else
  cpu=$(uname -m)
fi

ARCH=
# Normalise host CPU name and set ARCH.
# Note that this case should only have supported host CPUs, not guests.
case "$cpu" in
  ppc|ppc64|s390x|sparc64|x32|riscv32|riscv64)
  ;;
  ppc64le)
    ARCH="ppc64"
  ;;
  i386|i486|i586|i686|i86pc|BePC)
    cpu="i386"
  ;;
  x86_64|amd64)
    cpu="x86_64"
  ;;
  armv*b|armv*l|arm)
    cpu="arm"
  ;;
  aarch64)
    cpu="aarch64"
  ;;
  mips*)
    cpu="mips"
  ;;
  sparc|sun4[cdmuv])
    cpu="sparc"
  ;;
  *)
    # This will result in either an error or falling back to TCI later
    ARCH=unknown
  ;;
esac
if test -z "$ARCH"; then
  ARCH="$cpu"
fi

# OS specific

case $targetos in
MINGW32*)
  mingw32="yes"
  audio_possible_drivers="dsound sdl"
  if check_include dsound.h; then
    audio_drv_list="dsound"
  else
    audio_drv_list=""
  fi
  supported_os="yes"
  pie="no"
;;
GNU/kFreeBSD)
  bsd="yes"
  audio_drv_list="oss try-sdl"
  audio_possible_drivers="oss sdl pa"
;;
FreeBSD)
  bsd="yes"
  make="${MAKE-gmake}"
  audio_drv_list="oss try-sdl"
  audio_possible_drivers="oss sdl pa"
  # needed for kinfo_getvmmap(3) in libutil.h
  netmap=""  # enable netmap autodetect
;;
DragonFly)
  bsd="yes"
  make="${MAKE-gmake}"
  audio_drv_list="oss try-sdl"
  audio_possible_drivers="oss sdl pa"
;;
NetBSD)
  bsd="yes"
  make="${MAKE-gmake}"
  audio_drv_list="oss try-sdl"
  audio_possible_drivers="oss sdl"
  oss_lib="-lossaudio"
;;
OpenBSD)
  bsd="yes"
  make="${MAKE-gmake}"
  audio_drv_list="try-sdl"
  audio_possible_drivers="sdl"
;;
Darwin)
  bsd="yes"
  darwin="yes"
  if [ "$cpu" = "x86_64" ] ; then
    QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
    QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
  fi
  cocoa="enabled"
  audio_drv_list="coreaudio try-sdl"
  audio_possible_drivers="coreaudio sdl"
  QEMU_LDFLAGS="-framework CoreFoundation -framework IOKit $QEMU_LDFLAGS"
  # Disable attempts to use ObjectiveC features in os/object.h since they
  # won't work when we're compiling with gcc as a C compiler.
  QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
;;
SunOS)
  solaris="yes"
  make="${MAKE-gmake}"
  smbd="${SMBD-/usr/sfw/sbin/smbd}"
  if test -f /usr/include/sys/soundcard.h ; then
    audio_drv_list="oss try-sdl"
  fi
  audio_possible_drivers="oss sdl"
# needed for CMSG_ macros in sys/socket.h
  QEMU_CFLAGS="-D_XOPEN_SOURCE=600 $QEMU_CFLAGS"
# needed for TIOCWIN* defines in termios.h
  QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS"
;;
Haiku)
  haiku="yes"
  QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE $QEMU_CFLAGS"
;;
Linux)
  audio_drv_list="try-pa oss"
  audio_possible_drivers="oss alsa sdl pa"
  linux="yes"
  linux_user="yes"
  vhost_user="yes"
;;
esac

if [ "$bsd" = "yes" ] ; then
  if [ "$darwin" != "yes" ] ; then
    bsd_user="yes"
  fi
fi

: ${make=${MAKE-make}}

# We prefer python 3.x. A bare 'python' is traditionally
# python 2.x, but some distros have it as python 3.x, so
# we check that too
python=
explicit_python=no
for binary in "${PYTHON-python3}" python
do
    if has "$binary"
    then
        python=$(command -v "$binary")
        break
    fi
done


# Check for ancillary tools used in testing
genisoimage=
for binary in genisoimage mkisofs
do
    if has $binary
    then
        genisoimage=$(command -v "$binary")
        break
    fi
done

: ${smbd=${SMBD-/usr/sbin/smbd}}

# Default objcc to clang if available, otherwise use CC
if has clang; then
  objcc=clang
else
  objcc="$cc"
fi

if test "$mingw32" = "yes" ; then
  EXESUF=".exe"
  HOST_DSOSUF=".dll"
  # MinGW needs -mthreads for TLS and macro _MT.
  CONFIGURE_CFLAGS="-mthreads $CONFIGURE_CFLAGS"
  write_c_skeleton;
  prefix="/qemu"
  qemu_suffix=""
  libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -lwininet -liphlpapi -lnetapi32 $libs_qga"
fi

werror=""

for opt do
  optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
  case "$opt" in
  --help|-h) show_help=yes
  ;;
  --version|-V) exec cat $source_path/VERSION
  ;;
  --prefix=*) prefix="$optarg"
  ;;
  --interp-prefix=*) interp_prefix="$optarg"
  ;;
  --cross-prefix=*)
  ;;
  --cc=*)
  ;;
  --host-cc=*) host_cc="$optarg"
  ;;
  --cxx=*)
  ;;
  --iasl=*) iasl="$optarg"
  ;;
  --objcc=*) objcc="$optarg"
  ;;
  --make=*) make="$optarg"
  ;;
  --install=*)
  ;;
  --python=*) python="$optarg" ; explicit_python=yes
  ;;
  --sphinx-build=*) sphinx_build="$optarg"
  ;;
  --skip-meson) skip_meson=yes
  ;;
  --meson=*) meson="$optarg"
  ;;
  --ninja=*) ninja="$optarg"
  ;;
  --smbd=*) smbd="$optarg"
  ;;
  --extra-cflags=*)
  ;;
  --extra-cxxflags=*)
  ;;
  --extra-ldflags=*)
  ;;
  --enable-debug-info)
  ;;
  --disable-debug-info)
  ;;
  --cross-cc-*)
  ;;
  --enable-modules)
      modules="yes"
  ;;
  --disable-modules)
      modules="no"
  ;;
  --disable-module-upgrades) module_upgrades="no"
  ;;
  --enable-module-upgrades) module_upgrades="yes"
  ;;
  --cpu=*)
  ;;
  --target-list=*) target_list="$optarg"
                   if test "$target_list_exclude"; then
                       error_exit "Can't mix --target-list with --target-list-exclude"
                   fi
  ;;
  --target-list-exclude=*) target_list_exclude="$optarg"
                   if test "$target_list"; then
                       error_exit "Can't mix --target-list-exclude with --target-list"
                   fi
  ;;
  --enable-trace-backends=*) trace_backends="$optarg"
  ;;
  # XXX: backwards compatibility
  --enable-trace-backend=*) trace_backends="$optarg"
  ;;
  --with-trace-file=*) trace_file="$optarg"
  ;;
  --with-default-devices) default_devices="yes"
  ;;
  --without-default-devices) default_devices="no"
  ;;
  --enable-gprof) gprof="yes"
  ;;
  --enable-gcov) gcov="yes"
  ;;
  --static)
    static="yes"
    QEMU_PKG_CONFIG_FLAGS="--static $QEMU_PKG_CONFIG_FLAGS"
  ;;
  --mandir=*) mandir="$optarg"
  ;;
  --bindir=*) bindir="$optarg"
  ;;
  --libdir=*) libdir="$optarg"
  ;;
  --libexecdir=*) libexecdir="$optarg"
  ;;
  --includedir=*) includedir="$optarg"
  ;;
  --datadir=*) datadir="$optarg"
  ;;
  --with-suffix=*) qemu_suffix="$optarg"
  ;;
  --docdir=*) docdir="$optarg"
  ;;
  --localedir=*) localedir="$optarg"
  ;;
  --sysconfdir=*) sysconfdir="$optarg"
  ;;
  --localstatedir=*) local_statedir="$optarg"
  ;;
  --firmwarepath=*) firmwarepath="$optarg"
  ;;
  --host=*|--build=*|\
  --disable-dependency-tracking|\
  --sbindir=*|--sharedstatedir=*|\
  --oldincludedir=*|--datarootdir=*|--infodir=*|\
  --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
    # These switches are silently ignored, for compatibility with
    # autoconf-generated configure scripts. This allows QEMU's
    # configure to be used by RPM and similar macros that set
    # lots of directory switches by default.
  ;;
  --disable-sdl) sdl="disabled"
  ;;
  --enable-sdl) sdl="enabled"
  ;;
  --disable-sdl-image) sdl_image="disabled"
  ;;
  --enable-sdl-image) sdl_image="enabled"
  ;;
  --disable-qom-cast-debug) qom_cast_debug="no"
  ;;
  --enable-qom-cast-debug) qom_cast_debug="yes"
  ;;
  --disable-virtfs) virtfs="no"
  ;;
  --enable-virtfs) virtfs="yes"
  ;;
  --disable-libudev) libudev="disabled"
  ;;
  --enable-libudev) libudev="enabled"
  ;;
  --disable-virtiofsd) virtiofsd="disabled"
  ;;
  --enable-virtiofsd) virtiofsd="enabled"
  ;;
  --disable-mpath) mpath="disabled"
  ;;
  --enable-mpath) mpath="enabled"
  ;;
  --disable-vnc) vnc="disabled"
  ;;
  --enable-vnc) vnc="enabled"
  ;;
  --disable-gettext) gettext="false"
  ;;
  --enable-gettext) gettext="true"
  ;;
  --oss-lib=*) oss_lib="$optarg"
  ;;
  --audio-drv-list=*) audio_drv_list="$optarg"
  ;;
  --block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=$(echo "$optarg" | sed -e 's/,/ /g')
  ;;
  --block-drv-ro-whitelist=*) block_drv_ro_whitelist=$(echo "$optarg" | sed -e 's/,/ /g')
  ;;
  --enable-debug-tcg) debug_tcg="yes"
  ;;
  --disable-debug-tcg) debug_tcg="no"
  ;;
  --enable-debug)
      # Enable debugging options that aren't excessively noisy
      debug_tcg="yes"
      debug_mutex="yes"
      debug="yes"
      strip_opt="no"
      fortify_source="no"
  ;;
  --enable-sanitizers) sanitizers="yes"
  ;;
  --disable-sanitizers) sanitizers="no"
  ;;
  --enable-tsan) tsan="yes"
  ;;
  --disable-tsan) tsan="no"
  ;;
  --enable-sparse) sparse="enabled"
  ;;
  --disable-sparse) sparse="disabled"
  ;;
  --disable-strip) strip_opt="no"
  ;;
  --disable-vnc-sasl) vnc_sasl="disabled"
  ;;
  --enable-vnc-sasl) vnc_sasl="enabled"
  ;;
  --disable-vnc-jpeg) vnc_jpeg="disabled"
  ;;
  --enable-vnc-jpeg) vnc_jpeg="enabled"
  ;;
  --disable-vnc-png) vnc_png="disabled"
  ;;
  --enable-vnc-png) vnc_png="enabled"
  ;;
  --disable-slirp) slirp="disabled"
  ;;
  --enable-slirp=git) slirp="internal"
  ;;
  --enable-slirp=system) slirp="system"
  ;;
  --disable-vde) vde="no"
  ;;
  --enable-vde) vde="yes"
  ;;
  --disable-netmap) netmap="no"
  ;;
  --enable-netmap) netmap="yes"
  ;;
  --disable-xen) xen="disabled"
  ;;
  --enable-xen) xen="enabled"
  ;;
  --disable-xen-pci-passthrough) xen_pci_passthrough="disabled"
  ;;
  --enable-xen-pci-passthrough) xen_pci_passthrough="enabled"
  ;;
  --disable-brlapi) brlapi="no"
  ;;
  --enable-brlapi) brlapi="yes"
  ;;
  --disable-kvm) kvm="disabled"
  ;;
  --enable-kvm) kvm="enabled"
  ;;
  --disable-hax) hax="disabled"
  ;;
  --enable-hax) hax="enabled"
  ;;
  --disable-hvf) hvf="disabled"
  ;;
  --enable-hvf) hvf="enabled"
  ;;
  --disable-whpx) whpx="disabled"
  ;;
  --enable-whpx) whpx="enabled"
  ;;
  --disable-tcg-interpreter) tcg_interpreter="no"
  ;;
  --enable-tcg-interpreter) tcg_interpreter="yes"
  ;;
  --disable-cap-ng)  cap_ng="no"
  ;;
  --enable-cap-ng) cap_ng="yes"
  ;;
  --disable-tcg) tcg="disabled"
  ;;
  --enable-tcg) tcg="enabled"
  ;;
  --disable-malloc-trim) malloc_trim="disabled"
  ;;
  --enable-malloc-trim) malloc_trim="enabled"
  ;;
  --disable-spice) spice="no"
  ;;
  --enable-spice) spice="yes"
  ;;
  --disable-libiscsi) libiscsi="no"
  ;;
  --enable-libiscsi) libiscsi="yes"
  ;;
  --disable-libnfs) libnfs="no"
  ;;
  --enable-libnfs) libnfs="yes"
  ;;
  --enable-profiler) profiler="yes"
  ;;
  --disable-cocoa) cocoa="disabled"
  ;;
  --enable-cocoa)
      cocoa="enabled" ;
      audio_drv_list="coreaudio $(echo $audio_drv_list | sed s,coreaudio,,g)"
  ;;
  --disable-system) softmmu="no"
  ;;
  --enable-system) softmmu="yes"
  ;;
  --disable-user)
      linux_user="no" ;
      bsd_user="no" ;
  ;;
  --enable-user) ;;
  --disable-linux-user) linux_user="no"
  ;;
  --enable-linux-user) linux_user="yes"
  ;;
  --disable-bsd-user) bsd_user="no"
  ;;
  --enable-bsd-user) bsd_user="yes"
  ;;
  --enable-pie) pie="yes"
  ;;
  --disable-pie) pie="no"
  ;;
  --enable-werror) werror="yes"
  ;;
  --disable-werror) werror="no"
  ;;
  --enable-stack-protector) stack_protector="yes"
  ;;
  --disable-stack-protector) stack_protector="no"
  ;;
  --enable-safe-stack) safe_stack="yes"
  ;;
  --disable-safe-stack) safe_stack="no"
  ;;
  --disable-curses) curses="disabled"
  ;;
  --enable-curses) curses="enabled"
  ;;
  --disable-iconv) iconv="disabled"
  ;;
  --enable-iconv) iconv="enabled"
  ;;
  --disable-curl) curl="no"
  ;;
  --enable-curl) curl="yes"
  ;;
  --disable-fdt) fdt="disabled"
  ;;
  --enable-fdt) fdt="enabled"
  ;;
  --enable-fdt=git) fdt="internal"
  ;;
  --enable-fdt=system) fdt="system"
  ;;
  --disable-linux-aio) linux_aio="no"
  ;;
  --enable-linux-aio) linux_aio="yes"
  ;;
  --disable-linux-io-uring) linux_io_uring="no"
  ;;
  --enable-linux-io-uring) linux_io_uring="yes"
  ;;
  --disable-attr) attr="no"
  ;;
  --enable-attr) attr="yes"
  ;;
  --disable-membarrier) membarrier="no"
  ;;
  --enable-membarrier) membarrier="yes"
  ;;
  --disable-blobs) blobs="false"
  ;;
  --with-pkgversion=*) pkgversion="$optarg"
  ;;
  --with-coroutine=*) coroutine="$optarg"
  ;;
  --disable-coroutine-pool) coroutine_pool="no"
  ;;
  --enable-coroutine-pool) coroutine_pool="yes"
  ;;
  --enable-debug-stack-usage) debug_stack_usage="yes"
  ;;
  --enable-crypto-afalg) crypto_afalg="yes"
  ;;
  --disable-crypto-afalg) crypto_afalg="no"
  ;;
  --disable-docs) docs="disabled"
  ;;
  --enable-docs) docs="enabled"
  ;;
  --disable-vhost-net) vhost_net="no"
  ;;
  --enable-vhost-net) vhost_net="yes"
  ;;
  --disable-vhost-crypto) vhost_crypto="no"
  ;;
  --enable-vhost-crypto) vhost_crypto="yes"
  ;;
  --disable-vhost-scsi) vhost_scsi="no"
  ;;
  --enable-vhost-scsi) vhost_scsi="yes"
  ;;
  --disable-vhost-vsock) vhost_vsock="no"
  ;;
  --enable-vhost-vsock) vhost_vsock="yes"
  ;;
  --disable-vhost-user-blk-server) vhost_user_blk_server="disabled"
  ;;
  --enable-vhost-user-blk-server) vhost_user_blk_server="enabled"
  ;;
  --disable-vhost-user-fs) vhost_user_fs="no"
  ;;
  --enable-vhost-user-fs) vhost_user_fs="yes"
  ;;
  --disable-opengl) opengl="no"
  ;;
  --enable-opengl) opengl="yes"
  ;;
  --disable-rbd) rbd="no"
  ;;
  --enable-rbd) rbd="yes"
  ;;
  --disable-xfsctl) xfs="no"
  ;;
  --enable-xfsctl) xfs="yes"
  ;;
  --disable-smartcard) smartcard="no"
  ;;
  --enable-smartcard) smartcard="yes"
  ;;
  --disable-u2f) u2f="disabled"
  ;;
  --enable-u2f) u2f="enabled"
  ;;
  --disable-libusb) libusb="no"
  ;;
  --enable-libusb) libusb="yes"
  ;;
  --disable-usb-redir) usb_redir="no"
  ;;
  --enable-usb-redir) usb_redir="yes"
  ;;
  --disable-zlib-test)
  ;;
  --disable-lzo) lzo="no"
  ;;
  --enable-lzo) lzo="yes"
  ;;
  --disable-snappy) snappy="no"
  ;;
  --enable-snappy) snappy="yes"
  ;;
  --disable-bzip2) bzip2="no"
  ;;
  --enable-bzip2) bzip2="yes"
  ;;
  --enable-lzfse) lzfse="yes"
  ;;
  --disable-lzfse) lzfse="no"
  ;;
  --disable-zstd) zstd="no"
  ;;
  --enable-zstd) zstd="yes"
  ;;
  --enable-guest-agent) guest_agent="yes"
  ;;
  --disable-guest-agent) guest_agent="no"
  ;;
  --enable-guest-agent-msi) guest_agent_msi="yes"
  ;;
  --disable-guest-agent-msi) guest_agent_msi="no"
  ;;
  --with-vss-sdk) vss_win32_sdk=""
  ;;
  --with-vss-sdk=*) vss_win32_sdk="$optarg"
  ;;
  --without-vss-sdk) vss_win32_sdk="no"
  ;;
  --with-win-sdk) win_sdk=""
  ;;
  --with-win-sdk=*) win_sdk="$optarg"
  ;;
  --without-win-sdk) win_sdk="no"
  ;;
  --enable-tools) want_tools="yes"
  ;;
  --disable-tools) want_tools="no"
  ;;
  --enable-seccomp) seccomp="yes"
  ;;
  --disable-seccomp) seccomp="no"
  ;;
  --disable-glusterfs) glusterfs="no"
  ;;
  --disable-avx2) avx2_opt="no"
  ;;
  --enable-avx2) avx2_opt="yes"
  ;;
  --disable-avx512f) avx512f_opt="no"
  ;;
  --enable-avx512f) avx512f_opt="yes"
  ;;

  --enable-glusterfs) glusterfs="yes"
  ;;
  --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
      echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2
  ;;
  --enable-vhdx|--disable-vhdx)
      echo "$0: $opt is obsolete, VHDX driver is always built" >&2
  ;;
  --enable-uuid|--disable-uuid)
      echo "$0: $opt is obsolete, UUID support is always built" >&2
  ;;
  --disable-gtk) gtk="no"
  ;;
  --enable-gtk) gtk="yes"
  ;;
  --tls-priority=*) tls_priority="$optarg"
  ;;
  --disable-gnutls) gnutls="no"
  ;;
  --enable-gnutls) gnutls="yes"
  ;;
  --disable-nettle) nettle="no"
  ;;
  --enable-nettle) nettle="yes"
  ;;
  --disable-gcrypt) gcrypt="no"
  ;;
  --enable-gcrypt) gcrypt="yes"
  ;;
  --disable-auth-pam) auth_pam="no"
  ;;
  --enable-auth-pam) auth_pam="yes"
  ;;
  --enable-rdma) rdma="yes"
  ;;
  --disable-rdma) rdma="no"
  ;;
  --enable-pvrdma) pvrdma="yes"
  ;;
  --disable-pvrdma) pvrdma="no"
  ;;
  --disable-vte) vte="no"
  ;;
  --enable-vte) vte="yes"
  ;;
  --disable-virglrenderer) virglrenderer="no"
  ;;
  --enable-virglrenderer) virglrenderer="yes"
  ;;
  --disable-tpm) tpm="no"
  ;;
  --enable-tpm) tpm="yes"
  ;;
  --disable-libssh) libssh="no"
  ;;
  --enable-libssh) libssh="yes"
  ;;
  --disable-live-block-migration) live_block_migration="no"
  ;;
  --enable-live-block-migration) live_block_migration="yes"
  ;;
  --disable-numa) numa="no"
  ;;
  --enable-numa) numa="yes"
  ;;
  --disable-libxml2) libxml2="no"
  ;;
  --enable-libxml2) libxml2="yes"
  ;;
  --disable-tcmalloc) tcmalloc="no"
  ;;
  --enable-tcmalloc) tcmalloc="yes"
  ;;
  --disable-jemalloc) jemalloc="no"
  ;;
  --enable-jemalloc) jemalloc="yes"
  ;;
  --disable-replication) replication="no"
  ;;
  --enable-replication) replication="yes"
  ;;
  --disable-bochs) bochs="no"
  ;;
  --enable-bochs) bochs="yes"
  ;;
  --disable-cloop) cloop="no"
  ;;
  --enable-cloop) cloop="yes"
  ;;
  --disable-dmg) dmg="no"
  ;;
  --enable-dmg) dmg="yes"
  ;;
  --disable-qcow1) qcow1="no"
  ;;
  --enable-qcow1) qcow1="yes"
  ;;
  --disable-vdi) vdi="no"
  ;;
  --enable-vdi) vdi="yes"
  ;;
  --disable-vvfat) vvfat="no"
  ;;
  --enable-vvfat) vvfat="yes"
  ;;
  --disable-qed) qed="no"
  ;;
  --enable-qed) qed="yes"
  ;;
  --disable-parallels) parallels="no"
  ;;
  --enable-parallels) parallels="yes"
  ;;
  --disable-sheepdog) sheepdog="no"
  ;;
  --enable-sheepdog) sheepdog="yes"
  ;;
  --disable-vhost-user) vhost_user="no"
  ;;
  --enable-vhost-user) vhost_user="yes"
  ;;
  --disable-vhost-vdpa) vhost_vdpa="no"
  ;;
  --enable-vhost-vdpa) vhost_vdpa="yes"
  ;;
  --disable-vhost-kernel) vhost_kernel="no"
  ;;
  --enable-vhost-kernel) vhost_kernel="yes"
  ;;
  --disable-capstone) capstone="disabled"
  ;;
  --enable-capstone) capstone="enabled"
  ;;
  --enable-capstone=git) capstone="internal"
  ;;
  --enable-capstone=system) capstone="system"
  ;;
  --with-git=*) git="$optarg"
  ;;
  --enable-git-update) git_update=yes
  ;;
  --disable-git-update) git_update=no
  ;;
  --enable-debug-mutex) debug_mutex=yes
  ;;
  --disable-debug-mutex) debug_mutex=no
  ;;
  --enable-libpmem) libpmem=yes
  ;;
  --disable-libpmem) libpmem=no
  ;;
  --enable-xkbcommon) xkbcommon="enabled"
  ;;
  --disable-xkbcommon) xkbcommon="disabled"
  ;;
  --enable-plugins) plugins="yes"
  ;;
  --disable-plugins) plugins="no"
  ;;
  --enable-containers) use_containers="yes"
  ;;
  --disable-containers) use_containers="no"
  ;;
  --enable-fuzzing) fuzzing=yes
  ;;
  --disable-fuzzing) fuzzing=no
  ;;
  --gdb=*) gdb_bin="$optarg"
  ;;
  --enable-rng-none) rng_none=yes
  ;;
  --disable-rng-none) rng_none=no
  ;;
  --enable-keyring) secret_keyring="yes"
  ;;
  --disable-keyring) secret_keyring="no"
  ;;
  --enable-libdaxctl) libdaxctl=yes
  ;;
  --disable-libdaxctl) libdaxctl=no
  ;;
  --enable-fuse) fuse="enabled"
  ;;
  --disable-fuse) fuse="disabled"
  ;;
  --enable-fuse-lseek) fuse_lseek="enabled"
  ;;
  --disable-fuse-lseek) fuse_lseek="disabled"
  ;;
  *)
      echo "ERROR: unknown option $opt"
      echo "Try '$0 --help' for more information"
      exit 1
  ;;
  esac
done

libdir="${libdir:-$prefix/lib}"
libexecdir="${libexecdir:-$prefix/libexec}"
includedir="${includedir:-$prefix/include}"

if test "$mingw32" = "yes" ; then
    mandir="$prefix"
    datadir="$prefix"
    docdir="$prefix"
    bindir="$prefix"
    sysconfdir="$prefix"
    local_statedir="$prefix"
else
    mandir="${mandir:-$prefix/share/man}"
    datadir="${datadir:-$prefix/share}"
    docdir="${docdir:-$prefix/share/doc}"
    bindir="${bindir:-$prefix/bin}"
    sysconfdir="${sysconfdir:-$prefix/etc}"
    local_statedir="${local_statedir:-$prefix/var}"
fi
firmwarepath="${firmwarepath:-$datadir/qemu-firmware}"
localedir="${localedir:-$datadir/locale}"

case "$cpu" in
    ppc)
           CPU_CFLAGS="-m32"
           QEMU_LDFLAGS="-m32 $QEMU_LDFLAGS"
           ;;
    ppc64)
           CPU_CFLAGS="-m64"
           QEMU_LDFLAGS="-m64 $QEMU_LDFLAGS"
           ;;
    sparc)
           CPU_CFLAGS="-m32 -mv8plus -mcpu=ultrasparc"
           QEMU_LDFLAGS="-m32 -mv8plus $QEMU_LDFLAGS"
           ;;
    sparc64)
           CPU_CFLAGS="-m64 -mcpu=ultrasparc"
           QEMU_LDFLAGS="-m64 $QEMU_LDFLAGS"
           ;;
    s390)
           CPU_CFLAGS="-m31"
           QEMU_LDFLAGS="-m31 $QEMU_LDFLAGS"
           ;;
    s390x)
           CPU_CFLAGS="-m64"
           QEMU_LDFLAGS="-m64 $QEMU_LDFLAGS"
           ;;
    i386)
           CPU_CFLAGS="-m32"
           QEMU_LDFLAGS="-m32 $QEMU_LDFLAGS"
           ;;
    x86_64)
           # ??? Only extremely old AMD cpus do not have cmpxchg16b.
           # If we truly care, we should simply detect this case at
           # runtime and generate the fallback to serial emulation.
           CPU_CFLAGS="-m64 -mcx16"
           QEMU_LDFLAGS="-m64 $QEMU_LDFLAGS"
           ;;
    x32)
           CPU_CFLAGS="-mx32"
           QEMU_LDFLAGS="-mx32 $QEMU_LDFLAGS"
           ;;
    # No special flags required for other host CPUs
esac

eval "cross_cc_${cpu}=\$host_cc"
cross_cc_vars="$cross_cc_vars cross_cc_${cpu}"
QEMU_CFLAGS="$CPU_CFLAGS $QEMU_CFLAGS"

# For user-mode emulation the host arch has to be one we explicitly
# support, even if we're using TCI.
if [ "$ARCH" = "unknown" ]; then
  bsd_user="no"
  linux_user="no"
fi

default_target_list=""
deprecated_targets_list=ppc64abi32-linux-user,tilegx-linux-user,lm32-softmmu,unicore32-softmmu
deprecated_features=""
mak_wilds=""

if [ "$softmmu" = "yes" ]; then
    mak_wilds="${mak_wilds} $source_path/default-configs/targets/*-softmmu.mak"
fi
if [ "$linux_user" = "yes" ]; then
    mak_wilds="${mak_wilds} $source_path/default-configs/targets/*-linux-user.mak"
fi
if [ "$bsd_user" = "yes" ]; then
    mak_wilds="${mak_wilds} $source_path/default-configs/targets/*-bsd-user.mak"
fi

# If the user doesn't explicitly specify a deprecated target we will
# skip it.
if test -z "$target_list"; then
    if test -z "$target_list_exclude"; then
        target_list_exclude="$deprecated_targets_list"
    else
        target_list_exclude="$target_list_exclude,$deprecated_targets_list"
    fi
fi

for config in $mak_wilds; do
    target="$(basename "$config" .mak)"
    if echo "$target_list_exclude" | grep -vq "$target"; then
        default_target_list="${default_target_list} $target"
    fi
done

# Enumerate public trace backends for --help output
trace_backend_list=$(echo $(grep -le '^PUBLIC = True$' "$source_path"/scripts/tracetool/backend/*.py | sed -e 's/^.*\/\(.*\)\.py$/\1/'))

if test x"$show_help" = x"yes" ; then
cat << EOF

Usage: configure [options]
Options: [defaults in brackets after descriptions]

Standard options:
  --help                   print this message
  --prefix=PREFIX          install in PREFIX [$prefix]
  --interp-prefix=PREFIX   where to find shared libraries, etc.
                           use %M for cpu name [$interp_prefix]
  --target-list=LIST       set target list (default: build all non-deprecated)
$(echo Available targets: $default_target_list | \
  fold -s -w 53 | sed -e 's/^/                           /')
$(echo Deprecated targets: $deprecated_targets_list | \
  fold -s -w 53 | sed -e 's/^/                           /')
  --target-list-exclude=LIST exclude a set of targets from the default target-list

Advanced options (experts only):
  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]
  --cc=CC                  use C compiler CC [$cc]
  --iasl=IASL              use ACPI compiler IASL [$iasl]
  --host-cc=CC             use C compiler CC [$host_cc] for code run at
                           build time
  --cxx=CXX                use C++ compiler CXX [$cxx]
  --objcc=OBJCC            use Objective-C compiler OBJCC [$objcc]
  --extra-cflags=CFLAGS    append extra C compiler flags QEMU_CFLAGS
  --extra-cxxflags=CXXFLAGS append extra C++ compiler flags QEMU_CXXFLAGS
  --extra-ldflags=LDFLAGS  append extra linker flags LDFLAGS
  --cross-cc-ARCH=CC       use compiler when building ARCH guest test cases
  --cross-cc-flags-ARCH=   use compiler flags when building ARCH guest tests
  --make=MAKE              use specified make [$make]
  --python=PYTHON          use specified python [$python]
  --sphinx-build=SPHINX    use specified sphinx-build [$sphinx_build]
  --meson=MESON            use specified meson [$meson]
  --ninja=NINJA            use specified ninja [$ninja]
  --smbd=SMBD              use specified smbd [$smbd]
  --with-git=GIT           use specified git [$git]
  --static                 enable static build [$static]
  --mandir=PATH            install man pages in PATH
  --datadir=PATH           install firmware in PATH/$qemu_suffix
  --localedir=PATH         install translation in PATH/$qemu_suffix
  --docdir=PATH            install documentation in PATH/$qemu_suffix
  --bindir=PATH            install binaries in PATH
  --libdir=PATH            install libraries in PATH
  --libexecdir=PATH        install helper binaries in PATH
  --sysconfdir=PATH        install config in PATH/$qemu_suffix
  --localstatedir=PATH     install local state in PATH (set at runtime on win32)
  --firmwarepath=PATH      search PATH for firmware files
  --efi-aarch64=PATH       PATH of efi file to use for aarch64 VMs.
  --with-suffix=SUFFIX     suffix for QEMU data inside datadir/libdir/sysconfdir/docdir [$qemu_suffix]
  --with-pkgversion=VERS   use specified string as sub-version of the package
  --enable-debug           enable common debug build options
  --enable-sanitizers      enable default sanitizers
  --enable-tsan            enable thread sanitizer
  --disable-strip          disable stripping binaries
  --disable-werror         disable compilation abort on warning
  --disable-stack-protector disable compiler-provided stack protection
  --audio-drv-list=LIST    set audio drivers list:
                           Available drivers: $audio_possible_drivers
  --block-drv-whitelist=L  Same as --block-drv-rw-whitelist=L
  --block-drv-rw-whitelist=L
                           set block driver read-write whitelist
                           (affects only QEMU, not qemu-img)
  --block-drv-ro-whitelist=L
                           set block driver read-only whitelist
                           (affects only QEMU, not qemu-img)
  --enable-trace-backends=B Set trace backend
                           Available backends: $trace_backend_list
  --with-trace-file=NAME   Full PATH,NAME of file to store traces
                           Default:trace-<pid>
  --disable-slirp          disable SLIRP userspace network connectivity
  --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)
  --enable-malloc-trim     enable libc malloc_trim() for memory optimization
  --oss-lib                path to OSS library
  --cpu=CPU                Build for host CPU [$cpu]
  --with-coroutine=BACKEND coroutine backend. Supported options:
                           ucontext, sigaltstack, windows
  --enable-gcov            enable test coverage analysis with gcov
  --disable-blobs          disable installing provided firmware blobs
  --with-vss-sdk=SDK-path  enable Windows VSS support in QEMU Guest Agent
  --with-win-sdk=SDK-path  path to Windows Platform SDK (to build VSS .tlb)
  --tls-priority           default TLS protocol/cipher priority string
  --enable-gprof           QEMU profiling with gprof
  --enable-profiler        profiler support
  --enable-debug-stack-usage
                           track the maximum stack usage of stacks created by qemu_alloc_stack
  --enable-plugins
                           enable plugins via shared library loading
  --disable-containers     don't use containers for cross-building
  --gdb=GDB-path           gdb to use for gdbstub tests [$gdb_bin]

Optional features, enabled with --enable-FEATURE and
disabled with --disable-FEATURE, default is enabled if available:

  system          all system emulation targets
  user            supported user emulation targets
  linux-user      all linux usermode emulation targets
  bsd-user        all BSD usermode emulation targets
  docs            build documentation
  guest-agent     build the QEMU Guest Agent
  guest-agent-msi build guest agent Windows MSI installation package
  pie             Position Independent Executables
  modules         modules support (non-Windows)
  module-upgrades try to load modules from alternate paths for upgrades
  debug-tcg       TCG debugging (default is disabled)
  debug-info      debugging information
  sparse          sparse checker
  safe-stack      SafeStack Stack Smash Protection. Depends on
                  clang/llvm >= 3.7 and requires coroutine backend ucontext.

  gnutls          GNUTLS cryptography support
  nettle          nettle cryptography support
  gcrypt          libgcrypt cryptography support
  auth-pam        PAM access control
  sdl             SDL UI
  sdl-image       SDL Image support for icons
  gtk             gtk UI
  vte             vte support for the gtk UI
  curses          curses UI
  iconv           font glyph conversion support
  vnc             VNC UI support
  vnc-sasl        SASL encryption for VNC server
  vnc-jpeg        JPEG lossy compression for VNC server
  vnc-png         PNG compression for VNC server
  cocoa           Cocoa UI (Mac OS X only)
  virtfs          VirtFS
  virtiofsd       build virtiofs daemon (virtiofsd)
  libudev         Use libudev to enumerate host devices
  mpath           Multipath persistent reservation passthrough
  xen             xen backend driver support
  xen-pci-passthrough    PCI passthrough support for Xen
  brlapi          BrlAPI (Braile)
  curl            curl connectivity
  membarrier      membarrier system call (for Linux 4.14+ or Windows)
  fdt             fdt device tree
  kvm             KVM acceleration support
  hax             HAX acceleration support
  hvf             Hypervisor.framework acceleration support
  whpx            Windows Hypervisor Platform acceleration support
  rdma            Enable RDMA-based migration
  pvrdma          Enable PVRDMA support
  vde             support for vde network
  netmap          support for netmap network
  linux-aio       Linux AIO support
  linux-io-uring  Linux io_uring support
  cap-ng          libcap-ng support
  attr            attr and xattr support
  vhost-net       vhost-net kernel acceleration support
  vhost-vsock     virtio sockets device support
  vhost-scsi      vhost-scsi kernel target support
  vhost-crypto    vhost-user-crypto backend support
  vhost-kernel    vhost kernel backend support
  vhost-user      vhost-user backend support
  vhost-user-blk-server    vhost-user-blk server support
  vhost-vdpa      vhost-vdpa kernel backend support
  spice           spice
  rbd             rados block device (rbd)
  libiscsi        iscsi support
  libnfs          nfs support
  smartcard       smartcard support (libcacard)
  u2f             U2F support (u2f-emu)
  libusb          libusb (for usb passthrough)
  live-block-migration   Block migration in the main migration stream
  usb-redir       usb network redirection support
  lzo             support of lzo compression library
  snappy          support of snappy compression library
  bzip2           support of bzip2 compression library
                  (for reading bzip2-compressed dmg images)
  lzfse           support of lzfse compression library
                  (for reading lzfse-compressed dmg images)
  zstd            support for zstd compression library
                  (for migration compression and qcow2 cluster compression)
  seccomp         seccomp support
  coroutine-pool  coroutine freelist (better performance)
  glusterfs       GlusterFS backend
  tpm             TPM support
  libssh          ssh block device support
  numa            libnuma support
  libxml2         for Parallels image format
  tcmalloc        tcmalloc support
  jemalloc        jemalloc support
  avx2            AVX2 optimization support
  avx512f         AVX512F optimization support
  replication     replication support
  opengl          opengl support
  virglrenderer   virgl rendering support
  xfsctl          xfsctl support
  qom-cast-debug  cast debugging support
  tools           build qemu-io, qemu-nbd and qemu-img tools
  bochs           bochs image format support
  cloop           cloop image format support
  dmg             dmg image format support
  qcow1           qcow v1 image format support
  vdi             vdi image format support
  vvfat           vvfat image format support
  qed             qed image format support
  parallels       parallels image format support
  sheepdog        sheepdog block driver support (deprecated)
  crypto-afalg    Linux AF_ALG crypto backend driver
  capstone        capstone disassembler support
  debug-mutex     mutex debugging support
  libpmem         libpmem support
  xkbcommon       xkbcommon support
  rng-none        dummy RNG, avoid using /dev/(u)random and getrandom()
  libdaxctl       libdaxctl support
  fuse            FUSE block device export
  fuse-lseek      SEEK_HOLE/SEEK_DATA support for FUSE exports

NOTE: The object files are built at the place where configure is launched
EOF
exit 0
fi

# Remove old dependency files to make sure that they get properly regenerated
rm -f */config-devices.mak.d

if test -z "$python"
then
    error_exit "Python not found. Use --python=/path/to/python"
fi
if ! has "$make"
then
    error_exit "GNU make ($make) not found"
fi

# Note that if the Python conditional here evaluates True we will exit
# with status 1 which is a shell 'false' value.
if ! $python -c 'import sys; sys.exit(sys.version_info < (3,6))'; then
  error_exit "Cannot use '$python', Python >= 3.6 is required." \
      "Use --python=/path/to/python to specify a supported Python."
fi

# Preserve python version since some functionality is dependent on it
python_version=$($python -c 'import sys; print("%d.%d.%d" % (sys.version_info[0], sys.version_info[1], sys.version_info[2]))' 2>/dev/null)

# Suppress writing compiled files
python="$python -B"

if test -z "$meson"; then
    if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.55.3; then
        meson=meson
    elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then
        meson=git
    elif test -e "${source_path}/meson/meson.py" ; then
        meson=internal
    else
        if test "$explicit_python" = yes; then
            error_exit "--python requires using QEMU's embedded Meson distribution, but it was not found."
        else
            error_exit "Meson not found.  Use --meson=/path/to/meson"
        fi
    fi
else
    # Meson uses its own Python interpreter to invoke other Python scripts,
    # but the user wants to use the one they specified with --python.
    #
    # We do not want to override the distro Python interpreter (and sometimes
    # cannot: for example in Homebrew /usr/bin/meson is a bash script), so
    # just require --meson=git|internal together with --python.
    if test "$explicit_python" = yes; then
        case "$meson" in
            git | internal) ;;
            *) error_exit "--python requires using QEMU's embedded Meson distribution." ;;
        esac
    fi
fi

if test "$meson" = git; then
    git_submodules="${git_submodules} meson"
fi

case "$meson" in
    git | internal)
        meson="$python ${source_path}/meson/meson.py"
        ;;
    *) meson=$(command -v "$meson") ;;
esac

# Probe for ninja

if test -z "$ninja"; then
    for c in ninja ninja-build samu; do
        if has $c; then
            ninja=$(command -v "$c")
            break
        fi
    done
    if test -z "$ninja"; then
      error_exit "Cannot find Ninja"
    fi
fi

# Check that the C compiler works. Doing this here before testing
# the host CPU ensures that we had a valid CC to autodetect the
# $cpu var (and we should bail right here if that's not the case).
# It also allows the help message to be printed without a CC.
write_c_skeleton;
if compile_object ; then
  : C compiler works ok
else
    error_exit "\"$cc\" either does not exist or does not work"
fi
if ! compile_prog ; then
    error_exit "\"$cc\" cannot build an executable (is your linker broken?)"
fi

# Consult white-list to determine whether to enable werror
# by default.  Only enable by default for git builds
if test -z "$werror" ; then
    if test -e "$source_path/.git" && \
        { test "$linux" = "yes" || test "$mingw32" = "yes"; }; then
        werror="yes"
    else
        werror="no"
    fi
fi

if test "$bogus_os" = "yes"; then
    # Now that we know that we're not printing the help and that
    # the compiler works (so the results of the check_defines we used
    # to identify the OS are reliable), if we didn't recognize the
    # host OS we should stop now.
    error_exit "Unrecognized host OS (uname -s reports '$(uname -s)')"
fi

# Check whether the compiler matches our minimum requirements:
cat > $TMPC << EOF
#if defined(__clang_major__) && defined(__clang_minor__)
# ifdef __apple_build_version__
#  if __clang_major__ < 5 || (__clang_major__ == 5 && __clang_minor__ < 1)
#   error You need at least XCode Clang v5.1 to compile QEMU
#  endif
# else
#  if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 4)
#   error You need at least Clang v3.4 to compile QEMU
#  endif
# endif
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
#  error You need at least GCC v4.8 to compile QEMU
# endif
#else
# error You either need GCC or Clang to compiler QEMU
#endif
int main (void) { return 0; }
EOF
if ! compile_prog "" "" ; then
    error_exit "You need at least GCC v4.8 or Clang v3.4 (or XCode Clang v5.1)"
fi

# Accumulate -Wfoo and -Wno-bar separately.
# We will list all of the enable flags first, and the disable flags second.
# Note that we do not add -Werror, because that would enable it for all
# configure tests. If a configure test failed due to -Werror this would
# just silently disable some features, so it's too error prone.

warn_flags=
add_to warn_flags -Wold-style-declaration
add_to warn_flags -Wold-style-definition
add_to warn_flags -Wtype-limits
add_to warn_flags -Wformat-security
add_to warn_flags -Wformat-y2k
add_to warn_flags -Winit-self
add_to warn_flags -Wignored-qualifiers
add_to warn_flags -Wempty-body
add_to warn_flags -Wnested-externs
add_to warn_flags -Wendif-labels
add_to warn_flags -Wexpansion-to-defined

nowarn_flags=
add_to nowarn_flags -Wno-initializer-overrides
add_to nowarn_flags -Wno-missing-include-dirs
add_to nowarn_flags -Wno-shift-negative-value
add_to nowarn_flags -Wno-string-plus-int
add_to nowarn_flags -Wno-typedef-redefinition
add_to nowarn_flags -Wno-tautological-type-limit-compare
add_to nowarn_flags -Wno-psabi

gcc_flags="$warn_flags $nowarn_flags"

cc_has_warning_flag() {
    write_c_skeleton;

    # Use the positive sense of the flag when testing for -Wno-wombat
    # support (gcc will happily accept the -Wno- form of unknown
    # warning options).
    optflag="$(echo $1 | sed -e 's/^-Wno-/-W/')"
    compile_prog "-Werror $optflag" ""
}

for flag in $gcc_flags; do
    if cc_has_warning_flag $flag ; then
        QEMU_CFLAGS="$QEMU_CFLAGS $flag"
    fi
done

if test "$stack_protector" != "no"; then
  cat > $TMPC << EOF
int main(int argc, char *argv[])
{
    char arr[64], *p = arr, *c = argv[0];
    while (*c) {
        *p++ = *c++;
    }
    return 0;
}
EOF
  gcc_flags="-fstack-protector-strong -fstack-protector-all"
  sp_on=0
  for flag in $gcc_flags; do
    # We need to check both a compile and a link, since some compiler
    # setups fail only on a .c->.o compile and some only at link time
    if compile_object "-Werror $flag" &&
       compile_prog "-Werror $flag" ""; then
      QEMU_CFLAGS="$QEMU_CFLAGS $flag"
      QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
      sp_on=1
      break
    fi
  done
  if test "$stack_protector" = yes; then
    if test $sp_on = 0; then
      error_exit "Stack protector not supported"
    fi
  fi
fi

# Disable -Wmissing-braces on older compilers that warn even for
# the "universal" C zero initializer {0}.
cat > $TMPC << EOF
struct {
  int a[2];
} x = {0};
EOF
if compile_object "-Werror" "" ; then
  :
else
  QEMU_CFLAGS="$QEMU_CFLAGS -Wno-missing-braces"
fi

# Our module code doesn't support Windows
if test "$modules" = "yes" && test "$mingw32" = "yes" ; then
  error_exit "Modules are not available for Windows"
fi

# module_upgrades is only reasonable if modules are enabled
if test "$modules" = "no" && test "$module_upgrades" = "yes" ; then
  error_exit "Can't enable module-upgrades as Modules are not enabled"
fi

# Static linking is not possible with modules or PIE
if test "$static" = "yes" ; then
  if test "$modules" = "yes" ; then
    error_exit "static and modules are mutually incompatible"
  fi
fi

# Unconditional check for compiler __thread support
  cat > $TMPC << EOF
static __thread int tls_var;
int main(void) { return tls_var; }
EOF

if ! compile_prog "-Werror" "" ; then
    error_exit "Your compiler does not support the __thread specifier for " \
	"Thread-Local Storage (TLS). Please upgrade to a version that does."
fi

cat > $TMPC << EOF

#ifdef __linux__
#  define THREAD __thread
#else
#  define THREAD
#endif
static THREAD int tls_var;
int main(void) { return tls_var; }
EOF

# Check we support --no-pie first; we will need this for building ROMs.
if compile_prog "-Werror -fno-pie" "-no-pie"; then
  CFLAGS_NOPIE="-fno-pie"
fi

if test "$static" = "yes"; then
  if test "$pie" != "no" && compile_prog "-Werror -fPIE -DPIE" "-static-pie"; then
    CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS"
    QEMU_LDFLAGS="-static-pie $QEMU_LDFLAGS"
    pie="yes"
  elif test "$pie" = "yes"; then
    error_exit "-static-pie not available due to missing toolchain support"
  else
    QEMU_LDFLAGS="-static $QEMU_LDFLAGS"
    pie="no"
  fi
elif test "$pie" = "no"; then
  CONFIGURE_CFLAGS="$CFLAGS_NOPIE $CONFIGURE_CFLAGS"
elif compile_prog "-Werror -fPIE -DPIE" "-pie"; then
  CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS"
  CONFIGURE_LDFLAGS="-pie $CONFIGURE_LDFLAGS"
  pie="yes"
elif test "$pie" = "yes"; then
  error_exit "PIE not available due to missing toolchain support"
else
  echo "Disabling PIE due to missing toolchain support"
  pie="no"
fi

# Detect support for PT_GNU_RELRO + DT_BIND_NOW.
# The combination is known as "full relro", because .got.plt is read-only too.
if compile_prog "" "-Wl,-z,relro -Wl,-z,now" ; then
  QEMU_LDFLAGS="-Wl,-z,relro -Wl,-z,now $QEMU_LDFLAGS"
fi

##########################################
# __sync_fetch_and_and requires at least -march=i486. Many toolchains
# use i686 as default anyway, but for those that don't, an explicit
# specification is necessary

if test "$cpu" = "i386"; then
  cat > $TMPC << EOF
static int sfaa(int *ptr)
{
  return __sync_fetch_and_and(ptr, 0);
}

int main(void)
{
  int val = 42;
  val = __sync_val_compare_and_swap(&val, 0, 1);
  sfaa(&val);
  return val;
}
EOF
  if ! compile_prog "" "" ; then
    QEMU_CFLAGS="-march=i486 $QEMU_CFLAGS"
  fi
fi

#########################################
# Solaris specific configure tool chain decisions

if test "$solaris" = "yes" ; then
  if has ar; then
    :
  else
    if test -f /usr/ccs/bin/ar ; then
      error_exit "No path includes ar" \
          "Add /usr/ccs/bin to your path and rerun configure"
    fi
    error_exit "No path includes ar"
  fi
fi

if test -z "${target_list+xxx}" ; then
    default_targets=yes
    for target in $default_target_list; do
        target_list="$target_list $target"
    done
    target_list="${target_list# }"
else
    default_targets=no
    target_list=$(echo "$target_list" | sed -e 's/,/ /g')
    for target in $target_list; do
        # Check that we recognised the target name; this allows a more
        # friendly error message than if we let it fall through.
        case " $default_target_list " in
            *" $target "*)
                ;;
            *)
                error_exit "Unknown target name '$target'"
                ;;
        esac
    done
fi

for target in $target_list; do
    # if a deprecated target is enabled we note it here
    if echo "$deprecated_targets_list" | grep -q "$target"; then
        add_to deprecated_features $target
    fi
done

# see if system emulation was really requested
case " $target_list " in
  *"-softmmu "*) softmmu=yes
  ;;
  *) softmmu=no
  ;;
esac

feature_not_found() {
  feature=$1
  remedy=$2

  error_exit "User requested feature $feature" \
      "configure was not able to find it." \
      "$remedy"
}

# ---
# big/little endian test
cat > $TMPC << EOF
short big_endian[] = { 0x4269, 0x4765, 0x4e64, 0x4961, 0x4e00, 0, };
short little_endian[] = { 0x694c, 0x7454, 0x654c, 0x6e45, 0x6944, 0x6e41, 0, };
extern int foo(short *, short *);
int main(int argc, char *argv[]) {
    return foo(big_endian, little_endian);
}
EOF

if compile_object ; then
    if strings -a $TMPO | grep -q BiGeNdIaN ; then
        bigendian="yes"
    elif strings -a $TMPO | grep -q LiTtLeEnDiAn ; then
        bigendian="no"
    else
        echo big/little test failed
    fi
else
    echo big/little test failed
fi

##########################################
# system tools
if test -z "$want_tools"; then
    if test "$softmmu" = "no"; then
        want_tools=no
    else
        want_tools=yes
    fi
fi

##########################################
# cocoa implies not SDL or GTK
# (the cocoa UI code currently assumes it is always the active UI
# and doesn't interact well with other UI frontend code)
if test "$cocoa" = "enabled"; then
    if test "$sdl" = "enabled"; then
        error_exit "Cocoa and SDL UIs cannot both be enabled at once"
    fi
    if test "$gtk" = "yes"; then
        error_exit "Cocoa and GTK UIs cannot both be enabled at once"
    fi
    gtk=no
    sdl=disabled
fi

# Some versions of Mac OS X incorrectly define SIZE_MAX
cat > $TMPC << EOF
#include <stdint.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
    return printf("%zu", SIZE_MAX);
}
EOF
have_broken_size_max=no
if ! compile_object -Werror ; then
    have_broken_size_max=yes
fi

##########################################
# L2TPV3 probe

cat > $TMPC <<EOF
#include <sys/socket.h>
#include <linux/ip.h>
int main(void) { return sizeof(struct mmsghdr); }
EOF
if compile_prog "" "" ; then
  l2tpv3=yes
else
  l2tpv3=no
fi

cat > $TMPC <<EOF
#include <sys/mman.h>
int main(int argc, char *argv[]) {
    return mlockall(MCL_FUTURE);
}
EOF
if compile_prog "" "" ; then
  have_mlockall=yes
else
  have_mlockall=no
fi

#########################################
# vhost interdependencies and host support

# vhost backends
if test "$vhost_user" = "yes" && test "$linux" != "yes"; then
  error_exit "vhost-user is only available on Linux"
fi
test "$vhost_vdpa" = "" && vhost_vdpa=$linux
if test "$vhost_vdpa" = "yes" && test "$linux" != "yes"; then
  error_exit "vhost-vdpa is only available on Linux"
fi
test "$vhost_kernel" = "" && vhost_kernel=$linux
if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
  error_exit "vhost-kernel is only available on Linux"
fi

# vhost-kernel devices
test "$vhost_scsi" = "" && vhost_scsi=$vhost_kernel
if test "$vhost_scsi" = "yes" && test "$vhost_kernel" != "yes"; then
  error_exit "--enable-vhost-scsi requires --enable-vhost-kernel"
fi
test "$vhost_vsock" = "" && vhost_vsock=$vhost_kernel
if test "$vhost_vsock" = "yes" && test "$vhost_kernel" != "yes"; then
  error_exit "--enable-vhost-vsock requires --enable-vhost-kernel"
fi

# vhost-user backends
test "$vhost_net_user" = "" && vhost_net_user=$vhost_user
if test "$vhost_net_user" = "yes" && test "$vhost_user" = "no"; then
  error_exit "--enable-vhost-net-user requires --enable-vhost-user"
fi
test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
  error_exit "--enable-vhost-crypto requires --enable-vhost-user"
fi
test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
  error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
fi
#vhost-vdpa backends
test "$vhost_net_vdpa" = "" && vhost_net_vdpa=$vhost_vdpa
if test "$vhost_net_vdpa" = "yes" && test "$vhost_vdpa" = "no"; then
  error_exit "--enable-vhost-net-vdpa requires --enable-vhost-vdpa"
fi

# OR the vhost-kernel, vhost-vdpa and vhost-user values for simplicity
if test "$vhost_net" = ""; then
  test "$vhost_net_user" = "yes" && vhost_net=yes
  test "$vhost_net_vdpa" = "yes" && vhost_net=yes
  test "$vhost_kernel" = "yes" && vhost_net=yes
fi

##########################################
# pkg-config probe

if ! has "$pkg_config_exe"; then
  error_exit "pkg-config binary '$pkg_config_exe' not found"
fi

##########################################
# NPTL probe

if test "$linux_user" = "yes"; then
  cat > $TMPC <<EOF
#include <sched.h>
#include <linux/futex.h>
int main(void) {
#if !defined(CLONE_SETTLS) || !defined(FUTEX_WAIT)
#error bork
#endif
  return 0;
}
EOF
  if ! compile_object ; then
    feature_not_found "nptl" "Install glibc and linux kernel headers."
  fi
fi

##########################################
# lzo check

if test "$lzo" != "no" ; then
    cat > $TMPC << EOF
#include <lzo/lzo1x.h>
int main(void) { lzo_version(); return 0; }
EOF
    if compile_prog "" "-llzo2" ; then
        lzo_libs="-llzo2"
        lzo="yes"
    else
        if test "$lzo" = "yes"; then
            feature_not_found "liblzo2" "Install liblzo2 devel"
        fi
        lzo="no"
    fi
fi

##########################################
# snappy check

if test "$snappy" != "no" ; then
    cat > $TMPC << EOF
#include <snappy-c.h>
int main(void) { snappy_max_compressed_length(4096); return 0; }
EOF
    if compile_prog "" "-lsnappy" ; then
        snappy_libs='-lsnappy'
        snappy="yes"
    else
        if test "$snappy" = "yes"; then
            feature_not_found "libsnappy" "Install libsnappy devel"
        fi
        snappy="no"
    fi
fi

##########################################
# bzip2 check

if test "$bzip2" != "no" ; then
    cat > $TMPC << EOF
#include <bzlib.h>
int main(void) { BZ2_bzlibVersion(); return 0; }
EOF
    if compile_prog "" "-lbz2" ; then
        bzip2="yes"
    else
        if test "$bzip2" = "yes"; then
            feature_not_found "libbzip2" "Install libbzip2 devel"
        fi
        bzip2="no"
    fi
fi

##########################################
# lzfse check

if test "$lzfse" != "no" ; then
    cat > $TMPC << EOF
#include <lzfse.h>
int main(void) { lzfse_decode_scratch_size(); return 0; }
EOF
    if compile_prog "" "-llzfse" ; then
        lzfse="yes"
    else
        if test "$lzfse" = "yes"; then
            feature_not_found "lzfse" "Install lzfse devel"
        fi
        lzfse="no"
    fi
fi

##########################################
# zstd check

if test "$zstd" != "no" ; then
    libzstd_minver="1.4.0"
    if $pkg_config --atleast-version=$libzstd_minver libzstd ; then
        zstd_cflags="$($pkg_config --cflags libzstd)"
        zstd_libs="$($pkg_config --libs libzstd)"
        zstd="yes"
    else
        if test "$zstd" = "yes" ; then
            feature_not_found "libzstd" "Install libzstd devel"
        fi
        zstd="no"
    fi
fi

##########################################
# libseccomp check

if test "$seccomp" != "no" ; then
    libseccomp_minver="2.3.0"
    if $pkg_config --atleast-version=$libseccomp_minver libseccomp ; then
        seccomp_cflags="$($pkg_config --cflags libseccomp)"
        seccomp_libs="$($pkg_config --libs libseccomp)"
        seccomp="yes"
    else
        if test "$seccomp" = "yes" ; then
            feature_not_found "libseccomp" \
                 "Install libseccomp devel >= $libseccomp_minver"
        fi
        seccomp="no"
    fi
fi

##########################################
# xen probe

if test "$xen" != "disabled" ; then
  # Check whether Xen library path is specified via --extra-ldflags to avoid
  # overriding this setting with pkg-config output. If not, try pkg-config
  # to obtain all needed flags.

  if ! echo $EXTRA_LDFLAGS | grep tools/libxc > /dev/null && \
     $pkg_config --exists xencontrol ; then
    xen_ctrl_version="$(printf '%d%02d%02d' \
      $($pkg_config --modversion xencontrol | sed 's/\./ /g') )"
    xen=enabled
    xen_pc="xencontrol xenstore xenforeignmemory xengnttab"
    xen_pc="$xen_pc xenevtchn xendevicemodel"
    if $pkg_config --exists xentoolcore; then
      xen_pc="$xen_pc xentoolcore"
    fi
    xen_cflags="$($pkg_config --cflags $xen_pc)"
    xen_libs="$($pkg_config --libs $xen_pc)"
  else

    xen_libs="-lxenstore -lxenctrl"
    xen_stable_libs="-lxenforeignmemory -lxengnttab -lxenevtchn"

    # First we test whether Xen headers and libraries are available.
    # If no, we are done and there is no Xen support.
    # If yes, more tests are run to detect the Xen version.

    # Xen (any)
    cat > $TMPC <<EOF
#include <xenctrl.h>
int main(void) {
  return 0;
}
EOF
    if ! compile_prog "" "$xen_libs" ; then
      # Xen not found
      if test "$xen" = "enabled" ; then
        feature_not_found "xen" "Install xen devel"
      fi
      xen=disabled

    # Xen unstable
    elif
        cat > $TMPC <<EOF &&
#undef XC_WANT_COMPAT_DEVICEMODEL_API
#define __XEN_TOOLS__
#include <xendevicemodel.h>
#include <xenforeignmemory.h>
int main(void) {
  xendevicemodel_handle *xd;
  xenforeignmemory_handle *xfmem;

  xd = xendevicemodel_open(0, 0);
  xendevicemodel_pin_memory_cacheattr(xd, 0, 0, 0, 0);

  xfmem = xenforeignmemory_open(0, 0);
  xenforeignmemory_map_resource(xfmem, 0, 0, 0, 0, 0, NULL, 0, 0);

  return 0;
}
EOF
        compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs -lxentoolcore"
      then
      xen_stable_libs="-lxendevicemodel $xen_stable_libs -lxentoolcore"
      xen_ctrl_version=41100
      xen=enabled
    elif
        cat > $TMPC <<EOF &&
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
#include <xenforeignmemory.h>
#include <xentoolcore.h>
int main(void) {
  xenforeignmemory_handle *xfmem;

  xfmem = xenforeignmemory_open(0, 0);
  xenforeignmemory_map2(xfmem, 0, 0, 0, 0, 0, 0, 0);
  xentoolcore_restrict_all(0);

  return 0;
}
EOF
        compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs -lxentoolcore"
      then
      xen_stable_libs="-lxendevicemodel $xen_stable_libs -lxentoolcore"
      xen_ctrl_version=41000
      xen=enabled
    elif
        cat > $TMPC <<EOF &&
#undef XC_WANT_COMPAT_DEVICEMODEL_API
#define __XEN_TOOLS__
#include <xendevicemodel.h>
int main(void) {
  xendevicemodel_handle *xd;

  xd = xendevicemodel_open(0, 0);
  xendevicemodel_close(xd);

  return 0;
}
EOF
        compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs"
      then
      xen_stable_libs="-lxendevicemodel $xen_stable_libs"
      xen_ctrl_version=40900
      xen=enabled
    elif
        cat > $TMPC <<EOF &&
/*
 * If we have stable libs the we don't want the libxc compat
 * layers, regardless of what CFLAGS we may have been given.
 *
 * Also, check if xengnttab_grant_copy_segment_t is defined and
 * grant copy operation is implemented.
 */
#undef XC_WANT_COMPAT_EVTCHN_API
#undef XC_WANT_COMPAT_GNTTAB_API
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
#include <xenctrl.h>
#include <xenstore.h>
#include <xenevtchn.h>
#include <xengnttab.h>
#include <xenforeignmemory.h>
#include <stdint.h>
#include <xen/hvm/hvm_info_table.h>
#if !defined(HVM_MAX_VCPUS)
# error HVM_MAX_VCPUS not defined
#endif
int main(void) {
  xc_interface *xc = NULL;
  xenforeignmemory_handle *xfmem;
  xenevtchn_handle *xe;
  xengnttab_handle *xg;
  xengnttab_grant_copy_segment_t* seg = NULL;

  xs_daemon_open();

  xc = xc_interface_open(0, 0, 0);
  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
  xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000);
  xc_hvm_create_ioreq_server(xc, 0, HVM_IOREQSRV_BUFIOREQ_ATOMIC, NULL);

  xfmem = xenforeignmemory_open(0, 0);
  xenforeignmemory_map(xfmem, 0, 0, 0, 0, 0);

  xe = xenevtchn_open(0, 0);
  xenevtchn_fd(xe);

  xg = xengnttab_open(0, 0);
  xengnttab_grant_copy(xg, 0, seg);

  return 0;
}
EOF
        compile_prog "" "$xen_libs $xen_stable_libs"
      then
      xen_ctrl_version=40800
      xen=enabled
    elif
        cat > $TMPC <<EOF &&
/*
 * If we have stable libs the we don't want the libxc compat
 * layers, regardless of what CFLAGS we may have been given.
 */
#undef XC_WANT_COMPAT_EVTCHN_API
#undef XC_WANT_COMPAT_GNTTAB_API
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
#include <xenctrl.h>
#include <xenstore.h>
#include <xenevtchn.h>
#include <xengnttab.h>
#include <xenforeignmemory.h>
#include <stdint.h>
#include <xen/hvm/hvm_info_table.h>
#if !defined(HVM_MAX_VCPUS)
# error HVM_MAX_VCPUS not defined
#endif
int main(void) {
  xc_interface *xc = NULL;
  xenforeignmemory_handle *xfmem;
  xenevtchn_handle *xe;
  xengnttab_handle *xg;

  xs_daemon_open();

  xc = xc_interface_open(0, 0, 0);
  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
  xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000);
  xc_hvm_create_ioreq_server(xc, 0, HVM_IOREQSRV_BUFIOREQ_ATOMIC, NULL);

  xfmem = xenforeignmemory_open(0, 0);
  xenforeignmemory_map(xfmem, 0, 0, 0, 0, 0);

  xe = xenevtchn_open(0, 0);
  xenevtchn_fd(xe);

  xg = xengnttab_open(0, 0);
  xengnttab_map_grant_ref(xg, 0, 0, 0);

  return 0;
}
EOF
        compile_prog "" "$xen_libs $xen_stable_libs"
      then
      xen_ctrl_version=40701
      xen=enabled

    # Xen 4.6
    elif
        cat > $TMPC <<EOF &&
#include <xenctrl.h>
#include <xenstore.h>
#include <stdint.h>
#include <xen/hvm/hvm_info_table.h>
#if !defined(HVM_MAX_VCPUS)
# error HVM_MAX_VCPUS not defined
#endif
int main(void) {
  xc_interface *xc;
  xs_daemon_open();
  xc = xc_interface_open(0, 0, 0);
  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
  xc_gnttab_open(NULL, 0);
  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
  xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000);
  xc_hvm_create_ioreq_server(xc, 0, HVM_IOREQSRV_BUFIOREQ_ATOMIC, NULL);
  xc_reserved_device_memory_map(xc, 0, 0, 0, 0, NULL, 0);
  return 0;
}
EOF
        compile_prog "" "$xen_libs"
      then
      xen_ctrl_version=40600
      xen=enabled

    # Xen 4.5
    elif
        cat > $TMPC <<EOF &&
#include <xenctrl.h>
#include <xenstore.h>
#include <stdint.h>
#include <xen/hvm/hvm_info_table.h>
#if !defined(HVM_MAX_VCPUS)
# error HVM_MAX_VCPUS not defined
#endif
int main(void) {
  xc_interface *xc;
  xs_daemon_open();
  xc = xc_interface_open(0, 0, 0);
  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
  xc_gnttab_open(NULL, 0);
  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
  xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000);
  xc_hvm_create_ioreq_server(xc, 0, 0, NULL);
  return 0;
}
EOF
        compile_prog "" "$xen_libs"
      then
      xen_ctrl_version=40500
      xen=enabled

    elif
        cat > $TMPC <<EOF &&
#include <xenctrl.h>
#include <xenstore.h>
#include <stdint.h>
#include <xen/hvm/hvm_info_table.h>
#if !defined(HVM_MAX_VCPUS)
# error HVM_MAX_VCPUS not defined
#endif
int main(void) {
  xc_interface *xc;
  xs_daemon_open();
  xc = xc_interface_open(0, 0, 0);
  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
  xc_gnttab_open(NULL, 0);
  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
  xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000);
  return 0;
}
EOF
        compile_prog "" "$xen_libs"
      then
      xen_ctrl_version=40200
      xen=enabled

    else
      if test "$xen" = "enabled" ; then
        feature_not_found "xen (unsupported version)" \
                          "Install a supported xen (xen 4.2 or newer)"
      fi
      xen=disabled
    fi

    if test "$xen" = enabled; then
      if test $xen_ctrl_version -ge 40701  ; then
        xen_libs="$xen_libs $xen_stable_libs "
      fi
    fi
  fi
fi

if test "$xen_pci_passthrough" != "disabled"; then
  if test "$xen" = "enabled" && test "$linux" = "yes"; then
    xen_pci_passthrough=enabled
  else
    if test "$xen_pci_passthrough" = "enabled"; then
      error_exit "User requested feature Xen PCI Passthrough" \
          " but this feature requires /sys from Linux"
    fi
    xen_pci_passthrough=disabled
  fi
fi

##########################################
# gettext probe
if test "$gettext" != "false" ; then
  if has xgettext; then
    gettext=true
  else
    if test "$gettext" = "true" ; then
      feature_not_found "gettext" "Install xgettext binary"
    fi
    gettext=false
  fi
fi

##########################################
# X11 probe
if $pkg_config --exists "x11"; then
    have_x11=yes
    x11_cflags=$($pkg_config --cflags x11)
    x11_libs=$($pkg_config --libs x11)
fi

##########################################
# GTK probe

if test "$gtk" != "no"; then
    gtkpackage="gtk+-3.0"
    gtkx11package="gtk+-x11-3.0"
    gtkversion="3.22.0"
    if $pkg_config --exists "$gtkpackage >= $gtkversion"; then
        gtk_cflags=$($pkg_config --cflags $gtkpackage)
        gtk_libs=$($pkg_config --libs $gtkpackage)
        gtk_version=$($pkg_config --modversion $gtkpackage)
        if $pkg_config --exists "$gtkx11package >= $gtkversion"; then
            need_x11=yes
            gtk_cflags="$gtk_cflags $x11_cflags"
            gtk_libs="$gtk_libs $x11_libs"
        fi
        gtk="yes"
    elif test "$gtk" = "yes"; then
        feature_not_found "gtk" "Install gtk3-devel"
    else
        gtk="no"
    fi
fi


##########################################
# GNUTLS probe

if test "$gnutls" != "no"; then
    pass="no"
    if $pkg_config --exists "gnutls >= 3.1.18"; then
        gnutls_cflags=$($pkg_config --cflags gnutls)
        gnutls_libs=$($pkg_config --libs gnutls)
        # Packaging for the static libraries is not always correct.
        # At least ubuntu 18.04 ships only shared libraries.
        write_c_skeleton
        if compile_prog "" "$gnutls_libs" ; then
            pass="yes"
        fi
    fi
    if test "$pass" = "no" && test "$gnutls" = "yes"; then
	feature_not_found "gnutls" "Install gnutls devel >= 3.1.18"
    else
        gnutls="$pass"
    fi
fi


# If user didn't give a --disable/enable-gcrypt flag,
# then mark as disabled if user requested nettle
# explicitly
if test -z "$gcrypt"
then
    if test "$nettle" = "yes"
    then
        gcrypt="no"
    fi
fi

# If user didn't give a --disable/enable-nettle flag,
# then mark as disabled if user requested gcrypt
# explicitly
if test -z "$nettle"
then
    if test "$gcrypt" = "yes"
    then
        nettle="no"
    fi
fi

has_libgcrypt() {
    if ! has "libgcrypt-config"
    then
	return 1
    fi

    if test -n "$cross_prefix"
    then
	host=$(libgcrypt-config --host)
	if test "$host-" != $cross_prefix
	then
	    return 1
	fi
    fi

    maj=`libgcrypt-config --version | awk -F . '{print $1}'`
    min=`libgcrypt-config --version | awk -F . '{print $2}'`

    if test $maj != 1 || test $min -lt 5
    then
       return 1
    fi

    return 0
}


if test "$nettle" != "no"; then
    pass="no"
    if $pkg_config --exists "nettle >= 2.7.1"; then
        nettle_cflags=$($pkg_config --cflags nettle)
        nettle_libs=$($pkg_config --libs nettle)
        nettle_version=$($pkg_config --modversion nettle)
        # Link test to make sure the given libraries work (e.g for static).
        write_c_skeleton
        if compile_prog "" "$nettle_libs" ; then
            if test -z "$gcrypt"; then
               gcrypt="no"
            fi
            pass="yes"
        fi
    fi
    if test "$pass" = "yes"
    then
        cat > $TMPC << EOF
#include <nettle/xts.h>
int main(void) {
  return 0;
}
EOF
        if compile_prog "$nettle_cflags" "$nettle_libs" ; then
            nettle_xts=yes
            qemu_private_xts=no
        fi
    fi
    if test "$pass" = "no" && test "$nettle" = "yes"; then
        feature_not_found "nettle" "Install nettle devel >= 2.7.1"
    else
        nettle="$pass"
    fi
fi

if test "$gcrypt" != "no"; then
    pass="no"
    if has_libgcrypt; then
        gcrypt_cflags=$(libgcrypt-config --cflags)
        gcrypt_libs=$(libgcrypt-config --libs)
        # Debian has removed -lgpg-error from libgcrypt-config
        # as it "spreads unnecessary dependencies" which in
        # turn breaks static builds...
        if test "$static" = "yes"
        then
            gcrypt_libs="$gcrypt_libs -lgpg-error"
        fi

        # Link test to make sure the given libraries work (e.g for static).
        write_c_skeleton
        if compile_prog "" "$gcrypt_libs" ; then
            pass="yes"
        fi
    fi
    if test "$pass" = "yes"; then
        gcrypt="yes"
        cat > $TMPC << EOF
#include <gcrypt.h>
int main(void) {
  gcry_mac_hd_t handle;
  gcry_mac_open(&handle, GCRY_MAC_HMAC_MD5,
                GCRY_MAC_FLAG_SECURE, NULL);
  return 0;
}
EOF
        if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
            gcrypt_hmac=yes
        fi
        cat > $TMPC << EOF
#include <gcrypt.h>
int main(void) {
  gcry_cipher_hd_t handle;
  gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_XTS, 0);
  return 0;
}
EOF
        if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
            gcrypt_xts=yes
            qemu_private_xts=no
        fi
    elif test "$gcrypt" = "yes"; then
        feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
    else
        gcrypt="no"
    fi
fi


if test "$gcrypt" = "yes" && test "$nettle" = "yes"
then
    error_exit "Only one of gcrypt & nettle can be enabled"
fi

##########################################
# libtasn1 - only for the TLS creds/session test suite

tasn1=yes
tasn1_cflags=""
tasn1_libs=""
if $pkg_config --exists "libtasn1"; then
    tasn1_cflags=$($pkg_config --cflags libtasn1)
    tasn1_libs=$($pkg_config --libs libtasn1)
else
    tasn1=no
fi


##########################################
# PAM probe

if test "$auth_pam" != "no"; then
    cat > $TMPC <<EOF
#include <security/pam_appl.h>
#include <stdio.h>
int main(void) {
   const char *service_name = "qemu";
   const char *user = "frank";
   const struct pam_conv pam_conv = { 0 };
   pam_handle_t *pamh = NULL;
   pam_start(service_name, user, &pam_conv, &pamh);
   return 0;
}
EOF
    if compile_prog "" "-lpam" ; then
        auth_pam=yes
    else
        if test "$auth_pam" = "yes"; then
            feature_not_found "PAM" "Install PAM development package"
        else
            auth_pam=no
        fi
    fi
fi

##########################################
# VTE probe

if test "$vte" != "no"; then
    vteminversion="0.32.0"
    if $pkg_config --exists "vte-2.91"; then
      vtepackage="vte-2.91"
    else
      vtepackage="vte-2.90"
    fi
    if $pkg_config --exists "$vtepackage >= $vteminversion"; then
        vte_cflags=$($pkg_config --cflags $vtepackage)
        vte_libs=$($pkg_config --libs $vtepackage)
        vteversion=$($pkg_config --modversion $vtepackage)
        vte="yes"
    elif test "$vte" = "yes"; then
        feature_not_found "vte" "Install libvte-2.90/2.91 devel"
    else
        vte="no"
    fi
fi

##########################################
# RDMA needs OpenFabrics libraries
if test "$rdma" != "no" ; then
  cat > $TMPC <<EOF
#include <rdma/rdma_cma.h>
int main(void) { return 0; }
EOF
  rdma_libs="-lrdmacm -libverbs -libumad"
  if compile_prog "" "$rdma_libs" ; then
    rdma="yes"
  else
    if test "$rdma" = "yes" ; then
        error_exit \
            " OpenFabrics librdmacm/libibverbs/libibumad not present." \
            " Your options:" \
            "  (1) Fast: Install infiniband packages (devel) from your distro." \
            "  (2) Cleanest: Install libraries from www.openfabrics.org" \
            "  (3) Also: Install softiwarp if you don't have RDMA hardware"
    fi
    rdma="no"
  fi
fi

##########################################
# PVRDMA detection

cat > $TMPC <<EOF &&
#include <sys/mman.h>

int
main(void)
{
    char buf = 0;
    void *addr = &buf;
    addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);

    return 0;
}
EOF

if test "$rdma" = "yes" ; then
    case "$pvrdma" in
    "")
        if compile_prog "" ""; then
            pvrdma="yes"
        else
            pvrdma="no"
        fi
        ;;
    "yes")
        if ! compile_prog "" ""; then
            error_exit "PVRDMA is not supported since mremap is not implemented"
        fi
        pvrdma="yes"
        ;;
    "no")
        pvrdma="no"
        ;;
    esac
else
    if test "$pvrdma" = "yes" ; then
        error_exit "PVRDMA requires rdma suppport"
    fi
    pvrdma="no"
fi

# Let's see if enhanced reg_mr is supported
if test "$pvrdma" = "yes" ; then

cat > $TMPC <<EOF &&
#include <infiniband/verbs.h>

int
main(void)
{
    struct ibv_mr *mr;
    struct ibv_pd *pd = NULL;
    size_t length = 10;
    uint64_t iova = 0;
    int access = 0;
    void *addr = NULL;

    mr = ibv_reg_mr_iova(pd, addr, length, iova, access);

    ibv_dereg_mr(mr);

    return 0;
}
EOF
    if ! compile_prog "" "-libverbs"; then
        QEMU_CFLAGS="$QEMU_CFLAGS -DLEGACY_RDMA_REG_MR"
    fi
fi

##########################################
# xfsctl() probe, used for file-posix.c
if test "$xfs" != "no" ; then
  cat > $TMPC << EOF
#include <stddef.h>  /* NULL */
#include <xfs/xfs.h>
int main(void)
{
    xfsctl(NULL, 0, 0, NULL);
    return 0;
}
EOF
  if compile_prog "" "" ; then
    xfs="yes"
  else
    if test "$xfs" = "yes" ; then
      feature_not_found "xfs" "Install xfsprogs/xfslibs devel"
    fi
    xfs=no
  fi
fi

##########################################
# vde libraries probe
if test "$vde" != "no" ; then
  vde_libs="-lvdeplug"
  cat > $TMPC << EOF
#include <libvdeplug.h>
int main(void)
{
    struct vde_open_args a = {0, 0, 0};
    char s[] = "";
    vde_open(s, s, &a);
    return 0;
}
EOF
  if compile_prog "" "$vde_libs" ; then
    vde=yes
  else
    if test "$vde" = "yes" ; then
      feature_not_found "vde" "Install vde (Virtual Distributed Ethernet) devel"
    fi
    vde=no
  fi
fi

##########################################
# netmap support probe
# Apart from looking for netmap headers, we make sure that the host API version
# supports the netmap backend (>=11). The upper bound (15) is meant to simulate
# a minor/major version number. Minor new features will be marked with values up
# to 15, and if something happens that requires a change to the backend we will
# move above 15, submit the backend fixes and modify this two bounds.
if test "$netmap" != "no" ; then
  cat > $TMPC << EOF
#include <inttypes.h>
#include <net/if.h>
#include <net/netmap.h>
#include <net/netmap_user.h>
#if (NETMAP_API < 11) || (NETMAP_API > 15)
#error
#endif
int main(void) { return 0; }
EOF
  if compile_prog "" "" ; then
    netmap=yes
  else
    if test "$netmap" = "yes" ; then
      feature_not_found "netmap"
    fi
    netmap=no
  fi
fi

##########################################
# libcap-ng library probe
if test "$cap_ng" != "no" ; then
  cap_libs="-lcap-ng"
  cat > $TMPC << EOF
#include <cap-ng.h>
int main(void)
{
    capng_capability_to_name(CAPNG_EFFECTIVE);
    return 0;
}
EOF
  if compile_prog "" "$cap_libs" ; then
    cap_ng=yes
  else
    if test "$cap_ng" = "yes" ; then
      feature_not_found "cap_ng" "Install libcap-ng devel"
    fi
    cap_ng=no
  fi
fi

##########################################
# Sound support libraries probe

audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/,/ /g')
for drv in $audio_drv_list; do
    case $drv in
    alsa | try-alsa)
    if $pkg_config alsa --exists; then
        alsa_libs=$($pkg_config alsa --libs)
        alsa_cflags=$($pkg_config alsa --cflags)
        alsa=yes
        if test "$drv" = "try-alsa"; then
            audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-alsa/alsa/')
        fi
    else
        if test "$drv" = "try-alsa"; then
            audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-alsa//')
        else
            error_exit "$drv check failed" \
                "Make sure to have the $drv libs and headers installed."
        fi
    fi
    ;;

    pa | try-pa)
    if $pkg_config libpulse --exists; then
        libpulse=yes
        pulse_libs=$($pkg_config libpulse --libs)
        pulse_cflags=$($pkg_config libpulse --cflags)
        if test "$drv" = "try-pa"; then
            audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-pa/pa/')
        fi
    else
        if test "$drv" = "try-pa"; then
            audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-pa//')
        else
            error_exit "$drv check failed" \
                "Make sure to have the $drv libs and headers installed."
        fi
    fi
    ;;

    sdl)
    if test "$sdl" = "no"; then
        error_exit "sdl not found or disabled, can not use sdl audio driver"
    fi
    ;;

    try-sdl)
    if test "$sdl" = "no"; then
        audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-sdl//')
    else
        audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-sdl/sdl/')
    fi
    ;;

    coreaudio)
      coreaudio_libs="-framework CoreAudio"
    ;;

    dsound)
      dsound_libs="-lole32 -ldxguid"
      audio_win_int="yes"
    ;;

    oss)
      oss_libs="$oss_lib"
    ;;

    jack | try-jack)
    if $pkg_config jack --exists; then
        libjack=yes
        jack_libs=$($pkg_config jack --libs)
        if test "$drv" = "try-jack"; then
            audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-jack/jack/')
        fi
    else
        if test "$drv" = "try-jack"; then
            audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-jack//')
        else
            error_exit "$drv check failed" \
                "Make sure to have the $drv libs and headers installed."
        fi
    fi
    ;;

    *)
    echo "$audio_possible_drivers" | grep -q "\<$drv\>" || {
        error_exit "Unknown driver '$drv' selected" \
            "Possible drivers are: $audio_possible_drivers"
    }
    ;;
    esac
done

##########################################
# BrlAPI probe

if test "$brlapi" != "no" ; then
  brlapi_libs="-lbrlapi"
  cat > $TMPC << EOF
#include <brlapi.h>
#include <stddef.h>
int main( void ) { return brlapi__openConnection (NULL, NULL, NULL); }
EOF
  if compile_prog "" "$brlapi_libs" ; then
    brlapi=yes
  else
    if test "$brlapi" = "yes" ; then
      feature_not_found "brlapi" "Install brlapi devel"
    fi
    brlapi=no
  fi
fi

##########################################
# curl probe
if test "$curl" != "no" ; then
  if $pkg_config libcurl --exists; then
    curlconfig="$pkg_config libcurl"
  else
    curlconfig=curl-config
  fi
  cat > $TMPC << EOF
#include <curl/curl.h>
int main(void) { curl_easy_init(); curl_multi_setopt(0, 0, 0); return 0; }
EOF
  curl_cflags=$($curlconfig --cflags 2>/dev/null)
  curl_libs=$($curlconfig --libs 2>/dev/null)
  if compile_prog "$curl_cflags" "$curl_libs" ; then
    curl=yes
  else
    if test "$curl" = "yes" ; then
      feature_not_found "curl" "Install libcurl devel"
    fi
    curl=no
  fi
fi # test "$curl"

##########################################
# glib support probe

glib_req_ver=2.48
glib_modules=gthread-2.0
if test "$modules" = yes; then
    glib_modules="$glib_modules gmodule-export-2.0"
fi
if test "$plugins" = yes; then
    glib_modules="$glib_modules gmodule-2.0"
fi

for i in $glib_modules; do
    if $pkg_config --atleast-version=$glib_req_ver $i; then
        glib_cflags=$($pkg_config --cflags $i)
        glib_libs=$($pkg_config --libs $i)
    else
        error_exit "glib-$glib_req_ver $i is required to compile QEMU"
    fi
done

# This workaround is required due to a bug in pkg-config file for glib as it
# doesn't define GLIB_STATIC_COMPILATION for pkg-config --static

if test "$static" = yes && test "$mingw32" = yes; then
    glib_cflags="-DGLIB_STATIC_COMPILATION $glib_cflags"
fi

if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
    gio_cflags=$($pkg_config --cflags gio-2.0)
    gio_libs=$($pkg_config --libs gio-2.0)
    gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
    if [ ! -x "$gdbus_codegen" ]; then
        gdbus_codegen=
    fi
    # Check that the libraries actually work -- Ubuntu 18.04 ships
    # with pkg-config --static --libs data for gio-2.0 that is missing
    # -lblkid and will give a link error.
    cat > $TMPC <<EOF
#include <gio/gio.h>
int main(void)
{
    g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
    return 0;
}
EOF
    if compile_prog "$gio_cflags" "$gio_libs" ; then
        gio=yes
    else
        gio=no
    fi
else
    gio=no
fi

if $pkg_config --atleast-version=$glib_req_ver gio-unix-2.0; then
    gio_cflags="$gio_cflags $($pkg_config --cflags gio-unix-2.0)"
    gio_libs="$gio_libs $($pkg_config --libs gio-unix-2.0)"
fi

# Sanity check that the current size_t matches the
# size that glib thinks it should be. This catches
# problems on multi-arch where people try to build
# 32-bit QEMU while pointing at 64-bit glib headers
cat > $TMPC <<EOF
#include <glib.h>
#include <unistd.h>

#define QEMU_BUILD_BUG_ON(x) \
  typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));

int main(void) {
   QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
   return 0;
}
EOF

if ! compile_prog "$glib_cflags" "$glib_libs" ; then
    error_exit "sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T."\
               "You probably need to set PKG_CONFIG_LIBDIR"\
	       "to point to the right pkg-config files for your"\
	       "build target"
fi

# Silence clang 3.5.0 warnings about glib attribute __alloc_size__ usage
cat > $TMPC << EOF
#include <glib.h>
int main(void) { return 0; }
EOF
if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
    if cc_has_warning_flag "-Wno-unknown-attributes"; then
        glib_cflags="-Wno-unknown-attributes $glib_cflags"
        CONFIGURE_CFLAGS="-Wno-unknown-attributes $CONFIGURE_CFLAGS"
    fi
fi

# Silence clang warnings triggered by glib < 2.57.2
cat > $TMPC << EOF
#include <glib.h>
typedef struct Foo {
    int i;
} Foo;
static void foo_free(Foo *f)
{
    g_free(f);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free);
int main(void) { return 0; }
EOF
if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
    if cc_has_warning_flag "-Wno-unused-function"; then
        glib_cflags="$glib_cflags -Wno-unused-function"
        CONFIGURE_CFLAGS="$CONFIGURE_CFLAGS -Wno-unused-function"
    fi
fi

##########################################
# SHA command probe for modules
if test "$modules" = yes; then
    shacmd_probe="sha1sum sha1 shasum"
    for c in $shacmd_probe; do
        if has $c; then
            shacmd="$c"
            break
        fi
    done
    if test "$shacmd" = ""; then
        error_exit "one of the checksum commands is required to enable modules: $shacmd_probe"
    fi
fi

##########################################
# pthread probe
PTHREADLIBS_LIST="-pthread -lpthread -lpthreadGC2"

pthread=no
cat > $TMPC << EOF
#include <pthread.h>
static void *f(void *p) { return NULL; }
int main(void) {
  pthread_t thread;
  pthread_create(&thread, 0, f, 0);
  return 0;
}
EOF
if compile_prog "" "" ; then
  pthread=yes
else
  for pthread_lib in $PTHREADLIBS_LIST; do
    if compile_prog "" "$pthread_lib" ; then
      pthread=yes
      found=no
      for lib_entry in $LIBS; do
        if test "$lib_entry" = "$pthread_lib"; then
          found=yes
          break
        fi
      done
      if test "$found" = "no"; then
        LIBS="$pthread_lib $LIBS"
      fi
      break
    fi
  done
fi

if test "$mingw32" != yes && test "$pthread" = no; then
  error_exit "pthread check failed" \
      "Make sure to have the pthread libs and headers installed."
fi

# check for pthread_setname_np with thread id
pthread_setname_np_w_tid=no
cat > $TMPC << EOF
#include <pthread.h>

static void *f(void *p) { return NULL; }
int main(void)
{
    pthread_t thread;
    pthread_create(&thread, 0, f, 0);
    pthread_setname_np(thread, "QEMU");
    return 0;
}
EOF
if compile_prog "" "$pthread_lib" ; then
  pthread_setname_np_w_tid=yes
fi

# check for pthread_setname_np without thread id
pthread_setname_np_wo_tid=no
cat > $TMPC << EOF
#include <pthread.h>

static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
int main(void)
{
    pthread_t thread;
    pthread_create(&thread, 0, f, 0);
    return 0;
}
EOF
if compile_prog "" "$pthread_lib" ; then
  pthread_setname_np_wo_tid=yes
fi

##########################################
# rbd probe
if test "$rbd" != "no" ; then
  cat > $TMPC <<EOF
#include <stdio.h>
#include <rbd/librbd.h>
int main(void) {
    rados_t cluster;
    rados_create(&cluster, NULL);
    return 0;
}
EOF
  rbd_libs="-lrbd -lrados"
  if compile_prog "" "$rbd_libs" ; then
    rbd=yes
  else
    if test "$rbd" = "yes" ; then
      feature_not_found "rados block device" "Install librbd/ceph devel"
    fi
    rbd=no
  fi
fi

##########################################
# libssh probe
if test "$libssh" != "no" ; then
  if $pkg_config --exists libssh; then
    libssh_cflags=$($pkg_config libssh --cflags)
    libssh_libs=$($pkg_config libssh --libs)
    libssh=yes
  else
    if test "$libssh" = "yes" ; then
      error_exit "libssh required for --enable-libssh"
    fi
    libssh=no
  fi
fi

##########################################
# Check for libssh 0.8
# This is done like this instead of using the LIBSSH_VERSION_* and
# SSH_VERSION_* macros because some distributions in the past shipped
# snapshots of the future 0.8 from Git, and those snapshots did not
# have updated version numbers (still referring to 0.7.0).

if test "$libssh" = "yes"; then
  cat > $TMPC <<EOF
#include <libssh/libssh.h>
int main(void) { return ssh_get_server_publickey(NULL, NULL); }
EOF
  if compile_prog "$libssh_cflags" "$libssh_libs"; then
    libssh_cflags="-DHAVE_LIBSSH_0_8 $libssh_cflags"
  fi
fi

##########################################
# linux-aio probe

if test "$linux_aio" != "no" ; then
  cat > $TMPC <<EOF
#include <libaio.h>
#include <sys/eventfd.h>
#include <stddef.h>
int main(void) { io_setup(0, NULL); io_set_eventfd(NULL, 0); eventfd(0, 0); return 0; }
EOF
  if compile_prog "" "-laio" ; then
    linux_aio=yes
  else
    if test "$linux_aio" = "yes" ; then
      feature_not_found "linux AIO" "Install libaio devel"
    fi
    linux_aio=no
  fi
fi
##########################################
# linux-io-uring probe

if test "$linux_io_uring" != "no" ; then
  if $pkg_config liburing; then
    linux_io_uring_cflags=$($pkg_config --cflags liburing)
    linux_io_uring_libs=$($pkg_config --libs liburing)
    linux_io_uring=yes
  else
    if test "$linux_io_uring" = "yes" ; then
      feature_not_found "linux io_uring" "Install liburing devel"
    fi
    linux_io_uring=no
  fi
fi

##########################################
# TPM emulation is only on POSIX

if test "$tpm" = ""; then
  if test "$mingw32" = "yes"; then
    tpm=no
  else
    tpm=yes
  fi
elif test "$tpm" = "yes"; then
  if test "$mingw32" = "yes" ; then
    error_exit "TPM emulation only available on POSIX systems"
  fi
fi

##########################################
# attr probe

libattr_libs=
if test "$attr" != "no" ; then
  cat > $TMPC <<EOF
#include <stdio.h>
#include <sys/types.h>
#ifdef CONFIG_LIBATTR
#include <attr/xattr.h>
#else
#include <sys/xattr.h>
#endif
int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }
EOF
  if compile_prog "" "" ; then
    attr=yes
  # Older distros have <attr/xattr.h>, and need -lattr:
  elif compile_prog "-DCONFIG_LIBATTR" "-lattr" ; then
    attr=yes
    libattr_libs="-lattr"
    libattr=yes
  else
    if test "$attr" = "yes" ; then
      feature_not_found "ATTR" "Install libc6 or libattr devel"
    fi
    attr=no
  fi
fi

##########################################
# iovec probe
cat > $TMPC <<EOF
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
int main(void) { return sizeof(struct iovec); }
EOF
iovec=no
if compile_prog "" "" ; then
  iovec=yes
fi

##########################################
# preadv probe
cat > $TMPC <<EOF
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
int main(void) { return preadv(0, 0, 0, 0); }
EOF
preadv=no
if compile_prog "" "" ; then
  preadv=yes
fi

##########################################
# fdt probe

case "$fdt" in
  auto | enabled | internal)
    # Simpler to always update submodule, even if not needed.
    if test -e "${source_path}/.git" && test $git_update = 'yes' ; then
      git_submodules="${git_submodules} dtc"
    fi
    ;;
esac

##########################################
# opengl probe (for sdl2, gtk, milkymist-tmu2)

gbm="no"
if $pkg_config gbm; then
    gbm_cflags="$($pkg_config --cflags gbm)"
    gbm_libs="$($pkg_config --libs gbm)"
    gbm="yes"
fi

if test "$opengl" != "no" ; then
  opengl_pkgs="epoxy gbm"
  if $pkg_config $opengl_pkgs; then
    opengl_cflags="$($pkg_config --cflags $opengl_pkgs)"
    opengl_libs="$($pkg_config --libs $opengl_pkgs)"
    opengl=yes
    if test "$gtk" = "yes" && $pkg_config --exists "$gtkpackage >= 3.16"; then
        gtk_gl="yes"
    fi
  else
    if test "$opengl" = "yes" ; then
      feature_not_found "opengl" "Please install opengl (mesa) devel pkgs: $opengl_pkgs"
    fi
    opengl_cflags=""
    opengl_libs=""
    opengl=no
  fi
fi

if test "$opengl" = "yes"; then
  cat > $TMPC << EOF
#include <epoxy/egl.h>
#ifndef EGL_MESA_image_dma_buf_export
# error mesa/epoxy lacks support for dmabufs (mesa 10.6+)
#endif
int main(void) { return 0; }
EOF
  if compile_prog "" "" ; then
    opengl_dmabuf=yes
  fi
fi

if test "$opengl" = "yes" && test "$have_x11" = "yes"; then
  for target in $target_list; do
    case $target in
      lm32-softmmu) # milkymist-tmu2 requires X11 and OpenGL
        need_x11=yes
      ;;
    esac
  done
fi

##########################################
# libxml2 probe
if test "$libxml2" != "no" ; then
    if $pkg_config --exists libxml-2.0; then
        libxml2="yes"
        libxml2_cflags=$($pkg_config --cflags libxml-2.0)
        libxml2_libs=$($pkg_config --libs libxml-2.0)
    else
        if test "$libxml2" = "yes"; then
            feature_not_found "libxml2" "Install libxml2 devel"
        fi
        libxml2="no"
    fi
fi

##########################################
# glusterfs probe
if test "$glusterfs" != "no" ; then
  if $pkg_config --atleast-version=3 glusterfs-api; then
    glusterfs="yes"
    glusterfs_cflags=$($pkg_config --cflags glusterfs-api)
    glusterfs_libs=$($pkg_config --libs glusterfs-api)
    if $pkg_config --atleast-version=4 glusterfs-api; then
      glusterfs_xlator_opt="yes"
    fi
    if $pkg_config --atleast-version=5 glusterfs-api; then
      glusterfs_discard="yes"
    fi
    if $pkg_config --atleast-version=6 glusterfs-api; then
      glusterfs_fallocate="yes"
      glusterfs_zerofill="yes"
    fi
    cat > $TMPC << EOF
#include <glusterfs/api/glfs.h>

int
main(void)
{
	/* new glfs_ftruncate() passes two additional args */
	return glfs_ftruncate(NULL, 0, NULL, NULL);
}
EOF
    if compile_prog "$glusterfs_cflags" "$glusterfs_libs" ; then
      glusterfs_ftruncate_has_stat="yes"
    fi
    cat > $TMPC << EOF
#include <glusterfs/api/glfs.h>

/* new glfs_io_cbk() passes two additional glfs_stat structs */
static void
glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
{}

int
main(void)
{
	glfs_io_cbk iocb = &glusterfs_iocb;
	iocb(NULL, 0 , NULL, NULL, NULL);
	return 0;
}
EOF
    if compile_prog "$glusterfs_cflags" "$glusterfs_libs" ; then
      glusterfs_iocb_has_stat="yes"
    fi
  else
    if test "$glusterfs" = "yes" ; then
      feature_not_found "GlusterFS backend support" \
          "Install glusterfs-api devel >= 3"
    fi
    glusterfs="no"
  fi
fi

# Check for inotify functions when we are building linux-user
# emulator.  This is done because older glibc versions don't
# have syscall stubs for these implemented.  In that case we
# don't provide them even if kernel supports them.
#
inotify=no
cat > $TMPC << EOF
#include <sys/inotify.h>

int
main(void)
{
	/* try to start inotify */
	return inotify_init();
}
EOF
if compile_prog "" "" ; then
  inotify=yes
fi

inotify1=no
cat > $TMPC << EOF
#include <sys/inotify.h>

int
main(void)
{
    /* try to start inotify */
    return inotify_init1(0);
}
EOF
if compile_prog "" "" ; then
  inotify1=yes
fi

# check if pipe2 is there
pipe2=no
cat > $TMPC << EOF
#include <unistd.h>
#include <fcntl.h>

int main(void)
{
    int pipefd[2];
    return pipe2(pipefd, O_CLOEXEC);
}
EOF
if compile_prog "" "" ; then
  pipe2=yes
fi

# check if accept4 is there
accept4=no
cat > $TMPC << EOF
#include <sys/socket.h>
#include <stddef.h>

int main(void)
{
    accept4(0, NULL, NULL, SOCK_CLOEXEC);
    return 0;
}
EOF
if compile_prog "" "" ; then
  accept4=yes
fi

# check if tee/splice is there. vmsplice was added same time.
splice=no
cat > $TMPC << EOF
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>

int main(void)
{
    int len, fd = 0;
    len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
    splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
    return 0;
}
EOF
if compile_prog "" "" ; then
  splice=yes
fi

##########################################
# libnuma probe

if test "$numa" != "no" ; then
  cat > $TMPC << EOF
#include <numa.h>
int main(void) { return numa_available(); }
EOF

  if compile_prog "" "-lnuma" ; then
    numa=yes
    numa_libs="-lnuma"
  else
    if test "$numa" = "yes" ; then
      feature_not_found "numa" "install numactl devel"
    fi
    numa=no
  fi
fi

malloc=system
if test "$tcmalloc" = "yes" && test "$jemalloc" = "yes" ; then
    echo "ERROR: tcmalloc && jemalloc can't be used at the same time"
    exit 1
elif test "$tcmalloc" = "yes" ; then
    malloc=tcmalloc
elif test "$jemalloc" = "yes" ; then
    malloc=jemalloc
fi

##########################################
# signalfd probe
signalfd="no"
cat > $TMPC << EOF
#include <unistd.h>
#include <sys/syscall.h>
#include <signal.h>
int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }
EOF

if compile_prog "" "" ; then
  signalfd=yes
fi

# check if optreset global is declared by <getopt.h>
optreset="no"
cat > $TMPC << EOF
#include <getopt.h>
int main(void) { return optreset; }
EOF

if compile_prog "" "" ; then
  optreset=yes
fi

# check if eventfd is supported
eventfd=no
cat > $TMPC << EOF
#include <sys/eventfd.h>

int main(void)
{
    return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
}
EOF
if compile_prog "" "" ; then
  eventfd=yes
fi

# check if memfd is supported
memfd=no
cat > $TMPC << EOF
#include <sys/mman.h>

int main(void)
{
    return memfd_create("foo", MFD_ALLOW_SEALING);
}
EOF
if compile_prog "" "" ; then
  memfd=yes
fi

# check for usbfs
have_usbfs=no
if test "$linux_user" = "yes"; then
  cat > $TMPC << EOF
#include <linux/usbdevice_fs.h>

#ifndef USBDEVFS_GET_CAPABILITIES
#error "USBDEVFS_GET_CAPABILITIES undefined"
#endif

#ifndef USBDEVFS_DISCONNECT_CLAIM
#error "USBDEVFS_DISCONNECT_CLAIM undefined"
#endif

int main(void)
{
    return 0;
}
EOF
  if compile_prog "" ""; then
    have_usbfs=yes
  fi
fi

# check for fallocate
fallocate=no
cat > $TMPC << EOF
#include <fcntl.h>

int main(void)
{
    fallocate(0, 0, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  fallocate=yes
fi

# check for fallocate hole punching
fallocate_punch_hole=no
cat > $TMPC << EOF
#include <fcntl.h>
#include <linux/falloc.h>

int main(void)
{
    fallocate(0, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  fallocate_punch_hole=yes
fi

# check that fallocate supports range zeroing inside the file
fallocate_zero_range=no
cat > $TMPC << EOF
#include <fcntl.h>
#include <linux/falloc.h>

int main(void)
{
    fallocate(0, FALLOC_FL_ZERO_RANGE, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  fallocate_zero_range=yes
fi

# check for posix_fallocate
posix_fallocate=no
cat > $TMPC << EOF
#include <fcntl.h>

int main(void)
{
    posix_fallocate(0, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
    posix_fallocate=yes
fi

# check for sync_file_range
sync_file_range=no
cat > $TMPC << EOF
#include <fcntl.h>

int main(void)
{
    sync_file_range(0, 0, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  sync_file_range=yes
fi

# check for linux/fiemap.h and FS_IOC_FIEMAP
fiemap=no
cat > $TMPC << EOF
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/fiemap.h>

int main(void)
{
    ioctl(0, FS_IOC_FIEMAP, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  fiemap=yes
fi

# check for dup3
dup3=no
cat > $TMPC << EOF
#include <unistd.h>

int main(void)
{
    dup3(0, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  dup3=yes
fi

# check for ppoll support
ppoll=no
cat > $TMPC << EOF
#include <poll.h>

int main(void)
{
    struct pollfd pfd = { .fd = 0, .events = 0, .revents = 0 };
    ppoll(&pfd, 1, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  ppoll=yes
fi

# check for prctl(PR_SET_TIMERSLACK , ... ) support
prctl_pr_set_timerslack=no
cat > $TMPC << EOF
#include <sys/prctl.h>

int main(void)
{
    prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  prctl_pr_set_timerslack=yes
fi

# check for epoll support
epoll=no
cat > $TMPC << EOF
#include <sys/epoll.h>

int main(void)
{
    epoll_create(0);
    return 0;
}
EOF
if compile_prog "" "" ; then
  epoll=yes
fi

# epoll_create1 is a later addition
# so we must check separately for its presence
epoll_create1=no
cat > $TMPC << EOF
#include <sys/epoll.h>

int main(void)
{
    /* Note that we use epoll_create1 as a value, not as
     * a function being called. This is necessary so that on
     * old SPARC glibc versions where the function was present in
     * the library but not declared in the header file we will
     * fail the configure check. (Otherwise we will get a compiler
     * warning but not an error, and will proceed to fail the
     * qemu compile where we compile with -Werror.)
     */
    return (int)(uintptr_t)&epoll_create1;
}
EOF
if compile_prog "" "" ; then
  epoll_create1=yes
fi

# check for sendfile support
sendfile=no
cat > $TMPC << EOF
#include <sys/sendfile.h>

int main(void)
{
    return sendfile(0, 0, 0, 0);
}
EOF
if compile_prog "" "" ; then
  sendfile=yes
fi

# check for timerfd support (glibc 2.8 and newer)
timerfd=no
cat > $TMPC << EOF
#include <sys/timerfd.h>

int main(void)
{
    return(timerfd_create(CLOCK_REALTIME, 0));
}
EOF
if compile_prog "" "" ; then
  timerfd=yes
fi

# check for setns and unshare support
setns=no
cat > $TMPC << EOF
#include <sched.h>

int main(void)
{
    int ret;
    ret = setns(0, 0);
    ret = unshare(0);
    return ret;
}
EOF
if compile_prog "" "" ; then
  setns=yes
fi

# clock_adjtime probe
clock_adjtime=no
cat > $TMPC <<EOF
#include <time.h>

int main(void)
{
    return clock_adjtime(0, 0);
}
EOF
clock_adjtime=no
if compile_prog "" "" ; then
  clock_adjtime=yes
fi

# syncfs probe
syncfs=no
cat > $TMPC <<EOF
#include <unistd.h>

int main(void)
{
    return syncfs(0);
}
EOF
syncfs=no
if compile_prog "" "" ; then
  syncfs=yes
fi

# Search for bswap_32 function
byteswap_h=no
cat > $TMPC << EOF
#include <byteswap.h>
int main(void) { return bswap_32(0); }
EOF
if compile_prog "" "" ; then
  byteswap_h=yes
fi

# Search for bswap32 function
bswap_h=no
cat > $TMPC << EOF
#include <sys/endian.h>
#include <sys/types.h>
#include <machine/bswap.h>
int main(void) { return bswap32(0); }
EOF
if compile_prog "" "" ; then
  bswap_h=yes
fi

##########################################
# Do we have libiscsi >= 1.9.0
if test "$libiscsi" != "no" ; then
  if $pkg_config --atleast-version=1.9.0 libiscsi; then
    libiscsi="yes"
    libiscsi_cflags=$($pkg_config --cflags libiscsi)
    libiscsi_libs=$($pkg_config --libs libiscsi)
  else
    if test "$libiscsi" = "yes" ; then
      feature_not_found "libiscsi" "Install libiscsi >= 1.9.0"
    fi
    libiscsi="no"
  fi
fi

##########################################
# Do we need librt
# uClibc provides 2 versions of clock_gettime(), one with realtime
# support and one without. This means that the clock_gettime() don't
# need -lrt. We still need it for timer_create() so we check for this
# function in addition.
cat > $TMPC <<EOF
#include <signal.h>
#include <time.h>
int main(void) {
  timer_create(CLOCK_REALTIME, NULL, NULL);
  return clock_gettime(CLOCK_REALTIME, NULL);
}
EOF

if compile_prog "" "" ; then
  :
# we need pthread for static linking. use previous pthread test result
elif compile_prog "" "$pthread_lib -lrt" ; then
  LIBS="$LIBS -lrt"
fi

# Check whether we have openpty() in either libc or libutil
cat > $TMPC << EOF
extern int openpty(int *am, int *as, char *name, void *termp, void *winp);
int main(void) { return openpty(0, 0, 0, 0, 0); }
EOF

have_openpty="no"
if compile_prog "" "" ; then
  have_openpty="yes"
else
  if compile_prog "" "-lutil" ; then
    have_openpty="yes"
  fi
fi

##########################################
# spice probe
if test "$spice" != "no" ; then
  cat > $TMPC << EOF
#include <spice.h>
int main(void) { spice_server_new(); return 0; }
EOF
  spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
  spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
  if $pkg_config --atleast-version=0.12.5 spice-server && \
     $pkg_config --atleast-version=0.12.3 spice-protocol && \
     compile_prog "$spice_cflags" "$spice_libs" ; then
    spice="yes"
  else
    if test "$spice" = "yes" ; then
      feature_not_found "spice" \
          "Install spice-server(>=0.12.5) and spice-protocol(>=0.12.3) devel"
    fi
    spice="no"
  fi
fi

# check for smartcard support
if test "$smartcard" != "no"; then
    if $pkg_config --atleast-version=2.5.1 libcacard; then
        libcacard_cflags=$($pkg_config --cflags libcacard)
        libcacard_libs=$($pkg_config --libs libcacard)
        smartcard="yes"
    else
        if test "$smartcard" = "yes"; then
            feature_not_found "smartcard" "Install libcacard devel"
        fi
        smartcard="no"
    fi
fi

# check for libusb
if test "$libusb" != "no" ; then
    if $pkg_config --atleast-version=1.0.13 libusb-1.0; then
        libusb="yes"
        libusb_cflags=$($pkg_config --cflags libusb-1.0)
        libusb_libs=$($pkg_config --libs libusb-1.0)
    else
        if test "$libusb" = "yes"; then
            feature_not_found "libusb" "Install libusb devel >= 1.0.13"
        fi
        libusb="no"
    fi
fi

# check for usbredirparser for usb network redirection support
if test "$usb_redir" != "no" ; then
    if $pkg_config --atleast-version=0.6 libusbredirparser-0.5; then
        usb_redir="yes"
        usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5)
        usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5)
    else
        if test "$usb_redir" = "yes"; then
            feature_not_found "usb-redir" "Install usbredir devel"
        fi
        usb_redir="no"
    fi
fi

##########################################
# check if we have VSS SDK headers for win

if test "$mingw32" = "yes" && test "$guest_agent" != "no" && \
        test "$vss_win32_sdk" != "no" ; then
  case "$vss_win32_sdk" in
    "")   vss_win32_include="-isystem $source_path" ;;
    *\ *) # The SDK is installed in "Program Files" by default, but we cannot
          # handle path with spaces. So we symlink the headers into ".sdk/vss".
          vss_win32_include="-isystem $source_path/.sdk/vss"
	  symlink "$vss_win32_sdk/inc" "$source_path/.sdk/vss/inc"
	  ;;
    *)    vss_win32_include="-isystem $vss_win32_sdk"
  esac
  cat > $TMPC << EOF
#define __MIDL_user_allocate_free_DEFINED__
#include <inc/win2003/vss.h>
int main(void) { return VSS_CTX_BACKUP; }
EOF
  if compile_prog "$vss_win32_include" "" ; then
    guest_agent_with_vss="yes"
    QEMU_CFLAGS="$QEMU_CFLAGS $vss_win32_include"
    libs_qga="-lole32 -loleaut32 -lshlwapi -lstdc++ -Wl,--enable-stdcall-fixup $libs_qga"
    qga_vss_provider="qga/vss-win32/qga-vss.dll qga/vss-win32/qga-vss.tlb"
  else
    if test "$vss_win32_sdk" != "" ; then
      echo "ERROR: Please download and install Microsoft VSS SDK:"
      echo "ERROR:   http://www.microsoft.com/en-us/download/details.aspx?id=23490"
      echo "ERROR: On POSIX-systems, you can extract the SDK headers by:"
      echo "ERROR:   scripts/extract-vsssdk-headers setup.exe"
      echo "ERROR: The headers are extracted in the directory \`inc'."
      feature_not_found "VSS support"
    fi
    guest_agent_with_vss="no"
  fi
fi

##########################################
# lookup Windows platform SDK (if not specified)
# The SDK is needed only to build .tlb (type library) file of guest agent
# VSS provider from the source. It is usually unnecessary because the
# pre-compiled .tlb file is included.

if test "$mingw32" = "yes" && test "$guest_agent" != "no" && \
        test "$guest_agent_with_vss" = "yes" ; then
  if test -z "$win_sdk"; then
    programfiles="$PROGRAMFILES"
    test -n "$PROGRAMW6432" && programfiles="$PROGRAMW6432"
    if test -n "$programfiles"; then
      win_sdk=$(ls -d "$programfiles/Microsoft SDKs/Windows/v"* | tail -1) 2>/dev/null
    else
      feature_not_found "Windows SDK"
    fi
  elif test "$win_sdk" = "no"; then
    win_sdk=""
  fi
fi

##########################################
# check if mingw environment provides a recent ntddscsi.h
if test "$mingw32" = "yes" && test "$guest_agent" != "no"; then
  cat > $TMPC << EOF
#include <windows.h>
#include <ntddscsi.h>
int main(void) {
#if !defined(IOCTL_SCSI_GET_ADDRESS)
#error Missing required ioctl definitions
#endif
  SCSI_ADDRESS addr = { .Lun = 0, .TargetId = 0, .PathId = 0 };
  return addr.Lun;
}
EOF
  if compile_prog "" "" ; then
    guest_agent_ntddscsi=yes
    libs_qga="-lsetupapi -lcfgmgr32 $libs_qga"
  fi
fi

##########################################
# virgl renderer probe

if test "$virglrenderer" != "no" ; then
  cat > $TMPC << EOF
#include <virglrenderer.h>
int main(void) { virgl_renderer_poll(); return 0; }
EOF
  virgl_cflags=$($pkg_config --cflags virglrenderer 2>/dev/null)
  virgl_libs=$($pkg_config --libs virglrenderer 2>/dev/null)
  virgl_version=$($pkg_config --modversion virglrenderer 2>/dev/null)
  if $pkg_config virglrenderer >/dev/null 2>&1 && \
     compile_prog "$virgl_cflags" "$virgl_libs" ; then
    virglrenderer="yes"
  else
    if test "$virglrenderer" = "yes" ; then
      feature_not_found "virglrenderer"
    fi
    virglrenderer="no"
  fi
fi

##########################################
# capstone

case "$capstone" in
  auto | enabled | internal)
    # Simpler to always update submodule, even if not needed.
    if test -e "${source_path}/.git" && test $git_update = 'yes' ; then
      git_submodules="${git_submodules} capstone"
    fi
    ;;
esac

##########################################
# check if we have fdatasync

fdatasync=no
cat > $TMPC << EOF
#include <unistd.h>
int main(void) {
#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
return fdatasync(0);
#else
#error Not supported
#endif
}
EOF
if compile_prog "" "" ; then
    fdatasync=yes
fi

##########################################
# check if we have madvise

madvise=no
cat > $TMPC << EOF
#include <sys/types.h>
#include <sys/mman.h>
#include <stddef.h>
int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }
EOF
if compile_prog "" "" ; then
    madvise=yes
fi

##########################################
# check if we have posix_madvise

posix_madvise=no
cat > $TMPC << EOF
#include <sys/mman.h>
#include <stddef.h>
int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }
EOF
if compile_prog "" "" ; then
    posix_madvise=yes
fi

##########################################
# check if we have posix_memalign()

posix_memalign=no
cat > $TMPC << EOF
#include <stdlib.h>
int main(void) {
    void *p;
    return posix_memalign(&p, 8, 8);
}
EOF
if compile_prog "" "" ; then
    posix_memalign=yes
fi

##########################################
# check if we have posix_syslog

posix_syslog=no
cat > $TMPC << EOF
#include <syslog.h>
int main(void) { openlog("qemu", LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "configure"); return 0; }
EOF
if compile_prog "" "" ; then
    posix_syslog=yes
fi

##########################################
# check if we have sem_timedwait

sem_timedwait=no
cat > $TMPC << EOF
#include <semaphore.h>
int main(void) { sem_t s; struct timespec t = {0}; return sem_timedwait(&s, &t); }
EOF
if compile_prog "" "" ; then
    sem_timedwait=yes
fi

##########################################
# check if we have strchrnul

strchrnul=no
cat > $TMPC << EOF
#include <string.h>
int main(void);
// Use a haystack that the compiler shouldn't be able to constant fold
char *haystack = (char*)&main;
int main(void) { return strchrnul(haystack, 'x') != &haystack[6]; }
EOF
if compile_prog "" "" ; then
    strchrnul=yes
fi

#########################################
# check if we have st_atim

st_atim=no
cat > $TMPC << EOF
#include <sys/stat.h>
#include <stddef.h>
int main(void) { return offsetof(struct stat, st_atim); }
EOF
if compile_prog "" "" ; then
    st_atim=yes
fi

##########################################
# check if trace backend exists

$python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends  > /dev/null 2> /dev/null
if test "$?" -ne 0 ; then
  error_exit "invalid trace backends" \
      "Please choose supported trace backends."
fi

##########################################
# For 'ust' backend, test if ust headers are present
if have_backend "ust"; then
  cat > $TMPC << EOF
#include <lttng/tracepoint.h>
int main(void) { return 0; }
EOF
  if compile_prog "" "-Wl,--no-as-needed -ldl" ; then
    if $pkg_config lttng-ust --exists; then
      lttng_ust_libs=$($pkg_config --libs lttng-ust)
    else
      lttng_ust_libs="-llttng-ust -ldl"
    fi
    if $pkg_config liburcu-bp --exists; then
      urcu_bp_libs=$($pkg_config --libs liburcu-bp)
    else
      urcu_bp_libs="-lurcu-bp"
    fi
  else
    error_exit "Trace backend 'ust' missing lttng-ust header files"
  fi
fi

##########################################
# For 'dtrace' backend, test if 'dtrace' command is present
if have_backend "dtrace"; then
  if ! has 'dtrace' ; then
    error_exit "dtrace command is not found in PATH $PATH"
  fi
  trace_backend_stap="no"
  if has 'stap' ; then
    trace_backend_stap="yes"

    # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
    # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
    # instead. QEMU --enable-modules depends on this because the SystemTap
    # semaphores are linked into the main binary and not the module's shared
    # object.
    QEMU_CFLAGS="$QEMU_CFLAGS -DSTAP_SDT_V2"
  fi
fi

##########################################
# check and set a backend for coroutine

# We prefer ucontext, but it's not always possible. The fallback
# is sigcontext. On Windows the only valid backend is the Windows
# specific one.

ucontext_works=no
if test "$darwin" != "yes"; then
  cat > $TMPC << EOF
#include <ucontext.h>
#ifdef __stub_makecontext
#error Ignoring glibc stub makecontext which will always fail
#endif
int main(void) { makecontext(0, 0, 0); return 0; }
EOF
  if compile_prog "" "" ; then
    ucontext_works=yes
  fi
fi

if test "$coroutine" = ""; then
  if test "$mingw32" = "yes"; then
    coroutine=win32
  elif test "$ucontext_works" = "yes"; then
    coroutine=ucontext
  else
    coroutine=sigaltstack
  fi
else
  case $coroutine in
  windows)
    if test "$mingw32" != "yes"; then
      error_exit "'windows' coroutine backend only valid for Windows"
    fi
    # Unfortunately the user visible backend name doesn't match the
    # coroutine-*.c filename for this case, so we have to adjust it here.
    coroutine=win32
    ;;
  ucontext)
    if test "$ucontext_works" != "yes"; then
      feature_not_found "ucontext"
    fi
    ;;
  sigaltstack)
    if test "$mingw32" = "yes"; then
      error_exit "only the 'windows' coroutine backend is valid for Windows"
    fi
    ;;
  *)
    error_exit "unknown coroutine backend $coroutine"
    ;;
  esac
fi

if test "$coroutine_pool" = ""; then
  coroutine_pool=yes
fi

if test "$debug_stack_usage" = "yes"; then
  if test "$coroutine_pool" = "yes"; then
    echo "WARN: disabling coroutine pool for stack usage debugging"
    coroutine_pool=no
  fi
fi

##################################################
# SafeStack


if test "$safe_stack" = "yes"; then
cat > $TMPC << EOF
int main(int argc, char *argv[])
{
#if ! __has_feature(safe_stack)
#error SafeStack Disabled
#endif
    return 0;
}
EOF
  flag="-fsanitize=safe-stack"
  # Check that safe-stack is supported and enabled.
  if compile_prog "-Werror $flag" "$flag"; then
    # Flag needed both at compilation and at linking
    QEMU_CFLAGS="$QEMU_CFLAGS $flag"
    QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
  else
    error_exit "SafeStack not supported by your compiler"
  fi
  if test "$coroutine" != "ucontext"; then
    error_exit "SafeStack is only supported by the coroutine backend ucontext"
  fi
else
cat > $TMPC << EOF
int main(int argc, char *argv[])
{
#if defined(__has_feature)
#if __has_feature(safe_stack)
#error SafeStack Enabled
#endif
#endif
    return 0;
}
EOF
if test "$safe_stack" = "no"; then
  # Make sure that safe-stack is disabled
  if ! compile_prog "-Werror" ""; then
    # SafeStack was already enabled, try to explicitly remove the feature
    flag="-fno-sanitize=safe-stack"
    if ! compile_prog "-Werror $flag" "$flag"; then
      error_exit "Configure cannot disable SafeStack"
    fi
    QEMU_CFLAGS="$QEMU_CFLAGS $flag"
    QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
  fi
else # "$safe_stack" = ""
  # Set safe_stack to yes or no based on pre-existing flags
  if compile_prog "-Werror" ""; then
    safe_stack="no"
  else
    safe_stack="yes"
    if test "$coroutine" != "ucontext"; then
      error_exit "SafeStack is only supported by the coroutine backend ucontext"
    fi
  fi
fi
fi

##########################################
# check if we have open_by_handle_at

open_by_handle_at=no
cat > $TMPC << EOF
#include <fcntl.h>
#if !defined(AT_EMPTY_PATH)
# error missing definition
#else
int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
#endif
EOF
if compile_prog "" "" ; then
    open_by_handle_at=yes
fi

########################################
# check if we have linux/magic.h

linux_magic_h=no
cat > $TMPC << EOF
#include <linux/magic.h>
int main(void) {
  return 0;
}
EOF
if compile_prog "" "" ; then
    linux_magic_h=yes
fi

########################################
# check if we have valgrind/valgrind.h

valgrind_h=no
cat > $TMPC << EOF
#include <valgrind/valgrind.h>
int main(void) {
  return 0;
}
EOF
if compile_prog "" "" ; then
    valgrind_h=yes
fi

########################################
# check if environ is declared

has_environ=no
cat > $TMPC << EOF
#include <unistd.h>
int main(void) {
    environ = 0;
    return 0;
}
EOF
if compile_prog "" "" ; then
    has_environ=yes
fi

########################################
# check if cpuid.h is usable.

cat > $TMPC << EOF
#include <cpuid.h>
int main(void) {
    unsigned a, b, c, d;
    int max = __get_cpuid_max(0, 0);

    if (max >= 1) {
        __cpuid(1, a, b, c, d);
    }

    if (max >= 7) {
        __cpuid_count(7, 0, a, b, c, d);
    }

    return 0;
}
EOF
if compile_prog "" "" ; then
    cpuid_h=yes
fi

##########################################
# avx2 optimization requirement check
#
# There is no point enabling this if cpuid.h is not usable,
# since we won't be able to select the new routines.

if test "$cpuid_h" = "yes" && test "$avx2_opt" != "no"; then
  cat > $TMPC << EOF
#pragma GCC push_options
#pragma GCC target("avx2")
#include <cpuid.h>
#include <immintrin.h>
static int bar(void *a) {
    __m256i x = *(__m256i *)a;
    return _mm256_testz_si256(x, x);
}
int main(int argc, char *argv[]) { return bar(argv[0]); }
EOF
  if compile_object "" ; then
    avx2_opt="yes"
  else
    avx2_opt="no"
  fi
fi

##########################################
# avx512f optimization requirement check
#
# There is no point enabling this if cpuid.h is not usable,
# since we won't be able to select the new routines.
# by default, it is turned off.
# if user explicitly want to enable it, check environment

if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then
  cat > $TMPC << EOF
#pragma GCC push_options
#pragma GCC target("avx512f")
#include <cpuid.h>
#include <immintrin.h>
static int bar(void *a) {
    __m512i x = *(__m512i *)a;
    return _mm512_test_epi64_mask(x, x);
}
int main(int argc, char *argv[])
{
	return bar(argv[0]);
}
EOF
  if ! compile_object "" ; then
    avx512f_opt="no"
  fi
else
  avx512f_opt="no"
fi

########################################
# check if __[u]int128_t is usable.

int128=no
cat > $TMPC << EOF
__int128_t a;
__uint128_t b;
int main (void) {
  a = a + b;
  b = a * b;
  a = a * a;
  return 0;
}
EOF
if compile_prog "" "" ; then
    int128=yes
fi

#########################################
# See if 128-bit atomic operations are supported.

atomic128=no
if test "$int128" = "yes"; then
  cat > $TMPC << EOF
int main(void)
{
  unsigned __int128 x = 0, y = 0;
  y = __atomic_load_16(&x, 0);
  __atomic_store_16(&x, y, 0);
  __atomic_compare_exchange_16(&x, &y, x, 0, 0, 0);
  return 0;
}
EOF
  if compile_prog "" "" ; then
    atomic128=yes
  fi
fi

cmpxchg128=no
if test "$int128" = yes && test "$atomic128" = no; then
  cat > $TMPC << EOF
int main(void)
{
  unsigned __int128 x = 0, y = 0;
  __sync_val_compare_and_swap_16(&x, y, x);
  return 0;
}
EOF
  if compile_prog "" "" ; then
    cmpxchg128=yes
  fi
fi

#########################################
# See if 64-bit atomic operations are supported.
# Note that without __atomic builtins, we can only
# assume atomic loads/stores max at pointer size.

cat > $TMPC << EOF
#include <stdint.h>
int main(void)
{
  uint64_t x = 0, y = 0;
#ifdef __ATOMIC_RELAXED
  y = __atomic_load_n(&x, __ATOMIC_RELAXED);
  __atomic_store_n(&x, y, __ATOMIC_RELAXED);
  __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
  __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
  __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
#else
  typedef char is_host64[sizeof(void *) >= sizeof(uint64_t) ? 1 : -1];
  __sync_lock_test_and_set(&x, y);
  __sync_val_compare_and_swap(&x, y, 0);
  __sync_fetch_and_add(&x, y);
#endif
  return 0;
}
EOF
if compile_prog "" "" ; then
  atomic64=yes
fi

#########################################
# See if --dynamic-list is supported by the linker
ld_dynamic_list="no"
if test "$static" = "no" ; then
    cat > $TMPTXT <<EOF
{
  foo;
};
EOF

    cat > $TMPC <<EOF
#include <stdio.h>
void foo(void);

void foo(void)
{
  printf("foo\n");
}

int main(void)
{
  foo();
  return 0;
}
EOF

    if compile_prog "" "-Wl,--dynamic-list=$TMPTXT" ; then
        ld_dynamic_list="yes"
    fi
fi

#########################################
# See if -exported_symbols_list is supported by the linker

ld_exported_symbols_list="no"
if test "$static" = "no" ; then
    cat > $TMPTXT <<EOF
  _foo
EOF

    if compile_prog "" "-Wl,-exported_symbols_list,$TMPTXT" ; then
        ld_exported_symbols_list="yes"
    fi
fi

if  test "$plugins" = "yes" &&
    test "$ld_dynamic_list" = "no" &&
    test "$ld_exported_symbols_list" = "no" ; then
  error_exit \
      "Plugin support requires dynamic linking and specifying a set of symbols " \
      "that are exported to plugins. Unfortunately your linker doesn't " \
      "support the flag (--dynamic-list or -exported_symbols_list) used " \
      "for this purpose. You can't build with --static."
fi

########################################
# See if __attribute__((alias)) is supported.
# This false for Xcode 9, but has been remedied for Xcode 10.
# Unfortunately, travis uses Xcode 9 by default.

attralias=no
cat > $TMPC << EOF
int x = 1;
extern const int y __attribute__((alias("x")));
int main(void) { return 0; }
EOF
if compile_prog "" "" ; then
    attralias=yes
fi

########################################
# check if getauxval is available.

getauxval=no
cat > $TMPC << EOF
#include <sys/auxv.h>
int main(void) {
  return getauxval(AT_HWCAP) == 0;
}
EOF
if compile_prog "" "" ; then
    getauxval=yes
fi

########################################
# check if ccache is interfering with
# semantic analysis of macros

unset CCACHE_CPP2
ccache_cpp2=no
cat > $TMPC << EOF
static const int Z = 1;
#define fn() ({ Z; })
#define TAUT(X) ((X) == Z)
#define PAREN(X, Y) (X == Y)
#define ID(X) (X)
int main(int argc, char *argv[])
{
    int x = 0, y = 0;
    x = ID(x);
    x = fn();
    fn();
    if (PAREN(x, y)) return 0;
    if (TAUT(Z)) return 0;
    return 0;
}
EOF

if ! compile_object "-Werror"; then
    ccache_cpp2=yes
fi

#################################################
# clang does not support glibc + FORTIFY_SOURCE.

if test "$fortify_source" != "no"; then
  if echo | $cc -dM -E - | grep __clang__ > /dev/null 2>&1 ; then
    fortify_source="no";
  elif test -n "$cxx" && has $cxx &&
       echo | $cxx -dM -E - | grep __clang__ >/dev/null 2>&1 ; then
    fortify_source="no";
  else
    fortify_source="yes"
  fi
fi

###############################################
# Check if copy_file_range is provided by glibc
have_copy_file_range=no
cat > $TMPC << EOF
#include <unistd.h>
int main(void) {
  copy_file_range(0, NULL, 0, NULL, 0, 0);
  return 0;
}
EOF
if compile_prog "" "" ; then
    have_copy_file_range=yes
fi

##########################################
# check if struct fsxattr is available via linux/fs.h

have_fsxattr=no
cat > $TMPC << EOF
#include <linux/fs.h>
struct fsxattr foo;
int main(void) {
  return 0;
}
EOF
if compile_prog "" "" ; then
    have_fsxattr=yes
fi

##########################################
# check for usable membarrier system call
if test "$membarrier" = "yes"; then
    have_membarrier=no
    if test "$mingw32" = "yes" ; then
        have_membarrier=yes
    elif test "$linux" = "yes" ; then
        cat > $TMPC << EOF
    #include <linux/membarrier.h>
    #include <sys/syscall.h>
    #include <unistd.h>
    #include <stdlib.h>
    int main(void) {
        syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
        syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
	exit(0);
    }
EOF
        if compile_prog "" "" ; then
            have_membarrier=yes
        fi
    fi
    if test "$have_membarrier" = "no"; then
      feature_not_found "membarrier" "membarrier system call not available"
    fi
else
    # Do not enable it by default even for Mingw32, because it doesn't
    # work on Wine.
    membarrier=no
fi

##########################################
# check if rtnetlink.h exists and is useful
have_rtnetlink=no
cat > $TMPC << EOF
#include <linux/rtnetlink.h>
int main(void) {
  return IFLA_PROTO_DOWN;
}
EOF
if compile_prog "" "" ; then
    have_rtnetlink=yes
fi

##########################################
# check for usable AF_VSOCK environment
have_af_vsock=no
cat > $TMPC << EOF
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#if !defined(AF_VSOCK)
# error missing AF_VSOCK flag
#endif
#include <linux/vm_sockets.h>
int main(void) {
    int sock, ret;
    struct sockaddr_vm svm;
    socklen_t len = sizeof(svm);
    sock = socket(AF_VSOCK, SOCK_STREAM, 0);
    ret = getpeername(sock, (struct sockaddr *)&svm, &len);
    if ((ret == -1) && (errno == ENOTCONN)) {
        return 0;
    }
    return -1;
}
EOF
if compile_prog "" "" ; then
    have_af_vsock=yes
fi

##########################################
# check for usable AF_ALG environment
have_afalg=no
cat > $TMPC << EOF
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_alg.h>
int main(void) {
    int sock;
    sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
    return sock;
}
EOF
if compile_prog "" "" ; then
    have_afalg=yes
fi
if test "$crypto_afalg" = "yes"
then
    if test "$have_afalg" != "yes"
    then
	error_exit "AF_ALG requested but could not be detected"
    fi
fi


#################################################
# check for sysmacros.h

have_sysmacros=no
cat > $TMPC << EOF
#include <sys/sysmacros.h>
int main(void) {
    return makedev(0, 0);
}
EOF
if compile_prog "" "" ; then
    have_sysmacros=yes
fi

##########################################
# check for _Static_assert()

have_static_assert=no
cat > $TMPC << EOF
_Static_assert(1, "success");
int main(void) {
    return 0;
}
EOF
if compile_prog "" "" ; then
    have_static_assert=yes
fi

##########################################
# check for utmpx.h, it is missing e.g. on OpenBSD

have_utmpx=no
cat > $TMPC << EOF
#include <utmpx.h>
struct utmpx user_info;
int main(void) {
    return 0;
}
EOF
if compile_prog "" "" ; then
    have_utmpx=yes
fi

##########################################
# check for getrandom()

have_getrandom=no
cat > $TMPC << EOF
#include <sys/random.h>
int main(void) {
    return getrandom(0, 0, GRND_NONBLOCK);
}
EOF
if compile_prog "" "" ; then
    have_getrandom=yes
fi

##########################################
# checks for sanitizers

have_asan=no
have_ubsan=no
have_asan_iface_h=no
have_asan_iface_fiber=no

if test "$sanitizers" = "yes" ; then
  write_c_skeleton
  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address" ""; then
      have_asan=yes
  fi

  # we could use a simple skeleton for flags checks, but this also
  # detect the static linking issue of ubsan, see also:
  # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
  cat > $TMPC << EOF
#include <stdlib.h>
int main(void) {
    void *tmp = malloc(10);
    if (tmp != NULL) {
        return *(int *)(tmp + 2);
    }
    return 1;
}
EOF
  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=undefined" ""; then
      have_ubsan=yes
  fi

  if check_include "sanitizer/asan_interface.h" ; then
      have_asan_iface_h=yes
  fi

  cat > $TMPC << EOF
#include <sanitizer/asan_interface.h>
int main(void) {
  __sanitizer_start_switch_fiber(0, 0, 0);
  return 0;
}
EOF
  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address" "" ; then
      have_asan_iface_fiber=yes
  fi
fi

##########################################
# checks for fuzzer
if test "$fuzzing" = "yes" && test -z "${LIB_FUZZING_ENGINE+xxx}"; then
  write_c_fuzzer_skeleton
  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=fuzzer" ""; then
    have_fuzzer=yes
  else
    error_exit "Your compiler doesn't support -fsanitize=fuzzer"
    exit 1
  fi
fi

# Thread sanitizer is, for now, much noisier than the other sanitizers;
# keep it separate until that is not the case.
if test "$tsan" = "yes" && test "$sanitizers" = "yes"; then
  error_exit "TSAN is not supported with other sanitiziers."
fi
have_tsan=no
have_tsan_iface_fiber=no
if test "$tsan" = "yes" ; then
  write_c_skeleton
  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=thread" "" ; then
      have_tsan=yes
  fi
  cat > $TMPC << EOF
#include <sanitizer/tsan_interface.h>
int main(void) {
  __tsan_create_fiber(0);
  return 0;
}
EOF
  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=thread" "" ; then
      have_tsan_iface_fiber=yes
  fi
fi

##########################################
# check for libpmem

if test "$libpmem" != "no"; then
	if $pkg_config --exists "libpmem"; then
		libpmem="yes"
		libpmem_libs=$($pkg_config --libs libpmem)
		libpmem_cflags=$($pkg_config --cflags libpmem)
	else
		if test "$libpmem" = "yes" ; then
			feature_not_found "libpmem" "Install nvml or pmdk"
		fi
		libpmem="no"
	fi
fi

##########################################
# check for libdaxctl

if test "$libdaxctl" != "no"; then
	if $pkg_config --atleast-version=57 "libdaxctl"; then
		libdaxctl="yes"
		libdaxctl_libs=$($pkg_config --libs libdaxctl)
		libdaxctl_cflags=$($pkg_config --cflags libdaxctl)
	else
		if test "$libdaxctl" = "yes" ; then
			feature_not_found "libdaxctl" "Install libdaxctl"
		fi
		libdaxctl="no"
	fi
fi

##########################################
# check for slirp

case "$slirp" in
  auto | enabled | internal)
    # Simpler to always update submodule, even if not needed.
    if test -e "${source_path}/.git" && test $git_update = 'yes' ; then
      git_submodules="${git_submodules} slirp"
    fi
    ;;
esac

##########################################
# check for usable __NR_keyctl syscall

if test "$linux" = "yes" ; then

    have_keyring=no
    cat > $TMPC << EOF
#include <errno.h>
#include <asm/unistd.h>
#include <linux/keyctl.h>
#include <unistd.h>
int main(void) {
    return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
}
EOF
    if compile_prog "" "" ; then
        have_keyring=yes
    fi
fi
if test "$secret_keyring" != "no"
then
    if test "$have_keyring" = "yes"
    then
	secret_keyring=yes
    else
	if test "$secret_keyring" = "yes"
	then
	    error_exit "syscall __NR_keyctl requested, \
but not implemented on your system"
	else
	    secret_keyring=no
	fi
    fi
fi

##########################################
# End of CC checks
# After here, no more $cc or $ld runs

write_c_skeleton

if test "$gcov" = "yes" ; then
  :
elif test "$fortify_source" = "yes" ; then
  QEMU_CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
  debug=no
fi

case "$ARCH" in
alpha)
  # Ensure there's only a single GP
  QEMU_CFLAGS="-msmall-data $QEMU_CFLAGS"
;;
esac

if test "$gprof" = "yes" ; then
  QEMU_CFLAGS="-p $QEMU_CFLAGS"
  QEMU_LDFLAGS="-p $QEMU_LDFLAGS"
fi

if test "$have_asan" = "yes"; then
  QEMU_CFLAGS="-fsanitize=address $QEMU_CFLAGS"
  QEMU_LDFLAGS="-fsanitize=address $QEMU_LDFLAGS"
  if test "$have_asan_iface_h" = "no" ; then
      echo "ASAN build enabled, but ASAN header missing." \
           "Without code annotation, the report may be inferior."
  elif test "$have_asan_iface_fiber" = "no" ; then
      echo "ASAN build enabled, but ASAN header is too old." \
           "Without code annotation, the report may be inferior."
  fi
fi
if test "$have_tsan" = "yes" ; then
  if test "$have_tsan_iface_fiber" = "yes" ; then
    QEMU_CFLAGS="-fsanitize=thread $QEMU_CFLAGS"
    QEMU_LDFLAGS="-fsanitize=thread $QEMU_LDFLAGS"
  else
    error_exit "Cannot enable TSAN due to missing fiber annotation interface."
  fi
elif test "$tsan" = "yes" ; then
  error_exit "Cannot enable TSAN due to missing sanitize thread interface."
fi
if test "$have_ubsan" = "yes"; then
  QEMU_CFLAGS="-fsanitize=undefined $QEMU_CFLAGS"
  QEMU_LDFLAGS="-fsanitize=undefined $QEMU_LDFLAGS"
fi

##########################################
# Do we have libnfs
if test "$libnfs" != "no" ; then
  if $pkg_config --atleast-version=1.9.3 libnfs; then
    libnfs="yes"
    libnfs_libs=$($pkg_config --libs libnfs)
  else
    if test "$libnfs" = "yes" ; then
      feature_not_found "libnfs" "Install libnfs devel >= 1.9.3"
    fi
    libnfs="no"
  fi
fi

##########################################

# Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
if test "$solaris" = "no" && test "$tsan" = "no"; then
    if $ld --version 2>/dev/null | grep "GNU ld" >/dev/null 2>/dev/null ; then
        QEMU_LDFLAGS="-Wl,--warn-common $QEMU_LDFLAGS"
    fi
fi

# Use ASLR, no-SEH and DEP if available
if test "$mingw32" = "yes" ; then
    flags="--no-seh --nxcompat"

    # Disable ASLR for debug builds to allow debugging with gdb
    if test "$debug" = "no" ; then
        flags="--dynamicbase $flags"
    fi

    for flag in $flags; do
        if ld_has $flag ; then
            QEMU_LDFLAGS="-Wl,$flag $QEMU_LDFLAGS"
        fi
    done
fi

# We can only support ivshmem if we have eventfd
if [ "$eventfd" = "yes" ]; then
  ivshmem=yes
fi

if test "$softmmu" = yes ; then
  if test "$linux" = yes; then
    if test "$virtfs" != no && test "$cap_ng" = yes && test "$attr" = yes ; then
      virtfs=yes
    else
      if test "$virtfs" = yes; then
        error_exit "VirtFS requires libcap-ng devel and libattr devel"
      fi
      virtfs=no
    fi
  else
    if test "$virtfs" = yes; then
      error_exit "VirtFS is supported only on Linux"
    fi
    virtfs=no
  fi
fi

# Probe for guest agent support/options

if [ "$guest_agent" != "no" ]; then
  if [ "$softmmu" = no -a "$want_tools" = no ] ; then
      guest_agent=no
  elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
      guest_agent=yes
  elif [ "$guest_agent" != yes ]; then
      guest_agent=no
  else
      error_exit "Guest agent is not supported on this platform"
  fi
fi

# Guest agent Window MSI  package

if test "$guest_agent" != yes; then
  if test "$guest_agent_msi" = yes; then
    error_exit "MSI guest agent package requires guest agent enabled"
  fi
  guest_agent_msi=no
elif test "$mingw32" != "yes"; then
  if test "$guest_agent_msi" = "yes"; then
    error_exit "MSI guest agent package is available only for MinGW Windows cross-compilation"
  fi
  guest_agent_msi=no
elif ! has wixl; then
  if test "$guest_agent_msi" = "yes"; then
    error_exit "MSI guest agent package requires wixl tool installed ( usually from msitools package )"
  fi
  guest_agent_msi=no
else
  # we support qemu-ga, mingw32, and wixl: default to MSI enabled if it wasn't
  # disabled explicitly
  if test "$guest_agent_msi" != "no"; then
    guest_agent_msi=yes
  fi
fi

if test "$guest_agent_msi" = "yes"; then
  if test "$guest_agent_with_vss" = "yes"; then
    QEMU_GA_MSI_WITH_VSS="-D InstallVss"
  fi

  if test "$QEMU_GA_MANUFACTURER" = ""; then
    QEMU_GA_MANUFACTURER=QEMU
  fi

  if test "$QEMU_GA_DISTRO" = ""; then
    QEMU_GA_DISTRO=Linux
  fi

  if test "$QEMU_GA_VERSION" = ""; then
      QEMU_GA_VERSION=$(cat $source_path/VERSION)
  fi

  QEMU_GA_MSI_MINGW_DLL_PATH="-D Mingw_dlls=$($pkg_config --variable=prefix glib-2.0)/bin"

  case "$cpu" in
  x86_64)
    QEMU_GA_MSI_ARCH="-a x64 -D Arch=64"
    ;;
  i386)
    QEMU_GA_MSI_ARCH="-D Arch=32"
    ;;
  *)
    error_exit "CPU $cpu not supported for building installation package"
    ;;
  esac
fi

# Mac OS X ships with a broken assembler
roms=
if { test "$cpu" = "i386" || test "$cpu" = "x86_64"; } && \
        test "$targetos" != "Darwin" && test "$targetos" != "SunOS" && \
        test "$targetos" != "Haiku" && test "$softmmu" = yes ; then
    # Different host OS linkers have different ideas about the name of the ELF
    # emulation. Linux and OpenBSD/amd64 use 'elf_i386'; FreeBSD uses the _fbsd
    # variant; OpenBSD/i386 uses the _obsd variant; and Windows uses i386pe.
    for emu in elf_i386 elf_i386_fbsd elf_i386_obsd i386pe; do
        if "$ld" -verbose 2>&1 | grep -q "^[[:space:]]*$emu[[:space:]]*$"; then
            ld_i386_emulation="$emu"
            roms="optionrom"
            break
        fi
    done
fi

# Only build s390-ccw bios if we're on s390x and the compiler has -march=z900
if test "$cpu" = "s390x" ; then
  write_c_skeleton
  if compile_prog "-march=z900" ""; then
    roms="$roms s390-ccw"
    # SLOF is required for building the s390-ccw firmware on s390x,
    # since it is using the libnet code from SLOF for network booting.
    if test -e "${source_path}/.git" ; then
      git_submodules="${git_submodules} roms/SLOF"
    fi
  fi
fi

# Check that the C++ compiler exists and works with the C compiler.
# All the QEMU_CXXFLAGS are based on QEMU_CFLAGS. Keep this at the end to don't miss any other that could be added.
if has $cxx; then
    cat > $TMPC <<EOF
int c_function(void);
int main(void) { return c_function(); }
EOF

    compile_object

    cat > $TMPCXX <<EOF
extern "C" {
   int c_function(void);
}
int c_function(void) { return 42; }
EOF

    update_cxxflags

    if do_cxx $CXXFLAGS $CONFIGURE_CXXFLAGS $QEMU_CXXFLAGS -o $TMPE $TMPCXX $TMPO $QEMU_LDFLAGS; then
        # C++ compiler $cxx works ok with C compiler $cc
        :
    else
        echo "C++ compiler $cxx does not work with C compiler $cc"
        echo "Disabling C++ specific optional code"
        cxx=
    fi
else
    echo "No C++ compiler available; disabling C++ specific optional code"
    cxx=
fi

if test $git_update = 'yes' ; then
    (cd "${source_path}" && GIT="$git" "./scripts/git-submodule.sh" update "$git_submodules")
fi

config_host_mak="config-host.mak"

echo "# Automatically generated by configure - do not modify" > $config_host_mak
echo >> $config_host_mak

echo all: >> $config_host_mak
echo "GIT=$git" >> $config_host_mak
echo "GIT_SUBMODULES=$git_submodules" >> $config_host_mak
echo "GIT_UPDATE=$git_update" >> $config_host_mak

echo "ARCH=$ARCH" >> $config_host_mak

if test "$default_devices" = "yes" ; then
  echo "CONFIG_MINIKCONF_MODE=--defconfig" >> $config_host_mak
else
  echo "CONFIG_MINIKCONF_MODE=--allnoconfig" >> $config_host_mak
fi
if test "$debug_tcg" = "yes" ; then
  echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak
fi
if test "$strip_opt" = "yes" ; then
  echo "STRIP=${strip}" >> $config_host_mak
fi
if test "$bigendian" = "yes" ; then
  echo "HOST_WORDS_BIGENDIAN=y" >> $config_host_mak
fi
if test "$mingw32" = "yes" ; then
  echo "CONFIG_WIN32=y" >> $config_host_mak
  rc_version=$(cat $source_path/VERSION)
  version_major=${rc_version%%.*}
  rc_version=${rc_version#*.}
  version_minor=${rc_version%%.*}
  rc_version=${rc_version#*.}
  version_subminor=${rc_version%%.*}
  version_micro=0
  echo "CONFIG_FILEVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak
  echo "CONFIG_PRODUCTVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak
  if test "$guest_agent_with_vss" = "yes" ; then
    echo "CONFIG_QGA_VSS=y" >> $config_host_mak
    echo "QGA_VSS_PROVIDER=$qga_vss_provider" >> $config_host_mak
    echo "WIN_SDK=\"$win_sdk\"" >> $config_host_mak
  fi
  if test "$guest_agent_ntddscsi" = "yes" ; then
    echo "CONFIG_QGA_NTDDSCSI=y" >> $config_host_mak
  fi
  if test "$guest_agent_msi" = "yes"; then
    echo "CONFIG_QGA_MSI=y" >> $config_host_mak
    echo "QEMU_GA_MSI_MINGW_DLL_PATH=${QEMU_GA_MSI_MINGW_DLL_PATH}" >> $config_host_mak
    echo "QEMU_GA_MSI_WITH_VSS=${QEMU_GA_MSI_WITH_VSS}" >> $config_host_mak
    echo "QEMU_GA_MSI_ARCH=${QEMU_GA_MSI_ARCH}" >> $config_host_mak
    echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER}" >> $config_host_mak
    echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO}" >> $config_host_mak
    echo "QEMU_GA_VERSION=${QEMU_GA_VERSION}" >> $config_host_mak
  fi
else
  echo "CONFIG_POSIX=y" >> $config_host_mak
fi

if test "$linux" = "yes" ; then
  echo "CONFIG_LINUX=y" >> $config_host_mak
fi

if test "$darwin" = "yes" ; then
  echo "CONFIG_DARWIN=y" >> $config_host_mak
fi

if test "$solaris" = "yes" ; then
  echo "CONFIG_SOLARIS=y" >> $config_host_mak
fi
if test "$haiku" = "yes" ; then
  echo "CONFIG_HAIKU=y" >> $config_host_mak
fi
if test "$static" = "yes" ; then
  echo "CONFIG_STATIC=y" >> $config_host_mak
fi
if test "$profiler" = "yes" ; then
  echo "CONFIG_PROFILER=y" >> $config_host_mak
fi
if test "$want_tools" = "yes" ; then
  echo "CONFIG_TOOLS=y" >> $config_host_mak
fi
if test "$guest_agent" = "yes" ; then
  echo "CONFIG_GUEST_AGENT=y" >> $config_host_mak
fi
echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
if test "$vde" = "yes" ; then
  echo "CONFIG_VDE=y" >> $config_host_mak
  echo "VDE_LIBS=$vde_libs" >> $config_host_mak
fi
if test "$netmap" = "yes" ; then
  echo "CONFIG_NETMAP=y" >> $config_host_mak
fi
if test "$l2tpv3" = "yes" ; then
  echo "CONFIG_L2TPV3=y" >> $config_host_mak
fi
if test "$gprof" = "yes" ; then
  echo "CONFIG_GPROF=y" >> $config_host_mak
fi
if test "$cap_ng" = "yes" ; then
  echo "CONFIG_LIBCAP_NG=y" >> $config_host_mak
  echo "LIBCAP_NG_LIBS=$cap_libs" >> $config_host_mak
fi
echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak
for drv in $audio_drv_list; do
    def=CONFIG_AUDIO_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]')
    echo "$def=y" >> $config_host_mak
done
if test "$alsa" = "yes" ; then
    echo "CONFIG_ALSA=y" >> $config_host_mak
fi
echo "ALSA_LIBS=$alsa_libs" >> $config_host_mak
echo "ALSA_CFLAGS=$alsa_cflags" >> $config_host_mak
if test "$libpulse" = "yes" ; then
    echo "CONFIG_LIBPULSE=y" >> $config_host_mak
fi
echo "PULSE_LIBS=$pulse_libs" >> $config_host_mak
echo "PULSE_CFLAGS=$pulse_cflags" >> $config_host_mak
echo "COREAUDIO_LIBS=$coreaudio_libs" >> $config_host_mak
echo "DSOUND_LIBS=$dsound_libs" >> $config_host_mak
echo "OSS_LIBS=$oss_libs" >> $config_host_mak
if test "$libjack" = "yes" ; then
    echo "CONFIG_LIBJACK=y" >> $config_host_mak
fi
echo "JACK_LIBS=$jack_libs" >> $config_host_mak
if test "$audio_win_int" = "yes" ; then
  echo "CONFIG_AUDIO_WIN_INT=y" >> $config_host_mak
fi
echo "CONFIG_BDRV_RW_WHITELIST=$block_drv_rw_whitelist" >> $config_host_mak
echo "CONFIG_BDRV_RO_WHITELIST=$block_drv_ro_whitelist" >> $config_host_mak
if test "$xfs" = "yes" ; then
  echo "CONFIG_XFS=y" >> $config_host_mak
fi
qemu_version=$(head $source_path/VERSION)
echo "PKGVERSION=$pkgversion" >>$config_host_mak
echo "SRC_PATH=$source_path" >> $config_host_mak
echo "TARGET_DIRS=$target_list" >> $config_host_mak
if test "$modules" = "yes"; then
  # $shacmd can generate a hash started with digit, which the compiler doesn't
  # like as an symbol. So prefix it with an underscore
  echo "CONFIG_STAMP=_$( (echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ )" >> $config_host_mak
  echo "CONFIG_MODULES=y" >> $config_host_mak
fi
if test "$module_upgrades" = "yes"; then
  echo "CONFIG_MODULE_UPGRADES=y" >> $config_host_mak
fi
if test "$have_x11" = "yes" && test "$need_x11" = "yes"; then
  echo "CONFIG_X11=y" >> $config_host_mak
  echo "X11_CFLAGS=$x11_cflags" >> $config_host_mak
  echo "X11_LIBS=$x11_libs" >> $config_host_mak
fi
if test "$pipe2" = "yes" ; then
  echo "CONFIG_PIPE2=y" >> $config_host_mak
fi
if test "$accept4" = "yes" ; then
  echo "CONFIG_ACCEPT4=y" >> $config_host_mak
fi
if test "$splice" = "yes" ; then
  echo "CONFIG_SPLICE=y" >> $config_host_mak
fi
if test "$eventfd" = "yes" ; then
  echo "CONFIG_EVENTFD=y" >> $config_host_mak
fi
if test "$memfd" = "yes" ; then
  echo "CONFIG_MEMFD=y" >> $config_host_mak
fi
if test "$have_usbfs" = "yes" ; then
  echo "CONFIG_USBFS=y" >> $config_host_mak
fi
if test "$fallocate" = "yes" ; then
  echo "CONFIG_FALLOCATE=y" >> $config_host_mak
fi
if test "$fallocate_punch_hole" = "yes" ; then
  echo "CONFIG_FALLOCATE_PUNCH_HOLE=y" >> $config_host_mak
fi
if test "$fallocate_zero_range" = "yes" ; then
  echo "CONFIG_FALLOCATE_ZERO_RANGE=y" >> $config_host_mak
fi
if test "$posix_fallocate" = "yes" ; then
  echo "CONFIG_POSIX_FALLOCATE=y" >> $config_host_mak
fi
if test "$sync_file_range" = "yes" ; then
  echo "CONFIG_SYNC_FILE_RANGE=y" >> $config_host_mak
fi
if test "$fiemap" = "yes" ; then
  echo "CONFIG_FIEMAP=y" >> $config_host_mak
fi
if test "$dup3" = "yes" ; then
  echo "CONFIG_DUP3=y" >> $config_host_mak
fi
if test "$ppoll" = "yes" ; then
  echo "CONFIG_PPOLL=y" >> $config_host_mak
fi
if test "$prctl_pr_set_timerslack" = "yes" ; then
  echo "CONFIG_PRCTL_PR_SET_TIMERSLACK=y" >> $config_host_mak
fi
if test "$epoll" = "yes" ; then
  echo "CONFIG_EPOLL=y" >> $config_host_mak
fi
if test "$epoll_create1" = "yes" ; then
  echo "CONFIG_EPOLL_CREATE1=y" >> $config_host_mak
fi
if test "$sendfile" = "yes" ; then
  echo "CONFIG_SENDFILE=y" >> $config_host_mak
fi
if test "$timerfd" = "yes" ; then
  echo "CONFIG_TIMERFD=y" >> $config_host_mak
fi
if test "$setns" = "yes" ; then
  echo "CONFIG_SETNS=y" >> $config_host_mak
fi
if test "$clock_adjtime" = "yes" ; then
  echo "CONFIG_CLOCK_ADJTIME=y" >> $config_host_mak
fi
if test "$syncfs" = "yes" ; then
  echo "CONFIG_SYNCFS=y" >> $config_host_mak
fi
if test "$inotify" = "yes" ; then
  echo "CONFIG_INOTIFY=y" >> $config_host_mak
fi
if test "$inotify1" = "yes" ; then
  echo "CONFIG_INOTIFY1=y" >> $config_host_mak
fi
if test "$sem_timedwait" = "yes" ; then
  echo "CONFIG_SEM_TIMEDWAIT=y" >> $config_host_mak
fi
if test "$strchrnul" = "yes" ; then
  echo "HAVE_STRCHRNUL=y" >> $config_host_mak
fi
if test "$st_atim" = "yes" ; then
  echo "HAVE_STRUCT_STAT_ST_ATIM=y" >> $config_host_mak
fi
if test "$byteswap_h" = "yes" ; then
  echo "CONFIG_BYTESWAP_H=y" >> $config_host_mak
fi
if test "$bswap_h" = "yes" ; then
  echo "CONFIG_MACHINE_BSWAP_H=y" >> $config_host_mak
fi
if test "$curl" = "yes" ; then
  echo "CONFIG_CURL=y" >> $config_host_mak
  echo "CURL_CFLAGS=$curl_cflags" >> $config_host_mak
  echo "CURL_LIBS=$curl_libs" >> $config_host_mak
fi
if test "$brlapi" = "yes" ; then
  echo "CONFIG_BRLAPI=y" >> $config_host_mak
  echo "BRLAPI_LIBS=$brlapi_libs" >> $config_host_mak
fi
if test "$gtk" = "yes" ; then
  echo "CONFIG_GTK=y" >> $config_host_mak
  echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak
  echo "GTK_LIBS=$gtk_libs" >> $config_host_mak
  if test "$gtk_gl" = "yes" ; then
    echo "CONFIG_GTK_GL=y" >> $config_host_mak
  fi
fi
if test "$gio" = "yes" ; then
    echo "CONFIG_GIO=y" >> $config_host_mak
    echo "GIO_CFLAGS=$gio_cflags" >> $config_host_mak
    echo "GIO_LIBS=$gio_libs" >> $config_host_mak
    echo "GDBUS_CODEGEN=$gdbus_codegen" >> $config_host_mak
fi
echo "CONFIG_TLS_PRIORITY=\"$tls_priority\"" >> $config_host_mak
if test "$gnutls" = "yes" ; then
  echo "CONFIG_GNUTLS=y" >> $config_host_mak
  echo "GNUTLS_CFLAGS=$gnutls_cflags" >> $config_host_mak
  echo "GNUTLS_LIBS=$gnutls_libs" >> $config_host_mak
fi
if test "$gcrypt" = "yes" ; then
  echo "CONFIG_GCRYPT=y" >> $config_host_mak
  if test "$gcrypt_hmac" = "yes" ; then
    echo "CONFIG_GCRYPT_HMAC=y" >> $config_host_mak
  fi
  echo "GCRYPT_CFLAGS=$gcrypt_cflags" >> $config_host_mak
  echo "GCRYPT_LIBS=$gcrypt_libs" >> $config_host_mak
fi
if test "$nettle" = "yes" ; then
  echo "CONFIG_NETTLE=y" >> $config_host_mak
  echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
  echo "NETTLE_CFLAGS=$nettle_cflags" >> $config_host_mak
  echo "NETTLE_LIBS=$nettle_libs" >> $config_host_mak
fi
if test "$qemu_private_xts" = "yes" ; then
  echo "CONFIG_QEMU_PRIVATE_XTS=y" >> $config_host_mak
fi
if test "$tasn1" = "yes" ; then
  echo "CONFIG_TASN1=y" >> $config_host_mak
fi
if test "$auth_pam" = "yes" ; then
    echo "CONFIG_AUTH_PAM=y" >> $config_host_mak
fi
if test "$have_broken_size_max" = "yes" ; then
    echo "HAVE_BROKEN_SIZE_MAX=y" >> $config_host_mak
fi
if test "$have_openpty" = "yes" ; then
    echo "HAVE_OPENPTY=y" >> $config_host_mak
fi

# Work around a system header bug with some kernel/XFS header
# versions where they both try to define 'struct fsxattr':
# xfs headers will not try to redefine structs from linux headers
# if this macro is set.
if test "$have_fsxattr" = "yes" ; then
    echo "HAVE_FSXATTR=y" >> $config_host_mak
fi
if test "$have_copy_file_range" = "yes" ; then
    echo "HAVE_COPY_FILE_RANGE=y" >> $config_host_mak
fi
if test "$vte" = "yes" ; then
  echo "CONFIG_VTE=y" >> $config_host_mak
  echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak
  echo "VTE_LIBS=$vte_libs" >> $config_host_mak
fi
if test "$virglrenderer" = "yes" ; then
  echo "CONFIG_VIRGL=y" >> $config_host_mak
  echo "VIRGL_CFLAGS=$virgl_cflags" >> $config_host_mak
  echo "VIRGL_LIBS=$virgl_libs" >> $config_host_mak
fi
if test "$xen" = "enabled" ; then
  echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
  echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
  echo "XEN_CFLAGS=$xen_cflags" >> $config_host_mak
  echo "XEN_LIBS=$xen_libs" >> $config_host_mak
fi
if test "$linux_aio" = "yes" ; then
  echo "CONFIG_LINUX_AIO=y" >> $config_host_mak
fi
if test "$linux_io_uring" = "yes" ; then
  echo "CONFIG_LINUX_IO_URING=y" >> $config_host_mak
  echo "LINUX_IO_URING_CFLAGS=$linux_io_uring_cflags" >> $config_host_mak
  echo "LINUX_IO_URING_LIBS=$linux_io_uring_libs" >> $config_host_mak
fi
if test "$attr" = "yes" ; then
  echo "CONFIG_ATTR=y" >> $config_host_mak
  echo "LIBATTR_LIBS=$libattr_libs" >> $config_host_mak
fi
if test "$libattr" = "yes" ; then
  echo "CONFIG_LIBATTR=y" >> $config_host_mak
fi
if test "$virtfs" = "yes" ; then
  echo "CONFIG_VIRTFS=y" >> $config_host_mak
fi
if test "$vhost_scsi" = "yes" ; then
  echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak
fi
if test "$vhost_net" = "yes" ; then
  echo "CONFIG_VHOST_NET=y" >> $config_host_mak
fi
if test "$vhost_net_user" = "yes" ; then
  echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
fi
if test "$vhost_net_vdpa" = "yes" ; then
  echo "CONFIG_VHOST_NET_VDPA=y" >> $config_host_mak
fi
if test "$vhost_crypto" = "yes" ; then
  echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
fi
if test "$vhost_vsock" = "yes" ; then
  echo "CONFIG_VHOST_VSOCK=y" >> $config_host_mak
  if test "$vhost_user" = "yes" ; then
    echo "CONFIG_VHOST_USER_VSOCK=y" >> $config_host_mak
  fi
fi
if test "$vhost_kernel" = "yes" ; then
  echo "CONFIG_VHOST_KERNEL=y" >> $config_host_mak
fi
if test "$vhost_user" = "yes" ; then
  echo "CONFIG_VHOST_USER=y" >> $config_host_mak
fi
if test "$vhost_vdpa" = "yes" ; then
  echo "CONFIG_VHOST_VDPA=y" >> $config_host_mak
fi
if test "$vhost_user_fs" = "yes" ; then
  echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
fi
if test "$iovec" = "yes" ; then
  echo "CONFIG_IOVEC=y" >> $config_host_mak
fi
if test "$preadv" = "yes" ; then
  echo "CONFIG_PREADV=y" >> $config_host_mak
fi
if test "$membarrier" = "yes" ; then
  echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
fi
if test "$signalfd" = "yes" ; then
  echo "CONFIG_SIGNALFD=y" >> $config_host_mak
fi
if test "$optreset" = "yes" ; then
  echo "HAVE_OPTRESET=y" >> $config_host_mak
fi
if test "$tcg" = "enabled"; then
  if test "$tcg_interpreter" = "yes" ; then
    echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak
  fi
fi
if test "$fdatasync" = "yes" ; then
  echo "CONFIG_FDATASYNC=y" >> $config_host_mak
fi
if test "$madvise" = "yes" ; then
  echo "CONFIG_MADVISE=y" >> $config_host_mak
fi
if test "$posix_madvise" = "yes" ; then
  echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak
fi
if test "$posix_memalign" = "yes" ; then
  echo "CONFIG_POSIX_MEMALIGN=y" >> $config_host_mak
fi
if test "$spice" = "yes" ; then
  echo "CONFIG_SPICE=y" >> $config_host_mak
  echo "SPICE_CFLAGS=$spice_cflags" >> $config_host_mak
  echo "SPICE_LIBS=$spice_libs" >> $config_host_mak
fi

if test "$smartcard" = "yes" ; then
  echo "CONFIG_SMARTCARD=y" >> $config_host_mak
  echo "SMARTCARD_CFLAGS=$libcacard_cflags" >> $config_host_mak
  echo "SMARTCARD_LIBS=$libcacard_libs" >> $config_host_mak
fi

if test "$libusb" = "yes" ; then
  echo "CONFIG_USB_LIBUSB=y" >> $config_host_mak
  echo "LIBUSB_CFLAGS=$libusb_cflags" >> $config_host_mak
  echo "LIBUSB_LIBS=$libusb_libs" >> $config_host_mak
fi

if test "$usb_redir" = "yes" ; then
  echo "CONFIG_USB_REDIR=y" >> $config_host_mak
  echo "USB_REDIR_CFLAGS=$usb_redir_cflags" >> $config_host_mak
  echo "USB_REDIR_LIBS=$usb_redir_libs" >> $config_host_mak
fi

if test "$opengl" = "yes" ; then
  echo "CONFIG_OPENGL=y" >> $config_host_mak
  echo "OPENGL_CFLAGS=$opengl_cflags" >> $config_host_mak
  echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak
  if test "$opengl_dmabuf" = "yes" ; then
    echo "CONFIG_OPENGL_DMABUF=y" >> $config_host_mak
  fi
fi

if test "$gbm" = "yes" ; then
    echo "CONFIG_GBM=y" >> $config_host_mak
    echo "GBM_LIBS=$gbm_libs" >> $config_host_mak
    echo "GBM_CFLAGS=$gbm_cflags" >> $config_host_mak
fi


if test "$avx2_opt" = "yes" ; then
  echo "CONFIG_AVX2_OPT=y" >> $config_host_mak
fi

if test "$avx512f_opt" = "yes" ; then
  echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak
fi

if test "$lzo" = "yes" ; then
  echo "CONFIG_LZO=y" >> $config_host_mak
  echo "LZO_LIBS=$lzo_libs" >> $config_host_mak
fi

if test "$snappy" = "yes" ; then
  echo "CONFIG_SNAPPY=y" >> $config_host_mak
  echo "SNAPPY_LIBS=$snappy_libs" >> $config_host_mak
fi

if test "$bzip2" = "yes" ; then
  echo "CONFIG_BZIP2=y" >> $config_host_mak
  echo "BZIP2_LIBS=-lbz2" >> $config_host_mak
fi

if test "$lzfse" = "yes" ; then
  echo "CONFIG_LZFSE=y" >> $config_host_mak
  echo "LZFSE_LIBS=-llzfse" >> $config_host_mak
fi

if test "$zstd" = "yes" ; then
  echo "CONFIG_ZSTD=y" >> $config_host_mak
  echo "ZSTD_CFLAGS=$zstd_cflags" >> $config_host_mak
  echo "ZSTD_LIBS=$zstd_libs" >> $config_host_mak
fi

if test "$libiscsi" = "yes" ; then
  echo "CONFIG_LIBISCSI=y" >> $config_host_mak
  echo "LIBISCSI_CFLAGS=$libiscsi_cflags" >> $config_host_mak
  echo "LIBISCSI_LIBS=$libiscsi_libs" >> $config_host_mak
fi

if test "$libnfs" = "yes" ; then
  echo "CONFIG_LIBNFS=y" >> $config_host_mak
  echo "LIBNFS_LIBS=$libnfs_libs" >> $config_host_mak
fi

if test "$seccomp" = "yes"; then
  echo "CONFIG_SECCOMP=y" >> $config_host_mak
  echo "SECCOMP_CFLAGS=$seccomp_cflags" >> $config_host_mak
  echo "SECCOMP_LIBS=$seccomp_libs" >> $config_host_mak
fi

# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
  echo "CONFIG_BSD=y" >> $config_host_mak
fi

if test "$qom_cast_debug" = "yes" ; then
  echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
fi
if test "$rbd" = "yes" ; then
  echo "CONFIG_RBD=y" >> $config_host_mak
  echo "RBD_LIBS=$rbd_libs" >> $config_host_mak
fi

echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
if test "$coroutine_pool" = "yes" ; then
  echo "CONFIG_COROUTINE_POOL=1" >> $config_host_mak
else
  echo "CONFIG_COROUTINE_POOL=0" >> $config_host_mak
fi

if test "$debug_stack_usage" = "yes" ; then
  echo "CONFIG_DEBUG_STACK_USAGE=y" >> $config_host_mak
fi

if test "$crypto_afalg" = "yes" ; then
  echo "CONFIG_AF_ALG=y" >> $config_host_mak
fi

if test "$open_by_handle_at" = "yes" ; then
  echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak
fi

if test "$linux_magic_h" = "yes" ; then
  echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak
fi

if test "$valgrind_h" = "yes" ; then
  echo "CONFIG_VALGRIND_H=y" >> $config_host_mak
fi

if test "$have_asan_iface_fiber" = "yes" ; then
    echo "CONFIG_ASAN_IFACE_FIBER=y" >> $config_host_mak
fi

if test "$have_tsan" = "yes" && test "$have_tsan_iface_fiber" = "yes" ; then
    echo "CONFIG_TSAN=y" >> $config_host_mak
fi

if test "$has_environ" = "yes" ; then
  echo "CONFIG_HAS_ENVIRON=y" >> $config_host_mak
fi

if test "$cpuid_h" = "yes" ; then
  echo "CONFIG_CPUID_H=y" >> $config_host_mak
fi

if test "$int128" = "yes" ; then
  echo "CONFIG_INT128=y" >> $config_host_mak
fi

if test "$atomic128" = "yes" ; then
  echo "CONFIG_ATOMIC128=y" >> $config_host_mak
fi

if test "$cmpxchg128" = "yes" ; then
  echo "CONFIG_CMPXCHG128=y" >> $config_host_mak
fi

if test "$atomic64" = "yes" ; then
  echo "CONFIG_ATOMIC64=y" >> $config_host_mak
fi

if test "$attralias" = "yes" ; then
  echo "CONFIG_ATTRIBUTE_ALIAS=y" >> $config_host_mak
fi

if test "$getauxval" = "yes" ; then
  echo "CONFIG_GETAUXVAL=y" >> $config_host_mak
fi

if test "$glusterfs" = "yes" ; then
  echo "CONFIG_GLUSTERFS=y" >> $config_host_mak
  echo "GLUSTERFS_CFLAGS=$glusterfs_cflags" >> $config_host_mak
  echo "GLUSTERFS_LIBS=$glusterfs_libs" >> $config_host_mak
fi

if test "$glusterfs_xlator_opt" = "yes" ; then
  echo "CONFIG_GLUSTERFS_XLATOR_OPT=y" >> $config_host_mak
fi

if test "$glusterfs_discard" = "yes" ; then
  echo "CONFIG_GLUSTERFS_DISCARD=y" >> $config_host_mak
fi

if test "$glusterfs_fallocate" = "yes" ; then
  echo "CONFIG_GLUSTERFS_FALLOCATE=y" >> $config_host_mak
fi

if test "$glusterfs_zerofill" = "yes" ; then
  echo "CONFIG_GLUSTERFS_ZEROFILL=y" >> $config_host_mak
fi

if test "$glusterfs_ftruncate_has_stat" = "yes" ; then
  echo "CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT=y" >> $config_host_mak
fi

if test "$glusterfs_iocb_has_stat" = "yes" ; then
  echo "CONFIG_GLUSTERFS_IOCB_HAS_STAT=y" >> $config_host_mak
fi

if test "$libssh" = "yes" ; then
  echo "CONFIG_LIBSSH=y" >> $config_host_mak
  echo "LIBSSH_CFLAGS=$libssh_cflags" >> $config_host_mak
  echo "LIBSSH_LIBS=$libssh_libs" >> $config_host_mak
fi

if test "$live_block_migration" = "yes" ; then
  echo "CONFIG_LIVE_BLOCK_MIGRATION=y" >> $config_host_mak
fi

if test "$tpm" = "yes"; then
  echo 'CONFIG_TPM=y' >> $config_host_mak
fi

echo "TRACE_BACKENDS=$trace_backends" >> $config_host_mak
if have_backend "nop"; then
  echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
fi
if have_backend "simple"; then
  echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
  # Set the appropriate trace file.
  trace_file="\"$trace_file-\" FMT_pid"
fi
if have_backend "log"; then
  echo "CONFIG_TRACE_LOG=y" >> $config_host_mak
fi
if have_backend "ust"; then
  echo "CONFIG_TRACE_UST=y" >> $config_host_mak
  echo "LTTNG_UST_LIBS=$lttng_ust_libs" >> $config_host_mak
  echo "URCU_BP_LIBS=$urcu_bp_libs" >> $config_host_mak
fi
if have_backend "dtrace"; then
  echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak
  if test "$trace_backend_stap" = "yes" ; then
    echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
  fi
fi
if have_backend "ftrace"; then
  if test "$linux" = "yes" ; then
    echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak
  else
    feature_not_found "ftrace(trace backend)" "ftrace requires Linux"
  fi
fi
if have_backend "syslog"; then
  if test "$posix_syslog" = "yes" ; then
    echo "CONFIG_TRACE_SYSLOG=y" >> $config_host_mak
  else
    feature_not_found "syslog(trace backend)" "syslog not available"
  fi
fi
echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak

if test "$rdma" = "yes" ; then
  echo "CONFIG_RDMA=y" >> $config_host_mak
  echo "RDMA_LIBS=$rdma_libs" >> $config_host_mak
fi

if test "$pvrdma" = "yes" ; then
  echo "CONFIG_PVRDMA=y" >> $config_host_mak
fi

if test "$have_rtnetlink" = "yes" ; then
  echo "CONFIG_RTNETLINK=y" >> $config_host_mak
fi

if test "$libxml2" = "yes" ; then
  echo "CONFIG_LIBXML2=y" >> $config_host_mak
  echo "LIBXML2_CFLAGS=$libxml2_cflags" >> $config_host_mak
  echo "LIBXML2_LIBS=$libxml2_libs" >> $config_host_mak
fi

if test "$replication" = "yes" ; then
  echo "CONFIG_REPLICATION=y" >> $config_host_mak
fi

if test "$have_af_vsock" = "yes" ; then
  echo "CONFIG_AF_VSOCK=y" >> $config_host_mak
fi

if test "$have_sysmacros" = "yes" ; then
  echo "CONFIG_SYSMACROS=y" >> $config_host_mak
fi

if test "$have_static_assert" = "yes" ; then
  echo "CONFIG_STATIC_ASSERT=y" >> $config_host_mak
fi

if test "$have_utmpx" = "yes" ; then
  echo "HAVE_UTMPX=y" >> $config_host_mak
fi
if test "$have_getrandom" = "yes" ; then
  echo "CONFIG_GETRANDOM=y" >> $config_host_mak
fi
if test "$ivshmem" = "yes" ; then
  echo "CONFIG_IVSHMEM=y" >> $config_host_mak
fi
if test "$debug_mutex" = "yes" ; then
  echo "CONFIG_DEBUG_MUTEX=y" >> $config_host_mak
fi

# Hold two types of flag:
#   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
#                                     a thread we have a handle to
#   CONFIG_PTHREAD_SETNAME_NP_W_TID - A way of doing it on a particular
#                                     platform
if test "$pthread_setname_np_w_tid" = "yes" ; then
  echo "CONFIG_THREAD_SETNAME_BYTHREAD=y" >> $config_host_mak
  echo "CONFIG_PTHREAD_SETNAME_NP_W_TID=y" >> $config_host_mak
elif test "$pthread_setname_np_wo_tid" = "yes" ; then
  echo "CONFIG_THREAD_SETNAME_BYTHREAD=y" >> $config_host_mak
  echo "CONFIG_PTHREAD_SETNAME_NP_WO_TID=y" >> $config_host_mak
fi

if test "$libpmem" = "yes" ; then
  echo "CONFIG_LIBPMEM=y" >> $config_host_mak
  echo "LIBPMEM_LIBS=$libpmem_libs" >> $config_host_mak
  echo "LIBPMEM_CFLAGS=$libpmem_cflags" >> $config_host_mak
fi

if test "$libdaxctl" = "yes" ; then
  echo "CONFIG_LIBDAXCTL=y" >> $config_host_mak
  echo "LIBDAXCTL_LIBS=$libdaxctl_libs" >> $config_host_mak
fi

if test "$bochs" = "yes" ; then
  echo "CONFIG_BOCHS=y" >> $config_host_mak
fi
if test "$cloop" = "yes" ; then
  echo "CONFIG_CLOOP=y" >> $config_host_mak
fi
if test "$dmg" = "yes" ; then
  echo "CONFIG_DMG=y" >> $config_host_mak
fi
if test "$qcow1" = "yes" ; then
  echo "CONFIG_QCOW1=y" >> $config_host_mak
fi
if test "$vdi" = "yes" ; then
  echo "CONFIG_VDI=y" >> $config_host_mak
fi
if test "$vvfat" = "yes" ; then
  echo "CONFIG_VVFAT=y" >> $config_host_mak
fi
if test "$qed" = "yes" ; then
  echo "CONFIG_QED=y" >> $config_host_mak
fi
if test "$parallels" = "yes" ; then
  echo "CONFIG_PARALLELS=y" >> $config_host_mak
fi
if test "$sheepdog" = "yes" ; then
  add_to deprecated_features "sheepdog"
  echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
fi
if test "$have_mlockall" = "yes" ; then
  echo "HAVE_MLOCKALL=y" >> $config_host_mak
fi
if test "$fuzzing" = "yes" ; then
  # If LIB_FUZZING_ENGINE is set, assume we are running on OSS-Fuzz, and the
  # needed CFLAGS have already been provided
  if test -z "${LIB_FUZZING_ENGINE+xxx}" ; then
    QEMU_CFLAGS="$QEMU_CFLAGS -fsanitize=fuzzer-no-link"
    FUZZ_EXE_LDFLAGS="-fsanitize=fuzzer"
  else
    FUZZ_EXE_LDFLAGS="$LIB_FUZZING_ENGINE"
  fi
fi

if test "$plugins" = "yes" ; then
    echo "CONFIG_PLUGIN=y" >> $config_host_mak
    # Copy the export object list to the build dir
    if test "$ld_dynamic_list" = "yes" ; then
	echo "CONFIG_HAS_LD_DYNAMIC_LIST=yes" >> $config_host_mak
	ld_symbols=qemu-plugins-ld.symbols
	cp "$source_path/plugins/qemu-plugins.symbols" $ld_symbols
    elif test "$ld_exported_symbols_list" = "yes" ; then
	echo "CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST=yes" >> $config_host_mak
	ld64_symbols=qemu-plugins-ld64.symbols
	echo "# Automatically generated by configure - do not modify" > $ld64_symbols
	grep 'qemu_' "$source_path/plugins/qemu-plugins.symbols" | sed 's/;//g' | \
	    sed -E 's/^[[:space:]]*(.*)/_\1/' >> $ld64_symbols
    else
	error_exit \
	    "If \$plugins=yes, either \$ld_dynamic_list or " \
	    "\$ld_exported_symbols_list should have been set to 'yes'."
    fi
fi

if test -n "$gdb_bin" ; then
    echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
fi

if test "$secret_keyring" = "yes" ; then
  echo "CONFIG_SECRET_KEYRING=y" >> $config_host_mak
fi

echo "ROMS=$roms" >> $config_host_mak
echo "MAKE=$make" >> $config_host_mak
echo "PYTHON=$python" >> $config_host_mak
echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
echo "MESON=$meson" >> $config_host_mak
echo "NINJA=$ninja" >> $config_host_mak
echo "CC=$cc" >> $config_host_mak
if $iasl -h > /dev/null 2>&1; then
  echo "CONFIG_IASL=$iasl" >> $config_host_mak
fi
echo "CXX=$cxx" >> $config_host_mak
echo "OBJCC=$objcc" >> $config_host_mak
echo "AR=$ar" >> $config_host_mak
echo "ARFLAGS=$ARFLAGS" >> $config_host_mak
echo "AS=$as" >> $config_host_mak
echo "CCAS=$ccas" >> $config_host_mak
echo "CPP=$cpp" >> $config_host_mak
echo "OBJCOPY=$objcopy" >> $config_host_mak
echo "LD=$ld" >> $config_host_mak
echo "RANLIB=$ranlib" >> $config_host_mak
echo "NM=$nm" >> $config_host_mak
echo "PKG_CONFIG=$pkg_config_exe" >> $config_host_mak
echo "WINDRES=$windres" >> $config_host_mak
echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
echo "EXESUF=$EXESUF" >> $config_host_mak
echo "HOST_DSOSUF=$HOST_DSOSUF" >> $config_host_mak
echo "LIBS_QGA=$libs_qga" >> $config_host_mak
echo "TASN1_LIBS=$tasn1_libs" >> $config_host_mak
echo "TASN1_CFLAGS=$tasn1_cflags" >> $config_host_mak
if test "$gcov" = "yes" ; then
  echo "CONFIG_GCOV=y" >> $config_host_mak
fi

if test "$fuzzing" != "no"; then
    echo "CONFIG_FUZZ=y" >> $config_host_mak
fi
echo "FUZZ_EXE_LDFLAGS=$FUZZ_EXE_LDFLAGS" >> $config_host_mak

if test "$rng_none" = "yes"; then
  echo "CONFIG_RNG_NONE=y" >> $config_host_mak
fi

# use included Linux headers
if test "$linux" = "yes" ; then
  mkdir -p linux-headers
  case "$cpu" in
  i386|x86_64|x32)
    linux_arch=x86
    ;;
  ppc|ppc64|ppc64le)
    linux_arch=powerpc
    ;;
  s390x)
    linux_arch=s390
    ;;
  aarch64)
    linux_arch=arm64
    ;;
  mips64)
    linux_arch=mips
    ;;
  *)
    # For most CPUs the kernel architecture name and QEMU CPU name match.
    linux_arch="$cpu"
    ;;
  esac
    # For non-KVM architectures we will not have asm headers
    if [ -e "$source_path/linux-headers/asm-$linux_arch" ]; then
      symlink "$source_path/linux-headers/asm-$linux_arch" linux-headers/asm
    fi
fi

for target in $target_list; do
    target_dir="$target"
    target_name=$(echo $target | cut -d '-' -f 1)
    mkdir -p $target_dir
    case $target in
        *-user) symlink "../qemu-$target_name" "$target_dir/qemu-$target_name" ;;
        *) symlink "../qemu-system-$target_name" "$target_dir/qemu-system-$target_name" ;;
    esac
done

echo "CONFIG_QEMU_INTERP_PREFIX=$interp_prefix" | sed 's/%M/@0@/' >> $config_host_mak
if test "$default_targets" = "yes"; then
  echo "CONFIG_DEFAULT_TARGETS=y" >> $config_host_mak
fi

if test "$numa" = "yes"; then
  echo "CONFIG_NUMA=y" >> $config_host_mak
  echo "NUMA_LIBS=$numa_libs" >> $config_host_mak
fi

if test "$ccache_cpp2" = "yes"; then
  echo "export CCACHE_CPP2=y" >> $config_host_mak
fi

if test "$safe_stack" = "yes"; then
  echo "CONFIG_SAFESTACK=y" >> $config_host_mak
fi

# If we're using a separate build tree, set it up now.
# DIRS are directories which we simply mkdir in the build tree;
# LINKS are things to symlink back into the source tree
# (these can be both files and directories).
# Caution: do not add files or directories here using wildcards. This
# will result in problems later if a new file matching the wildcard is
# added to the source tree -- nothing will cause configure to be rerun
# so the build tree will be missing the link back to the new file, and
# tests might fail. Prefer to keep the relevant files in their own
# directory and symlink the directory instead.
# UNLINK is used to remove symlinks from older development versions
# that might get into the way when doing "git update" without doing
# a "make distclean" in between.
DIRS="tests tests/tcg tests/tcg/lm32 tests/qapi-schema tests/qtest/libqos"
DIRS="$DIRS tests/qtest tests/qemu-iotests tests/vm tests/fp tests/qgraph"
DIRS="$DIRS docs docs/interop fsdev scsi"
DIRS="$DIRS pc-bios/optionrom pc-bios/s390-ccw"
DIRS="$DIRS roms/seabios"
DIRS="$DIRS contrib/plugins/"
LINKS="Makefile"
LINKS="$LINKS tests/tcg/lm32/Makefile"
LINKS="$LINKS tests/tcg/Makefile.target"
LINKS="$LINKS pc-bios/optionrom/Makefile"
LINKS="$LINKS pc-bios/s390-ccw/Makefile"
LINKS="$LINKS roms/seabios/Makefile"
LINKS="$LINKS pc-bios/qemu-icon.bmp"
LINKS="$LINKS .gdbinit scripts" # scripts needed by relative path in .gdbinit
LINKS="$LINKS tests/acceptance tests/data"
LINKS="$LINKS tests/qemu-iotests/check"
LINKS="$LINKS python"
LINKS="$LINKS contrib/plugins/Makefile "
UNLINK="pc-bios/keymaps"
for bios_file in \
    $source_path/pc-bios/*.bin \
    $source_path/pc-bios/*.elf \
    $source_path/pc-bios/*.lid \
    $source_path/pc-bios/*.rom \
    $source_path/pc-bios/*.dtb \
    $source_path/pc-bios/*.img \
    $source_path/pc-bios/openbios-* \
    $source_path/pc-bios/u-boot.* \
    $source_path/pc-bios/edk2-*.fd.bz2 \
    $source_path/pc-bios/palcode-*
do
    LINKS="$LINKS pc-bios/$(basename $bios_file)"
done
mkdir -p $DIRS
for f in $LINKS ; do
    if [ -e "$source_path/$f" ]; then
        symlink "$source_path/$f" "$f"
    fi
done
for f in $UNLINK ; do
    if [ -L "$f" ]; then
        rm -f "$f"
    fi
done

(for i in $cross_cc_vars; do
  export $i
done
export target_list source_path use_containers
$source_path/tests/tcg/configure.sh)

# temporary config to build submodules
for rom in seabios; do
    config_mak=roms/$rom/config.mak
    echo "# Automatically generated by configure - do not modify" > $config_mak
    echo "SRC_PATH=$source_path/roms/$rom" >> $config_mak
    echo "AS=$as" >> $config_mak
    echo "CCAS=$ccas" >> $config_mak
    echo "CC=$cc" >> $config_mak
    echo "BCC=bcc" >> $config_mak
    echo "CPP=$cpp" >> $config_mak
    echo "OBJCOPY=objcopy" >> $config_mak
    echo "IASL=$iasl" >> $config_mak
    echo "LD=$ld" >> $config_mak
    echo "RANLIB=$ranlib" >> $config_mak
done

# set up qemu-iotests in this build directory
iotests_common_env="tests/qemu-iotests/common.env"

echo "# Automatically generated by configure - do not modify" > "$iotests_common_env"
echo >> "$iotests_common_env"
echo "export PYTHON='$python'" >> "$iotests_common_env"

if test "$skip_meson" = no; then
cross="config-meson.cross.new"
meson_quote() {
    echo "'$(echo $* | sed "s/ /','/g")'"
}

echo "# Automatically generated by configure - do not modify" > $cross
echo "[properties]" >> $cross
test -z "$cxx" && echo "link_language = 'c'" >> $cross
echo "[built-in options]" >> $cross
echo "c_args = [${CFLAGS:+$(meson_quote $CFLAGS)}]" >> $cross
echo "cpp_args = [${CXXFLAGS:+$(meson_quote $CXXFLAGS)}]" >> $cross
echo "c_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
echo "[binaries]" >> $cross
echo "c = [$(meson_quote $cc)]" >> $cross
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
echo "ar = [$(meson_quote $ar)]" >> $cross
echo "nm = [$(meson_quote $nm)]" >> $cross
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
echo "ranlib = [$(meson_quote $ranlib)]" >> $cross
if has $sdl2_config; then
  echo "sdl2-config = [$(meson_quote $sdl2_config)]" >> $cross
fi
echo "strip = [$(meson_quote $strip)]" >> $cross
echo "windres = [$(meson_quote $windres)]" >> $cross
if test -n "$cross_prefix"; then
    cross_arg="--cross-file config-meson.cross"
    echo "[host_machine]" >> $cross
    if test "$mingw32" = "yes" ; then
        echo "system = 'windows'" >> $cross
    fi
    if test "$linux" = "yes" ; then
        echo "system = 'linux'" >> $cross
    fi
    case "$ARCH" in
        i386|x86_64)
            echo "cpu_family = 'x86'" >> $cross
            ;;
        ppc64le)
            echo "cpu_family = 'ppc64'" >> $cross
            ;;
        *)
            echo "cpu_family = '$ARCH'" >> $cross
            ;;
    esac
    echo "cpu = '$cpu'" >> $cross
    if test "$bigendian" = "yes" ; then
        echo "endian = 'big'" >> $cross
    else
        echo "endian = 'little'" >> $cross
    fi
else
    cross_arg="--native-file config-meson.cross"
fi
mv $cross config-meson.cross

rm -rf meson-private meson-info meson-logs
unset staticpic
if ! version_ge "$($meson --version)" 0.56.0; then
  staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi)
fi
NINJA=$ninja $meson setup \
        --prefix "$prefix" \
        --libdir "$libdir" \
        --libexecdir "$libexecdir" \
        --bindir "$bindir" \
        --includedir "$includedir" \
        --datadir "$datadir" \
        --mandir "$mandir" \
        --sysconfdir "$sysconfdir" \
        --localedir "$localedir" \
        --localstatedir "$local_statedir" \
        -Ddocdir="$docdir" \
        -Dqemu_firmwarepath="$firmwarepath" \
        -Dqemu_suffix="$qemu_suffix" \
        -Doptimization=$(if test "$debug" = yes; then echo 0; else echo 2; fi) \
        -Ddebug=$(if test "$debug_info" = yes; then echo true; else echo false; fi) \
        -Dwerror=$(if test "$werror" = yes; then echo true; else echo false; fi) \
        -Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \
        -Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \
        ${staticpic:+-Db_staticpic=$staticpic} \
        -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \
        -Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \
        -Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \
        -Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \
        -Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
        -Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \
        -Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f -Dvirtiofsd=$virtiofsd \
        -Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt \
        -Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\
        -Ddocs=$docs -Dsphinx_build=$sphinx_build -Dinstall_blobs=$blobs \
        -Dvhost_user_blk_server=$vhost_user_blk_server \
        -Dfuse=$fuse -Dfuse_lseek=$fuse_lseek \
        $cross_arg \
        "$PWD" "$source_path"

if test "$?" -ne 0 ; then
    error_exit "meson setup failed"
fi
fi

if test -n "${deprecated_features}"; then
    echo "Warning, deprecated features enabled."
    echo "Please see docs/system/deprecated.rst"
    echo "  features: ${deprecated_features}"
fi

# Save the configure command line for later reuse.
cat <<EOD >config.status
#!/bin/sh
# Generated by configure.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
EOD

preserve_env() {
    envname=$1

    eval envval=\$$envname

    if test -n "$envval"
    then
	echo "$envname='$envval'" >> config.status
	echo "export $envname" >> config.status
    else
	echo "unset $envname" >> config.status
    fi
}

# Preserve various env variables that influence what
# features/build target configure will detect
preserve_env AR
preserve_env AS
preserve_env CC
preserve_env CPP
preserve_env CXX
preserve_env INSTALL
preserve_env LD
preserve_env LD_LIBRARY_PATH
preserve_env LIBTOOL
preserve_env MAKE
preserve_env NM
preserve_env OBJCOPY
preserve_env PATH
preserve_env PKG_CONFIG
preserve_env PKG_CONFIG_LIBDIR
preserve_env PKG_CONFIG_PATH
preserve_env PYTHON
preserve_env SDL2_CONFIG
preserve_env SMBD
preserve_env STRIP
preserve_env WINDRES

printf "exec" >>config.status
for i in "$0" "$@"; do
  test "$i" = --skip-meson || printf " '%s'" "$i" >>config.status
done
echo ' "$@"' >>config.status
chmod +x config.status

rm -r "$TMPDIR1"