e3feb2cc22
The only reason to add this implementation is to control the memory allocator used. Some users (e.g. TCG) cannot work reliably in multi-threaded environments (e.g. forking in user-mode) with GTree's allocator, GSlice. See https://gitlab.com/qemu-project/qemu/-/issues/285 for details. Importing GTree is a temporary workaround until GTree migrates away from GSlice. This implementation is identical to that in glib v2.75.0, except that we don't import recent additions to the API nor deprecated API calls, none of which are used in QEMU. I've imported tests from glib and added a benchmark just to make sure that performance is similar. Note: it cannot be identical because (1) we are not using GSlice, (2) we use different compilation flags (e.g. -fPIC) and (3) we're linking statically. $ cat /proc/cpuinfo| grep 'model name' | head -1 model name : AMD Ryzen 7 PRO 5850U with Radeon Graphics $ echo '0' | sudo tee /sys/devices/system/cpu/cpufreq/boost $ tests/bench/qtree-bench Tree Op 32 1024 4096 131072 1048576 ------------------------------------------------------------------------------------------------ GTree Lookup 83.23 43.08 25.31 19.40 16.22 QTree Lookup 113.42 (1.36x) 53.83 (1.25x) 28.38 (1.12x) 17.64 (0.91x) 13.04 (0.80x) GTree Insert 44.23 29.37 25.83 19.49 17.03 QTree Insert 46.87 (1.06x) 25.62 (0.87x) 24.29 (0.94x) 16.83 (0.86x) 12.97 (0.76x) GTree Remove 53.27 35.15 31.43 24.64 16.70 QTree Remove 57.32 (1.08x) 41.76 (1.19x) 38.37 (1.22x) 29.30 (1.19x) 15.07 (0.90x) GTree RemoveAll 135.44 127.52 126.72 120.11 64.34 QTree RemoveAll 127.15 (0.94x) 110.37 (0.87x) 107.97 (0.85x) 97.13 (0.81x) 55.10 (0.86x) GTree Traverse 277.71 276.09 272.78 246.72 98.47 QTree Traverse 370.33 (1.33x) 411.97 (1.49x) 400.23 (1.47x) 262.82 (1.07x) 78.52 (0.80x) ------------------------------------------------------------------------------------------------ As a sanity check, the same benchmark when Glib's version is >= $glib_dropped_gslice_version (i.e. QTree == GTree): Tree Op 32 1024 4096 131072 1048576 ------------------------------------------------------------------------------------------------ GTree Lookup 82.72 43.09 24.18 19.73 16.09 QTree Lookup 81.82 (0.99x) 43.10 (1.00x) 24.20 (1.00x) 19.76 (1.00x) 16.26 (1.01x) GTree Insert 45.07 29.62 26.34 19.90 17.18 QTree Insert 45.72 (1.01x) 29.60 (1.00x) 26.38 (1.00x) 19.71 (0.99x) 17.20 (1.00x) GTree Remove 54.48 35.36 31.77 24.97 16.95 QTree Remove 54.46 (1.00x) 35.32 (1.00x) 31.77 (1.00x) 24.91 (1.00x) 17.15 (1.01x) GTree RemoveAll 140.68 127.36 125.43 121.45 68.20 QTree RemoveAll 140.65 (1.00x) 127.64 (1.00x) 125.01 (1.00x) 121.73 (1.00x) 67.06 (0.98x) GTree Traverse 278.68 276.05 266.75 251.65 104.93 QTree Traverse 278.31 (1.00x) 275.78 (1.00x) 266.42 (1.00x) 247.89 (0.99x) 104.58 (1.00x) ------------------------------------------------------------------------------------------------ Signed-off-by: Emilio Cota <cota@braap.org> Message-Id: <20230205163758.416992-2-cota@braap.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2702 lines
77 KiB
Bash
Executable File
2702 lines
77 KiB
Bash
Executable File
#!/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
|
|
|
|
if ! mkdir build || ! touch $MARKER
|
|
then
|
|
echo "ERROR: Could not create ./build directory. Check the permissions on"
|
|
echo "your source directory, or try doing an out-of-tree build."
|
|
exit 1
|
|
fi
|
|
|
|
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}"
|
|
if ! mkdir -p "${TMPDIR1}"; then
|
|
echo "ERROR: failed to create temporary directory"
|
|
exit 1
|
|
fi
|
|
|
|
TMPB="qemu-conf"
|
|
TMPC="${TMPDIR1}/${TMPB}.c"
|
|
TMPO="${TMPDIR1}/${TMPB}.o"
|
|
TMPM="${TMPDIR1}/${TMPB}.m"
|
|
TMPE="${TMPDIR1}/${TMPB}.exe"
|
|
|
|
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
|
|
# repeat the invocation to log and stdout for CI
|
|
invoke=$(printf " '%s'" "$0" "$@")
|
|
test -n "$GITLAB_CI" && echo "configuring with: $invoke"
|
|
{ echo "$invoke"; echo; echo "#"; } >> config.log
|
|
|
|
quote_sh() {
|
|
printf "%s" "$1" | sed "s,','\\\\'',g; s,.*,'&',"
|
|
}
|
|
|
|
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.
|
|
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 $?
|
|
}
|
|
|
|
do_compiler_werror() {
|
|
# Run the compiler, capturing its output to the log. First argument
|
|
# is compiler binary to execute.
|
|
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_werror "$cc" $CPU_CFLAGS "$@"
|
|
}
|
|
|
|
do_objc() {
|
|
do_compiler_werror "$objcc" $CPU_CFLAGS "$@"
|
|
}
|
|
|
|
# Append $2 to the variable named $1, with space separation
|
|
add_to() {
|
|
eval $1=\${$1:+\"\$$1 \"}\$2
|
|
}
|
|
|
|
compile_object() {
|
|
local_cflags="$1"
|
|
do_cc $CFLAGS $EXTRA_CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
|
|
}
|
|
|
|
compile_prog() {
|
|
local_cflags="$1"
|
|
local_ldflags="$2"
|
|
do_cc $CFLAGS $EXTRA_CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC \
|
|
$LDFLAGS $EXTRA_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=$(expr "$1" : '\([0-9.]*\)' | 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
|
|
}
|
|
|
|
if printf %s\\n "$source_path" "$PWD" | grep -q "[[:space:]:]";
|
|
then
|
|
error_exit "main directory cannot contain spaces nor colons"
|
|
fi
|
|
|
|
# default parameters
|
|
cpu=""
|
|
static="no"
|
|
cross_compile="no"
|
|
cross_prefix=""
|
|
host_cc="cc"
|
|
stack_protector=""
|
|
safe_stack=""
|
|
use_containers="yes"
|
|
gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
|
|
gdb_arches=""
|
|
glib_has_gslice="no"
|
|
|
|
if test -e "$source_path/.git"
|
|
then
|
|
git_submodules_action="update"
|
|
else
|
|
git_submodules_action="ignore"
|
|
fi
|
|
|
|
git_submodules="ui/keycodemapdb"
|
|
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.
|
|
|
|
default_feature=""
|
|
# parse CC options second
|
|
for opt do
|
|
optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
|
|
case "$opt" in
|
|
--without-default-features)
|
|
default_feature="no"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
EXTRA_CFLAGS=""
|
|
EXTRA_CXXFLAGS=""
|
|
EXTRA_OBJCFLAGS=""
|
|
EXTRA_LDFLAGS=""
|
|
|
|
debug_tcg="no"
|
|
sanitizers="no"
|
|
tsan="no"
|
|
fortify_source="yes"
|
|
EXESUF=""
|
|
modules="no"
|
|
prefix="/usr/local"
|
|
qemu_suffix="qemu"
|
|
softmmu="yes"
|
|
linux_user=""
|
|
bsd_user=""
|
|
pie=""
|
|
coroutine=""
|
|
plugins="$default_feature"
|
|
meson=""
|
|
ninja=""
|
|
bindir="bin"
|
|
skip_meson=no
|
|
vfio_user_server="disabled"
|
|
|
|
# The following Meson options are handled manually (still they
|
|
# are included in the automatically generated help message)
|
|
|
|
# 1. Track which submodules are needed
|
|
fdt="auto"
|
|
|
|
# 2. Automatically enable/disable other options
|
|
tcg="auto"
|
|
cfi="false"
|
|
|
|
# parse CC options second
|
|
for opt do
|
|
optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
|
|
case "$opt" in
|
|
--cross-prefix=*) cross_prefix="$optarg"
|
|
cross_compile="yes"
|
|
;;
|
|
--cc=*) CC="$optarg"
|
|
;;
|
|
--cxx=*) CXX="$optarg"
|
|
;;
|
|
--cpu=*) cpu="$optarg"
|
|
;;
|
|
--extra-cflags=*)
|
|
EXTRA_CFLAGS="$EXTRA_CFLAGS $optarg"
|
|
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $optarg"
|
|
EXTRA_OBJCFLAGS="$EXTRA_OBJCFLAGS $optarg"
|
|
;;
|
|
--extra-cxxflags=*) EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $optarg"
|
|
;;
|
|
--extra-objcflags=*) EXTRA_OBJCFLAGS="$EXTRA_OBJCFLAGS $optarg"
|
|
;;
|
|
--extra-ldflags=*) EXTRA_LDFLAGS="$EXTRA_LDFLAGS $optarg"
|
|
;;
|
|
--cross-cc-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --cross-cc-FOO option"
|
|
;;
|
|
--cross-cc-cflags-*) cc_arch=${opt#--cross-cc-cflags-}; cc_arch=${cc_arch%%=*}
|
|
eval "cross_cc_cflags_${cc_arch}=\$optarg"
|
|
;;
|
|
--cross-cc-*) cc_arch=${opt#--cross-cc-}; cc_arch=${cc_arch%%=*}
|
|
eval "cross_cc_${cc_arch}=\$optarg"
|
|
;;
|
|
--cross-prefix-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --cross-prefix-FOO option"
|
|
;;
|
|
--cross-prefix-*) cc_arch=${opt#--cross-prefix-}; cc_arch=${cc_arch%%=*}
|
|
eval "cross_prefix_${cc_arch}=\$optarg"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# 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}"
|
|
objcopy="${OBJCOPY-${cross_prefix}objcopy}"
|
|
ld="${LD-${cross_prefix}ld}"
|
|
ranlib="${RANLIB-${cross_prefix}ranlib}"
|
|
nm="${NM-${cross_prefix}nm}"
|
|
smbd="$SMBD"
|
|
strip="${STRIP-${cross_prefix}strip}"
|
|
widl="${WIDL-${cross_prefix}widl}"
|
|
windres="${WINDRES-${cross_prefix}windres}"
|
|
windmc="${WINDMC-${cross_prefix}windmc}"
|
|
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}"
|
|
|
|
# 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="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
|
|
|
|
QEMU_LDFLAGS=
|
|
|
|
# Flags that are needed during configure but later taken care of by Meson
|
|
CONFIGURE_CFLAGS="-std=gnu11 -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
|
|
}
|
|
|
|
if check_define __linux__ ; then
|
|
targetos=linux
|
|
elif check_define _WIN32 ; then
|
|
targetos=windows
|
|
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
|
|
fi
|
|
|
|
# OS specific
|
|
|
|
mingw32="no"
|
|
bsd="no"
|
|
linux="no"
|
|
solaris="no"
|
|
case $targetos in
|
|
windows)
|
|
mingw32="yes"
|
|
plugins="no"
|
|
pie="no"
|
|
;;
|
|
gnu/kfreebsd)
|
|
bsd="yes"
|
|
;;
|
|
freebsd)
|
|
bsd="yes"
|
|
make="${MAKE-gmake}"
|
|
# needed for kinfo_getvmmap(3) in libutil.h
|
|
;;
|
|
dragonfly)
|
|
bsd="yes"
|
|
make="${MAKE-gmake}"
|
|
;;
|
|
netbsd)
|
|
bsd="yes"
|
|
make="${MAKE-gmake}"
|
|
;;
|
|
openbsd)
|
|
bsd="yes"
|
|
make="${MAKE-gmake}"
|
|
;;
|
|
darwin)
|
|
bsd="yes"
|
|
darwin="yes"
|
|
# 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}"
|
|
# 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)
|
|
pie="no"
|
|
QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE -fPIC $QEMU_CFLAGS"
|
|
;;
|
|
linux)
|
|
linux="yes"
|
|
;;
|
|
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
|
|
cpu="riscv"
|
|
elif check_define __arm__ ; then
|
|
cpu="arm"
|
|
elif check_define __aarch64__ ; then
|
|
cpu="aarch64"
|
|
elif check_define __loongarch64 ; then
|
|
cpu="loongarch64"
|
|
else
|
|
# Using uname is really broken, but it is just a fallback for architectures
|
|
# that are going to use TCI anyway
|
|
cpu=$(uname -m)
|
|
echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output '$cpu'"
|
|
fi
|
|
|
|
# Normalise host CPU name and set multilib cflags. The canonicalization
|
|
# isn't really necessary, because the architectures that we check for
|
|
# should not hit the 'uname -m' case, but better safe than sorry.
|
|
# Note that this case should only have supported host CPUs, not guests.
|
|
case "$cpu" in
|
|
armv*b|armv*l|arm)
|
|
cpu="arm" ;;
|
|
|
|
i386|i486|i586|i686)
|
|
cpu="i386"
|
|
CPU_CFLAGS="-m32" ;;
|
|
x32)
|
|
cpu="x86_64"
|
|
CPU_CFLAGS="-mx32" ;;
|
|
x86_64|amd64)
|
|
cpu="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" ;;
|
|
|
|
mips*)
|
|
cpu="mips" ;;
|
|
|
|
ppc)
|
|
CPU_CFLAGS="-m32" ;;
|
|
ppc64)
|
|
CPU_CFLAGS="-m64 -mbig-endian" ;;
|
|
ppc64le)
|
|
cpu="ppc64"
|
|
CPU_CFLAGS="-m64 -mlittle-endian" ;;
|
|
|
|
s390)
|
|
CPU_CFLAGS="-m31" ;;
|
|
s390x)
|
|
CPU_CFLAGS="-m64" ;;
|
|
|
|
sparc|sun4[cdmuv])
|
|
cpu="sparc"
|
|
CPU_CFLAGS="-m32 -mv8plus -mcpu=ultrasparc" ;;
|
|
sparc64)
|
|
CPU_CFLAGS="-m64 -mcpu=ultrasparc" ;;
|
|
esac
|
|
|
|
: ${make=${MAKE-make}}
|
|
|
|
|
|
check_py_version() {
|
|
# We require python >= 3.6.
|
|
# NB: a True python conditional creates a non-zero return code (Failure)
|
|
"$1" -c 'import sys; sys.exit(sys.version_info < (3,6))'
|
|
}
|
|
|
|
python=
|
|
first_python=
|
|
if test -z "${PYTHON}"; then
|
|
explicit_python=no
|
|
# A bare 'python' is traditionally python 2.x, but some distros
|
|
# have it as python 3.x, so check in both places.
|
|
for binary in python3 python python3.11 python3.10 python3.9 python3.8 python3.7 python3.6; do
|
|
if has "$binary"; then
|
|
python=$(command -v "$binary")
|
|
if check_py_version "$python"; then
|
|
# This one is good.
|
|
first_python=
|
|
break
|
|
else
|
|
first_python=$python
|
|
fi
|
|
fi
|
|
done
|
|
else
|
|
# Same as above, but only check the environment variable.
|
|
has "${PYTHON}" || error_exit "The PYTHON environment variable does not point to an executable"
|
|
python=$(command -v "$PYTHON")
|
|
explicit_python=yes
|
|
if check_py_version "$python"; then
|
|
# This one is good.
|
|
first_python=
|
|
else
|
|
first_python=$first_python
|
|
fi
|
|
fi
|
|
|
|
# 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
|
|
|
|
# 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"
|
|
# MinGW needs -mthreads for TLS and macro _MT.
|
|
CONFIGURE_CFLAGS="-mthreads $CONFIGURE_CFLAGS"
|
|
prefix="/qemu"
|
|
bindir=""
|
|
qemu_suffix=""
|
|
fi
|
|
|
|
werror=""
|
|
|
|
meson_option_build_array() {
|
|
printf '['
|
|
(if test "$targetos" = windows; then
|
|
IFS=\;
|
|
else
|
|
IFS=:
|
|
fi
|
|
for e in $1; do
|
|
printf '"""'
|
|
# backslash escape any '\' and '"' characters
|
|
printf "%s" "$e" | sed -e 's/\([\"]\)/\\\1/g'
|
|
printf '""",'
|
|
done)
|
|
printf ']\n'
|
|
}
|
|
|
|
. "$source_path/scripts/meson-buildoptions.sh"
|
|
|
|
meson_options=
|
|
meson_option_add() {
|
|
meson_options="$meson_options $(quote_sh "$1")"
|
|
}
|
|
meson_option_parse() {
|
|
meson_options="$meson_options $(_meson_option_parse "$@")"
|
|
if test $? -eq 1; then
|
|
echo "ERROR: unknown option $1"
|
|
echo "Try '$0 --help' for more information"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
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"
|
|
;;
|
|
--cross-prefix=*)
|
|
;;
|
|
--cc=*)
|
|
;;
|
|
--host-cc=*) host_cc="$optarg"
|
|
;;
|
|
--cxx=*)
|
|
;;
|
|
--objcc=*) objcc="$optarg"
|
|
;;
|
|
--make=*) make="$optarg"
|
|
;;
|
|
--install=*)
|
|
;;
|
|
--python=*) python="$optarg" ; explicit_python=yes
|
|
;;
|
|
--skip-meson) skip_meson=yes
|
|
;;
|
|
--meson=*) meson="$optarg"
|
|
;;
|
|
--ninja=*) ninja="$optarg"
|
|
;;
|
|
--smbd=*) smbd="$optarg"
|
|
;;
|
|
--extra-cflags=*)
|
|
;;
|
|
--extra-cxxflags=*)
|
|
;;
|
|
--extra-objcflags=*)
|
|
;;
|
|
--extra-ldflags=*)
|
|
;;
|
|
--cross-cc-*)
|
|
;;
|
|
--cross-prefix-*)
|
|
;;
|
|
--enable-debug-info) meson_option_add -Ddebug=true
|
|
;;
|
|
--disable-debug-info) meson_option_add -Ddebug=false
|
|
;;
|
|
--enable-modules)
|
|
modules="yes"
|
|
;;
|
|
--disable-modules)
|
|
modules="no"
|
|
;;
|
|
--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
|
|
;;
|
|
--with-default-devices) meson_option_add -Ddefault_devices=true
|
|
;;
|
|
--without-default-devices) meson_option_add -Ddefault_devices=false
|
|
;;
|
|
--with-devices-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --with-devices-FOO option"
|
|
;;
|
|
--with-devices-*) device_arch=${opt#--with-devices-};
|
|
device_arch=${device_arch%%=*}
|
|
cf=$source_path/configs/devices/$device_arch-softmmu/$optarg.mak
|
|
if test -f "$cf"; then
|
|
device_archs="$device_archs $device_arch"
|
|
eval "devices_${device_arch}=\$optarg"
|
|
else
|
|
error_exit "File $cf does not exist"
|
|
fi
|
|
;;
|
|
--without-default-features) # processed above
|
|
;;
|
|
--static)
|
|
static="yes"
|
|
QEMU_PKG_CONFIG_FLAGS="--static $QEMU_PKG_CONFIG_FLAGS"
|
|
;;
|
|
--bindir=*) bindir="$optarg"
|
|
;;
|
|
--with-suffix=*) qemu_suffix="$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.
|
|
;;
|
|
--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"
|
|
meson_option_parse --enable-debug-mutex ""
|
|
meson_option_add -Doptimization=0
|
|
fortify_source="no"
|
|
;;
|
|
--enable-sanitizers) sanitizers="yes"
|
|
;;
|
|
--disable-sanitizers) sanitizers="no"
|
|
;;
|
|
--enable-tsan) tsan="yes"
|
|
;;
|
|
--disable-tsan) tsan="no"
|
|
;;
|
|
--disable-tcg) tcg="disabled"
|
|
plugins="no"
|
|
;;
|
|
--enable-tcg) tcg="enabled"
|
|
;;
|
|
--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"
|
|
;;
|
|
--enable-cfi)
|
|
cfi="true";
|
|
meson_option_add -Db_lto=true
|
|
;;
|
|
--disable-cfi) cfi="false"
|
|
;;
|
|
--disable-fdt) fdt="disabled"
|
|
;;
|
|
--enable-fdt) fdt="enabled"
|
|
;;
|
|
--enable-fdt=git) fdt="internal"
|
|
;;
|
|
--enable-fdt=*) fdt="$optarg"
|
|
;;
|
|
--with-coroutine=*) coroutine="$optarg"
|
|
;;
|
|
--with-git=*) git="$optarg"
|
|
;;
|
|
--with-git-submodules=*)
|
|
git_submodules_action="$optarg"
|
|
;;
|
|
--enable-plugins) if test "$mingw32" = "yes"; then
|
|
error_exit "TCG plugins not currently supported on Windows platforms"
|
|
else
|
|
plugins="yes"
|
|
fi
|
|
;;
|
|
--disable-plugins) plugins="no"
|
|
;;
|
|
--enable-containers) use_containers="yes"
|
|
;;
|
|
--disable-containers) use_containers="no"
|
|
;;
|
|
--gdb=*) gdb_bin="$optarg"
|
|
;;
|
|
--enable-vfio-user-server) vfio_user_server="enabled"
|
|
;;
|
|
--disable-vfio-user-server) vfio_user_server="disabled"
|
|
;;
|
|
# everything else has the same name in configure and meson
|
|
--*) meson_option_parse "$opt" "$optarg"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# test for any invalid configuration combinations
|
|
if test "$plugins" = "yes" -a "$tcg" = "disabled"; then
|
|
error_exit "Can't enable plugins on non-TCG builds"
|
|
fi
|
|
|
|
case $git_submodules_action in
|
|
update|validate)
|
|
if test ! -e "$source_path/.git"; then
|
|
echo "ERROR: cannot $git_submodules_action git submodules without .git"
|
|
exit 1
|
|
fi
|
|
;;
|
|
ignore)
|
|
if ! test -f "$source_path/ui/keycodemapdb/README"
|
|
then
|
|
echo
|
|
echo "ERROR: missing GIT submodules"
|
|
echo
|
|
if test -e "$source_path/.git"; then
|
|
echo "--with-git-submodules=ignore specified but submodules were not"
|
|
echo "checked out. Please initialize and update submodules."
|
|
else
|
|
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."
|
|
fi
|
|
echo
|
|
exit 1
|
|
fi
|
|
;;
|
|
*)
|
|
echo "ERROR: invalid --with-git-submodules= value '$git_submodules_action'"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
default_target_list=""
|
|
mak_wilds=""
|
|
|
|
if [ "$linux_user" != no ]; then
|
|
if [ "$targetos" = linux ] && [ -d "$source_path/linux-user/include/host/$cpu" ]; then
|
|
linux_user=yes
|
|
elif [ "$linux_user" = yes ]; then
|
|
error_exit "linux-user not supported on this architecture"
|
|
fi
|
|
fi
|
|
if [ "$bsd_user" != no ]; then
|
|
if [ "$bsd_user" = "" ]; then
|
|
test $targetos = freebsd && bsd_user=yes
|
|
fi
|
|
if [ "$bsd_user" = yes ] && ! [ -d "$source_path/bsd-user/$targetos" ]; then
|
|
error_exit "bsd-user not supported on this host OS"
|
|
fi
|
|
fi
|
|
if [ "$softmmu" = "yes" ]; then
|
|
mak_wilds="${mak_wilds} $source_path/configs/targets/*-softmmu.mak"
|
|
fi
|
|
if [ "$linux_user" = "yes" ]; then
|
|
mak_wilds="${mak_wilds} $source_path/configs/targets/*-linux-user.mak"
|
|
fi
|
|
if [ "$bsd_user" = "yes" ]; then
|
|
mak_wilds="${mak_wilds} $source_path/configs/targets/*-bsd-user.mak"
|
|
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
|
|
|
|
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]
|
|
--target-list=LIST set target list (default: build all)
|
|
$(echo Available targets: $default_target_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, PREFIX can be blank [$cross_prefix]
|
|
--cc=CC use C compiler CC [$cc]
|
|
--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 CFLAGS
|
|
--extra-cxxflags=CXXFLAGS append extra C++ compiler flags CXXFLAGS
|
|
--extra-objcflags=OBJCFLAGS append extra Objective C compiler flags OBJCFLAGS
|
|
--extra-ldflags=LDFLAGS append extra linker flags LDFLAGS
|
|
--cross-cc-ARCH=CC use compiler when building ARCH guest test cases
|
|
--cross-cc-cflags-ARCH= use compiler flags when building ARCH guest tests
|
|
--cross-prefix-ARCH=PREFIX cross compiler prefix when building ARCH guest test cases
|
|
--make=MAKE use specified make [$make]
|
|
--python=PYTHON use specified python [$python]
|
|
--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]
|
|
--with-git-submodules=update update git submodules (default if .git dir exists)
|
|
--with-git-submodules=validate fail if git submodules are not up to date
|
|
--with-git-submodules=ignore do not update or check git submodules (default if no .git dir)
|
|
--static enable static build [$static]
|
|
--bindir=PATH install binaries in PATH
|
|
--with-suffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir/docdir [$qemu_suffix]
|
|
--without-default-features default all --enable-* options to "disabled"
|
|
--without-default-devices do not include any device that is not needed to
|
|
start the emulator (only use if you are including
|
|
desired devices in configs/devices/)
|
|
--with-devices-ARCH=NAME override default configs/devices
|
|
--enable-debug enable common debug build options
|
|
--enable-sanitizers enable default sanitizers
|
|
--enable-tsan enable thread sanitizer
|
|
--disable-werror disable compilation abort on warning
|
|
--disable-stack-protector disable compiler-provided stack protection
|
|
--cpu=CPU Build for host CPU [$cpu]
|
|
--with-coroutine=BACKEND coroutine backend. Supported options:
|
|
ucontext, sigaltstack, windows
|
|
--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]
|
|
EOF
|
|
meson_options_help
|
|
cat << EOF
|
|
system all system emulation targets
|
|
user supported user emulation targets
|
|
linux-user all linux usermode emulation targets
|
|
bsd-user all BSD usermode emulation targets
|
|
pie Position Independent Executables
|
|
modules modules support (non-Windows)
|
|
debug-tcg TCG debugging (default is disabled)
|
|
debug-info debugging information
|
|
safe-stack SafeStack Stack Smash Protection. Depends on
|
|
clang/llvm and requires coroutine backend ucontext.
|
|
|
|
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
|
|
# If first_python is set, there was a binary somewhere even though
|
|
# it was not suitable. Use it for the error message.
|
|
if test -n "$first_python"; then
|
|
error_exit "Cannot use '$first_python', Python >= 3.6 is required." \
|
|
"Use --python=/path/to/python to specify a supported Python."
|
|
else
|
|
error_exit "Python not found. Use --python=/path/to/python"
|
|
fi
|
|
fi
|
|
|
|
if ! has "$make"
|
|
then
|
|
error_exit "GNU make ($make) not found"
|
|
fi
|
|
|
|
if ! check_py_version "$python"; then
|
|
error_exit "Cannot use '$python', Python >= 3.6 is required." \
|
|
"Use --python=/path/to/python to specify a supported Python."
|
|
fi
|
|
|
|
# Resolve PATH + suppress writing compiled files
|
|
python="$(command -v "$python") -B"
|
|
|
|
has_meson() {
|
|
local python_dir=$(dirname "$python")
|
|
# PEP405: pyvenv.cfg is either adjacent to the Python executable
|
|
# or one directory above
|
|
if test -f $python_dir/pyvenv.cfg || test -f $python_dir/../pyvenv.cfg; then
|
|
# Ensure that Meson and Python come from the same virtual environment
|
|
test -x "$python_dir/meson" &&
|
|
test "$(command -v meson)" -ef "$python_dir/meson"
|
|
else
|
|
has meson
|
|
fi
|
|
}
|
|
|
|
if test -z "$meson"; then
|
|
if test "$explicit_python" = no && has_meson && version_ge "$(meson --version)" 0.61.5; then
|
|
meson=meson
|
|
elif test "$git_submodules_action" != 'ignore' ; 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 "$git_submodules_action" != "ignore" && \
|
|
{ test "$linux" = "yes" || test "$mingw32" = "yes"; }; then
|
|
werror="yes"
|
|
else
|
|
werror="no"
|
|
fi
|
|
fi
|
|
|
|
if test "$targetos" = "bogus"; 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__ < 12 || (__clang_major__ == 12 && __clang_minor__ < 0)
|
|
# error You need at least XCode Clang v12.0 to compile QEMU
|
|
# endif
|
|
# else
|
|
# if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
|
|
# error You need at least Clang v10.0 to compile QEMU
|
|
# endif
|
|
# endif
|
|
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
|
# if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 4)
|
|
# error You need at least GCC v7.4.0 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 v7.4 or Clang v10.0 (or XCode Clang v12.0)"
|
|
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 -Wundef
|
|
add_to warn_flags -Wwrite-strings
|
|
add_to warn_flags -Wmissing-prototypes
|
|
add_to warn_flags -Wstrict-prototypes
|
|
add_to warn_flags -Wredundant-decls
|
|
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
|
|
add_to warn_flags -Wimplicit-fallthrough=2
|
|
add_to warn_flags -Wmissing-format-attribute
|
|
|
|
if test "$targetos" != "darwin"; then
|
|
add_to warn_flags -Wthread-safety
|
|
fi
|
|
|
|
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
|
|
add_to nowarn_flags -Wno-gnu-variable-sized-type-not-at-end
|
|
|
|
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" ""
|
|
}
|
|
|
|
objcc_has_warning_flag() {
|
|
cat > $TMPM <<EOF
|
|
int main(void) { return 0; }
|
|
EOF
|
|
|
|
# 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/')"
|
|
do_objc -Werror $optflag \
|
|
$OBJCFLAGS $EXTRA_OBJCFLAGS $CONFIGURE_OBJCFLAGS $QEMU_OBJCFLAGS \
|
|
-o $TMPE $TMPM $QEMU_LDFLAGS
|
|
}
|
|
|
|
for flag in $gcc_flags; do
|
|
if cc_has_warning_flag $flag ; then
|
|
QEMU_CFLAGS="$QEMU_CFLAGS $flag"
|
|
fi
|
|
if objcc_has_warning_flag $flag ; then
|
|
QEMU_OBJCFLAGS="$QEMU_OBJCFLAGS $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[argc - 1];
|
|
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
|
|
|
|
# Our module code doesn't support Windows
|
|
if test "$modules" = "yes" && test "$mingw32" = "yes" ; then
|
|
error_exit "Modules are not available for Windows"
|
|
fi
|
|
|
|
# Static linking is not possible with plugins, modules or PIE
|
|
if test "$static" = "yes" ; then
|
|
if test "$modules" = "yes" ; then
|
|
error_exit "static and modules are mutually incompatible"
|
|
fi
|
|
if test "$plugins" = "yes"; then
|
|
error_exit "static and plugins are mutually incompatible"
|
|
else
|
|
plugins="no"
|
|
fi
|
|
fi
|
|
test "$plugins" = "" && plugins=yes
|
|
|
|
cat > $TMPC << EOF
|
|
|
|
#ifdef __linux__
|
|
# define THREAD __thread
|
|
#else
|
|
# define THREAD
|
|
#endif
|
|
static THREAD int tls_var;
|
|
int main(void) { return tls_var; }
|
|
EOF
|
|
|
|
# Meson currently only handles pie as a boolean for now so if we have
|
|
# explicitly disabled PIE we need to extend our cflags because it wont.
|
|
if test "$static" = "yes"; then
|
|
if test "$pie" != "no" && compile_prog "-Werror -fPIE -DPIE" "-static-pie"; then
|
|
CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS"
|
|
pie="yes"
|
|
elif test "$pie" = "yes"; then
|
|
error_exit "-static-pie not available due to missing toolchain support"
|
|
else
|
|
pie="no"
|
|
QEMU_CFLAGS="-fno-pie $QEMU_CFLAGS"
|
|
fi
|
|
elif test "$pie" = "no"; then
|
|
if compile_prog "-Werror -fno-pie" "-no-pie"; then
|
|
CONFIGURE_CFLAGS="-fno-pie $CONFIGURE_CFLAGS"
|
|
CONFIGURE_LDFLAGS="-no-pie $CONFIGURE_LDFLAGS"
|
|
QEMU_CFLAGS="-fno-pie -no-pie $QEMU_CFLAGS"
|
|
fi
|
|
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
|
|
|
|
##########################################
|
|
# __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
|
|
|
|
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
|
|
|
|
# see if system emulation was really requested
|
|
case " $target_list " in
|
|
*"-softmmu "*) softmmu=yes
|
|
;;
|
|
*) softmmu=no
|
|
;;
|
|
esac
|
|
|
|
if test "$tcg" = "auto"; then
|
|
if test -z "$target_list"; then
|
|
tcg="disabled"
|
|
else
|
|
tcg="enabled"
|
|
fi
|
|
fi
|
|
|
|
if test "$tcg" = "enabled"; then
|
|
git_submodules="$git_submodules tests/fp/berkeley-testfloat-3"
|
|
git_submodules="$git_submodules tests/fp/berkeley-softfloat-3"
|
|
fi
|
|
|
|
##########################################
|
|
# big/little endian test
|
|
cat > $TMPC << EOF
|
|
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
# error LITTLE
|
|
#endif
|
|
int main(void) { return 0; }
|
|
EOF
|
|
|
|
if ! compile_prog ; then
|
|
bigendian="no"
|
|
else
|
|
cat > $TMPC << EOF
|
|
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
# error BIG
|
|
#endif
|
|
int main(void) { return 0; }
|
|
EOF
|
|
|
|
if ! compile_prog ; then
|
|
bigendian="yes"
|
|
else
|
|
echo big/little test failed
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
##########################################
|
|
# pkg-config probe
|
|
|
|
if ! has "$pkg_config_exe"; then
|
|
error_exit "pkg-config binary '$pkg_config_exe' not found"
|
|
fi
|
|
|
|
##########################################
|
|
# glib support probe
|
|
|
|
# When bumping glib_req_ver, please check also whether we should increase
|
|
# the _WIN32_WINNT setting in osdep.h according to the value from glib
|
|
glib_req_ver=2.56
|
|
glib_modules=gthread-2.0
|
|
if test "$modules" = yes; then
|
|
glib_modules="$glib_modules gmodule-export-2.0"
|
|
elif test "$plugins" = "yes"; then
|
|
glib_modules="$glib_modules gmodule-no-export-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
|
|
|
|
# Check whether glib has gslice, which we have to avoid for correctness.
|
|
# TODO: remove this check and the corresponding workaround (qtree) when
|
|
# the minimum supported glib is >= $glib_dropped_gslice_version.
|
|
glib_dropped_gslice_version=2.75.3
|
|
for i in $glib_modules; do
|
|
if ! $pkg_config --atleast-version=$glib_dropped_gslice_version $i; then
|
|
glib_has_gslice="yes"
|
|
break
|
|
fi
|
|
done
|
|
|
|
glib_bindir="$($pkg_config --variable=bindir glib-2.0)"
|
|
if test -z "$glib_bindir" ; then
|
|
glib_bindir="$($pkg_config --variable=prefix glib-2.0)"/bin
|
|
fi
|
|
|
|
# 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
|
|
|
|
# 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 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
|
|
|
|
##########################################
|
|
# fdt probe
|
|
|
|
case "$fdt" in
|
|
auto | enabled | internal)
|
|
# Simpler to always update submodule, even if not needed.
|
|
git_submodules="${git_submodules} dtc"
|
|
;;
|
|
esac
|
|
|
|
##########################################
|
|
# 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
|
|
error_exit "'ucontext' backend requested but makecontext not available"
|
|
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
|
|
|
|
##################################################
|
|
# SafeStack
|
|
|
|
|
|
if test "$safe_stack" = "yes"; then
|
|
cat > $TMPC << EOF
|
|
int main(void)
|
|
{
|
|
#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(void)
|
|
{
|
|
#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 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(void)
|
|
{
|
|
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
|
|
|
|
##########################################
|
|
# 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
|
|
|
|
# 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
|
|
|
|
##########################################
|
|
# functions to probe cross compilers
|
|
|
|
container="no"
|
|
runc=""
|
|
if test $use_containers = "yes" && (has "docker" || has "podman"); then
|
|
case $($python "$source_path"/tests/docker/docker.py probe) in
|
|
*docker) container=docker ;;
|
|
podman) container=podman ;;
|
|
no) container=no ;;
|
|
esac
|
|
if test "$container" != "no"; then
|
|
docker_py="$python $source_path/tests/docker/docker.py --engine $container"
|
|
runc=$($python "$source_path"/tests/docker/docker.py probe)
|
|
fi
|
|
fi
|
|
|
|
# cross compilers defaults, can be overridden with --cross-cc-ARCH
|
|
: ${cross_prefix_aarch64="aarch64-linux-gnu-"}
|
|
: ${cross_prefix_aarch64_be="$cross_prefix_aarch64"}
|
|
: ${cross_prefix_alpha="alpha-linux-gnu-"}
|
|
: ${cross_prefix_arm="arm-linux-gnueabihf-"}
|
|
: ${cross_prefix_armeb="$cross_prefix_arm"}
|
|
: ${cross_prefix_hexagon="hexagon-unknown-linux-musl-"}
|
|
: ${cross_prefix_loongarch64="loongarch64-unknown-linux-gnu-"}
|
|
: ${cross_prefix_hppa="hppa-linux-gnu-"}
|
|
: ${cross_prefix_i386="i686-linux-gnu-"}
|
|
: ${cross_prefix_m68k="m68k-linux-gnu-"}
|
|
: ${cross_prefix_microblaze="microblaze-linux-musl-"}
|
|
: ${cross_prefix_mips64el="mips64el-linux-gnuabi64-"}
|
|
: ${cross_prefix_mips64="mips64-linux-gnuabi64-"}
|
|
: ${cross_prefix_mipsel="mipsel-linux-gnu-"}
|
|
: ${cross_prefix_mips="mips-linux-gnu-"}
|
|
: ${cross_prefix_nios2="nios2-linux-gnu-"}
|
|
: ${cross_prefix_ppc="powerpc-linux-gnu-"}
|
|
: ${cross_prefix_ppc64="powerpc64-linux-gnu-"}
|
|
: ${cross_prefix_ppc64le="$cross_prefix_ppc64"}
|
|
: ${cross_prefix_riscv64="riscv64-linux-gnu-"}
|
|
: ${cross_prefix_s390x="s390x-linux-gnu-"}
|
|
: ${cross_prefix_sh4="sh4-linux-gnu-"}
|
|
: ${cross_prefix_sparc64="sparc64-linux-gnu-"}
|
|
: ${cross_prefix_sparc="$cross_prefix_sparc64"}
|
|
: ${cross_prefix_x86_64="x86_64-linux-gnu-"}
|
|
|
|
: ${cross_cc_aarch64_be="$cross_cc_aarch64"}
|
|
: ${cross_cc_cflags_aarch64_be="-mbig-endian"}
|
|
: ${cross_cc_armeb="$cross_cc_arm"}
|
|
: ${cross_cc_cflags_armeb="-mbig-endian"}
|
|
: ${cross_cc_hexagon="hexagon-unknown-linux-musl-clang"}
|
|
: ${cross_cc_cflags_hexagon="-mv67 -O2 -static"}
|
|
: ${cross_cc_cflags_i386="-m32"}
|
|
: ${cross_cc_cflags_ppc="-m32 -mbig-endian"}
|
|
: ${cross_cc_cflags_ppc64="-m64 -mbig-endian"}
|
|
: ${cross_cc_ppc64le="$cross_cc_ppc64"}
|
|
: ${cross_cc_cflags_ppc64le="-m64 -mlittle-endian"}
|
|
: ${cross_cc_cflags_sparc64="-m64 -mcpu=ultrasparc"}
|
|
: ${cross_cc_sparc="$cross_cc_sparc64"}
|
|
: ${cross_cc_cflags_sparc="-m32 -mcpu=supersparc"}
|
|
: ${cross_cc_cflags_x86_64="-m64"}
|
|
|
|
compute_target_variable() {
|
|
eval "$2="
|
|
if eval test -n "\"\${cross_prefix_$1}\""; then
|
|
if eval has "\"\${cross_prefix_$1}\$3\""; then
|
|
eval "$2=\"\${cross_prefix_$1}\$3\""
|
|
fi
|
|
fi
|
|
}
|
|
|
|
have_target() {
|
|
for i; do
|
|
case " $target_list " in
|
|
*" $i "*) return 0;;
|
|
*) ;;
|
|
esac
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# probe_target_compiler TARGET
|
|
#
|
|
# Look for a compiler for the given target, either native or cross.
|
|
# Set variables target_* if a compiler is found, and container_cross_*
|
|
# if a Docker-based cross-compiler image is known for the target.
|
|
# Set got_cross_cc to yes/no depending on whether a non-container-based
|
|
# compiler was found.
|
|
#
|
|
# If TARGET is a user-mode emulation target, also set build_static to
|
|
# "y" if static linking is possible.
|
|
#
|
|
probe_target_compiler() {
|
|
# reset all output variables
|
|
got_cross_cc=no
|
|
container_image=
|
|
container_hosts=
|
|
container_cross_cc=
|
|
container_cross_ar=
|
|
container_cross_as=
|
|
container_cross_ld=
|
|
container_cross_nm=
|
|
container_cross_objcopy=
|
|
container_cross_ranlib=
|
|
container_cross_strip=
|
|
|
|
# We shall skip configuring the target compiler if the user didn't
|
|
# bother enabling an appropriate guest. This avoids building
|
|
# extraneous firmware images and tests.
|
|
if test "${target_list#*$1}" = "$1"; then
|
|
return 1
|
|
fi
|
|
|
|
target_arch=${1%%-*}
|
|
case $target_arch in
|
|
aarch64) container_hosts="x86_64 aarch64" ;;
|
|
alpha) container_hosts=x86_64 ;;
|
|
arm) container_hosts="x86_64 aarch64" ;;
|
|
cris) container_hosts=x86_64 ;;
|
|
hexagon) container_hosts=x86_64 ;;
|
|
hppa) container_hosts=x86_64 ;;
|
|
i386) container_hosts=x86_64 ;;
|
|
loongarch64) container_hosts=x86_64 ;;
|
|
m68k) container_hosts=x86_64 ;;
|
|
microblaze) container_hosts=x86_64 ;;
|
|
mips64el) container_hosts=x86_64 ;;
|
|
mips64) container_hosts=x86_64 ;;
|
|
mipsel) container_hosts=x86_64 ;;
|
|
mips) container_hosts=x86_64 ;;
|
|
nios2) container_hosts=x86_64 ;;
|
|
ppc) container_hosts=x86_64 ;;
|
|
ppc64|ppc64le) container_hosts=x86_64 ;;
|
|
riscv64) container_hosts=x86_64 ;;
|
|
s390x) container_hosts=x86_64 ;;
|
|
sh4) container_hosts=x86_64 ;;
|
|
sparc64) container_hosts=x86_64 ;;
|
|
tricore) container_hosts=x86_64 ;;
|
|
x86_64) container_hosts="aarch64 ppc64el x86_64" ;;
|
|
xtensa*) container_hosts=x86_64 ;;
|
|
esac
|
|
|
|
for host in $container_hosts; do
|
|
test "$container" != no || continue
|
|
test "$host" = "$cpu" || continue
|
|
case $target_arch in
|
|
aarch64)
|
|
# We don't have any bigendian build tools so we only use this for AArch64
|
|
container_image=debian-arm64-cross
|
|
container_cross_prefix=aarch64-linux-gnu-
|
|
container_cross_cc=${container_cross_prefix}gcc-10
|
|
;;
|
|
alpha)
|
|
container_image=debian-alpha-cross
|
|
container_cross_prefix=alpha-linux-gnu-
|
|
;;
|
|
arm)
|
|
# We don't have any bigendian build tools so we only use this for ARM
|
|
container_image=debian-armhf-cross
|
|
container_cross_prefix=arm-linux-gnueabihf-
|
|
;;
|
|
cris)
|
|
container_image=fedora-cris-cross
|
|
container_cross_prefix=cris-linux-gnu-
|
|
;;
|
|
hexagon)
|
|
container_image=debian-hexagon-cross
|
|
container_cross_prefix=hexagon-unknown-linux-musl-
|
|
container_cross_cc=${container_cross_prefix}clang
|
|
;;
|
|
hppa)
|
|
container_image=debian-hppa-cross
|
|
container_cross_prefix=hppa-linux-gnu-
|
|
;;
|
|
i386)
|
|
container_image=fedora-i386-cross
|
|
container_cross_prefix=
|
|
;;
|
|
loongarch64)
|
|
container_image=debian-loongarch-cross
|
|
container_cross_prefix=loongarch64-unknown-linux-gnu-
|
|
;;
|
|
m68k)
|
|
container_image=debian-m68k-cross
|
|
container_cross_prefix=m68k-linux-gnu-
|
|
;;
|
|
microblaze)
|
|
container_image=debian-microblaze-cross
|
|
container_cross_prefix=microblaze-linux-musl-
|
|
;;
|
|
mips64el)
|
|
container_image=debian-mips64el-cross
|
|
container_cross_prefix=mips64el-linux-gnuabi64-
|
|
;;
|
|
mips64)
|
|
container_image=debian-mips64-cross
|
|
container_cross_prefix=mips64-linux-gnuabi64-
|
|
;;
|
|
mipsel)
|
|
container_image=debian-mipsel-cross
|
|
container_cross_prefix=mipsel-linux-gnu-
|
|
;;
|
|
mips)
|
|
container_image=debian-mips-cross
|
|
container_cross_prefix=mips-linux-gnu-
|
|
;;
|
|
nios2)
|
|
container_image=debian-nios2-cross
|
|
container_cross_prefix=nios2-linux-gnu-
|
|
;;
|
|
ppc)
|
|
container_image=debian-powerpc-test-cross
|
|
container_cross_prefix=powerpc-linux-gnu-
|
|
container_cross_cc=${container_cross_prefix}gcc-10
|
|
;;
|
|
ppc64|ppc64le)
|
|
container_image=debian-powerpc-test-cross
|
|
container_cross_prefix=powerpc${target_arch#ppc}-linux-gnu-
|
|
container_cross_cc=${container_cross_prefix}gcc-10
|
|
;;
|
|
riscv64)
|
|
container_image=debian-riscv64-test-cross
|
|
container_cross_prefix=riscv64-linux-gnu-
|
|
;;
|
|
s390x)
|
|
container_image=debian-s390x-cross
|
|
container_cross_prefix=s390x-linux-gnu-
|
|
;;
|
|
sh4)
|
|
container_image=debian-sh4-cross
|
|
container_cross_prefix=sh4-linux-gnu-
|
|
;;
|
|
sparc64)
|
|
container_image=debian-sparc64-cross
|
|
container_cross_prefix=sparc64-linux-gnu-
|
|
;;
|
|
tricore)
|
|
container_image=debian-tricore-cross
|
|
container_cross_prefix=tricore-
|
|
container_cross_as=tricore-as
|
|
container_cross_ld=tricore-ld
|
|
break
|
|
;;
|
|
x86_64)
|
|
container_image=debian-amd64-cross
|
|
container_cross_prefix=x86_64-linux-gnu-
|
|
;;
|
|
xtensa*)
|
|
container_hosts=x86_64
|
|
container_image=debian-xtensa-cross
|
|
|
|
# default to the dc232b cpu
|
|
container_cross_prefix=/opt/2020.07/xtensa-dc232b-elf/bin/xtensa-dc232b-elf-
|
|
;;
|
|
esac
|
|
: ${container_cross_cc:=${container_cross_prefix}gcc}
|
|
: ${container_cross_ar:=${container_cross_prefix}ar}
|
|
: ${container_cross_as:=${container_cross_prefix}as}
|
|
: ${container_cross_ld:=${container_cross_prefix}ld}
|
|
: ${container_cross_nm:=${container_cross_prefix}nm}
|
|
: ${container_cross_objcopy:=${container_cross_prefix}objcopy}
|
|
: ${container_cross_ranlib:=${container_cross_prefix}ranlib}
|
|
: ${container_cross_strip:=${container_cross_prefix}strip}
|
|
done
|
|
|
|
try=cross
|
|
case "$target_arch:$cpu" in
|
|
aarch64_be:aarch64 | \
|
|
armeb:arm | \
|
|
i386:x86_64 | \
|
|
mips*:mips64 | \
|
|
ppc*:ppc64 | \
|
|
sparc:sparc64 | \
|
|
"$cpu:$cpu")
|
|
try='native cross' ;;
|
|
esac
|
|
eval "target_cflags=\${cross_cc_cflags_$target_arch}"
|
|
for thistry in $try; do
|
|
case $thistry in
|
|
native)
|
|
target_cc=$cc
|
|
target_ccas=$ccas
|
|
target_ar=$ar
|
|
target_as=$as
|
|
target_ld=$ld
|
|
target_nm=$nm
|
|
target_objcopy=$objcopy
|
|
target_ranlib=$ranlib
|
|
target_strip=$strip
|
|
;;
|
|
cross)
|
|
target_cc=
|
|
if eval test -n "\"\${cross_cc_$target_arch}\""; then
|
|
if eval has "\"\${cross_cc_$target_arch}\""; then
|
|
eval "target_cc=\"\${cross_cc_$target_arch}\""
|
|
fi
|
|
else
|
|
compute_target_variable $target_arch target_cc gcc
|
|
fi
|
|
target_ccas=$target_cc
|
|
compute_target_variable $target_arch target_ar ar
|
|
compute_target_variable $target_arch target_as as
|
|
compute_target_variable $target_arch target_ld ld
|
|
compute_target_variable $target_arch target_nm nm
|
|
compute_target_variable $target_arch target_objcopy objcopy
|
|
compute_target_variable $target_arch target_ranlib ranlib
|
|
compute_target_variable $target_arch target_strip strip
|
|
;;
|
|
esac
|
|
|
|
if test -n "$target_cc"; then
|
|
case $target_arch in
|
|
i386|x86_64)
|
|
if $target_cc --version | grep -qi "clang"; then
|
|
continue
|
|
fi
|
|
;;
|
|
esac
|
|
elif test -n "$target_as" && test -n "$target_ld"; then
|
|
# Special handling for assembler only targets
|
|
case $target in
|
|
tricore-softmmu)
|
|
build_static=
|
|
got_cross_cc=yes
|
|
break
|
|
;;
|
|
*)
|
|
continue
|
|
;;
|
|
esac
|
|
else
|
|
continue
|
|
fi
|
|
|
|
write_c_skeleton
|
|
case $1 in
|
|
*-softmmu)
|
|
if do_compiler "$target_cc" $target_cflags -o $TMPO -c $TMPC &&
|
|
do_compiler "$target_cc" $target_cflags -r -nostdlib -o "${TMPDIR1}/${TMPB}2.o" "$TMPO" -lgcc; then
|
|
got_cross_cc=yes
|
|
break
|
|
fi
|
|
;;
|
|
*)
|
|
if do_compiler "$target_cc" $target_cflags -o $TMPE $TMPC -static ; then
|
|
build_static=y
|
|
got_cross_cc=yes
|
|
break
|
|
fi
|
|
if do_compiler "$target_cc" $target_cflags -o $TMPE $TMPC ; then
|
|
build_static=
|
|
got_cross_cc=yes
|
|
break
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
if test $got_cross_cc != yes; then
|
|
build_static=
|
|
target_cc=
|
|
target_ccas=
|
|
target_ar=
|
|
target_as=
|
|
target_ld=
|
|
target_nm=
|
|
target_objcopy=
|
|
target_ranlib=
|
|
target_strip=
|
|
fi
|
|
test -n "$target_cc"
|
|
}
|
|
|
|
write_target_makefile() {
|
|
echo "EXTRA_CFLAGS=$target_cflags"
|
|
if test -z "$target_cc" && test -z "$target_as"; then
|
|
test -z "$container_image" && error_exit "Internal error: could not find cross compiler for $1?"
|
|
echo "$1: docker-image-$container_image" >> Makefile.prereqs
|
|
if test -n "$container_cross_cc"; then
|
|
echo "CC=$docker_py cc --cc $container_cross_cc -i qemu/$container_image -s $source_path --"
|
|
echo "CCAS=$docker_py cc --cc $container_cross_cc -i qemu/$container_image -s $source_path --"
|
|
fi
|
|
echo "AR=$docker_py cc --cc $container_cross_ar -i qemu/$container_image -s $source_path --"
|
|
echo "AS=$docker_py cc --cc $container_cross_as -i qemu/$container_image -s $source_path --"
|
|
echo "LD=$docker_py cc --cc $container_cross_ld -i qemu/$container_image -s $source_path --"
|
|
echo "NM=$docker_py cc --cc $container_cross_nm -i qemu/$container_image -s $source_path --"
|
|
echo "OBJCOPY=$docker_py cc --cc $container_cross_objcopy -i qemu/$container_image -s $source_path --"
|
|
echo "RANLIB=$docker_py cc --cc $container_cross_ranlib -i qemu/$container_image -s $source_path --"
|
|
echo "STRIP=$docker_py cc --cc $container_cross_strip -i qemu/$container_image -s $source_path --"
|
|
else
|
|
if test -n "$target_cc"; then
|
|
echo "CC=$target_cc"
|
|
echo "CCAS=$target_ccas"
|
|
fi
|
|
if test -n "$target_ar"; then
|
|
echo "AR=$target_ar"
|
|
fi
|
|
if test -n "$target_as"; then
|
|
echo "AS=$target_as"
|
|
fi
|
|
if test -n "$target_ld"; then
|
|
echo "LD=$target_ld"
|
|
fi
|
|
if test -n "$target_nm"; then
|
|
echo "NM=$target_nm"
|
|
fi
|
|
if test -n "$target_objcopy"; then
|
|
echo "OBJCOPY=$target_objcopy"
|
|
fi
|
|
if test -n "$target_ranlib"; then
|
|
echo "RANLIB=$target_ranlib"
|
|
fi
|
|
if test -n "$target_strip"; then
|
|
echo "STRIP=$target_strip"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
##########################################
|
|
# check for vfio_user_server
|
|
|
|
case "$vfio_user_server" in
|
|
enabled )
|
|
if test "$git_submodules_action" != "ignore"; then
|
|
git_submodules="${git_submodules} subprojects/libvfio-user"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
##########################################
|
|
# End of CC checks
|
|
# After here, no more $cc or $ld runs
|
|
|
|
write_c_skeleton
|
|
|
|
if test "$fortify_source" = "yes" ; then
|
|
QEMU_CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
|
|
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
|
|
|
|
#######################################
|
|
# cross-compiled firmware targets
|
|
|
|
# Set up build tree symlinks that point back into the source tree
|
|
# (these can be both files and directories).
|
|
# Caution: avoid adding 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.
|
|
LINKS="Makefile"
|
|
LINKS="$LINKS docs/config"
|
|
LINKS="$LINKS pc-bios/optionrom/Makefile"
|
|
LINKS="$LINKS pc-bios/s390-ccw/Makefile"
|
|
LINKS="$LINKS pc-bios/vof/Makefile"
|
|
LINKS="$LINKS .gdbinit scripts" # scripts needed by relative path in .gdbinit
|
|
LINKS="$LINKS tests/avocado tests/data"
|
|
LINKS="$LINKS tests/qemu-iotests/check"
|
|
LINKS="$LINKS python"
|
|
LINKS="$LINKS contrib/plugins/Makefile "
|
|
for f in $LINKS ; do
|
|
if [ -e "$source_path/$f" ]; then
|
|
mkdir -p "$(dirname ./"$f")"
|
|
symlink "$source_path/$f" "$f"
|
|
fi
|
|
done
|
|
|
|
echo "# Automatically generated by configure - do not modify" > Makefile.prereqs
|
|
|
|
# Mac OS X ships with a broken assembler
|
|
roms=
|
|
if have_target i386-softmmu x86_64-softmmu && \
|
|
test "$targetos" != "darwin" && test "$targetos" != "sunos" && \
|
|
test "$targetos" != "haiku" && \
|
|
probe_target_compiler i386-softmmu; then
|
|
roms="pc-bios/optionrom"
|
|
config_mak=pc-bios/optionrom/config.mak
|
|
echo "# Automatically generated by configure - do not modify" > $config_mak
|
|
echo "TOPSRC_DIR=$source_path" >> $config_mak
|
|
write_target_makefile >> $config_mak
|
|
fi
|
|
|
|
if have_target ppc-softmmu ppc64-softmmu && \
|
|
probe_target_compiler ppc-softmmu; then
|
|
roms="$roms pc-bios/vof"
|
|
config_mak=pc-bios/vof/config.mak
|
|
echo "# Automatically generated by configure - do not modify" > $config_mak
|
|
echo "SRC_DIR=$source_path/pc-bios/vof" >> $config_mak
|
|
write_target_makefile >> $config_mak
|
|
fi
|
|
|
|
# Only build s390-ccw bios if the compiler has -march=z900 or -march=z10
|
|
# (which is the lowest architecture level that Clang supports)
|
|
if have_target s390x-softmmu && probe_target_compiler s390x-softmmu; then
|
|
write_c_skeleton
|
|
do_compiler "$target_cc" $target_cc_cflags -march=z900 -o $TMPO -c $TMPC
|
|
has_z900=$?
|
|
if [ $has_z900 = 0 ] || do_compiler "$target_cc" $target_cc_cflags -march=z10 -msoft-float -Werror -o $TMPO -c $TMPC; then
|
|
if [ $has_z900 != 0 ]; then
|
|
echo "WARNING: Your compiler does not support the z900!"
|
|
echo " The s390-ccw bios will only work with guest CPUs >= z10."
|
|
fi
|
|
roms="$roms pc-bios/s390-ccw"
|
|
config_mak=pc-bios/s390-ccw/config-host.mak
|
|
echo "# Automatically generated by configure - do not modify" > $config_mak
|
|
echo "SRC_PATH=$source_path/pc-bios/s390-ccw" >> $config_mak
|
|
write_target_makefile >> $config_mak
|
|
# SLOF is required for building the s390-ccw firmware on s390x,
|
|
# since it is using the libnet code from SLOF for network booting.
|
|
git_submodules="${git_submodules} roms/SLOF"
|
|
fi
|
|
fi
|
|
|
|
#######################################
|
|
# generate config-host.mak
|
|
|
|
if ! (GIT="$git" "$source_path/scripts/git-submodule.sh" "$git_submodules_action" "$git_submodules"); then
|
|
exit 1
|
|
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_SUBMODULES_ACTION=$git_submodules_action" >> $config_host_mak
|
|
|
|
if test "$debug_tcg" = "yes" ; then
|
|
echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak
|
|
fi
|
|
if test "$mingw32" = "yes" ; then
|
|
echo "CONFIG_WIN32=y" >> $config_host_mak
|
|
echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER-QEMU}" >> $config_host_mak
|
|
echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO-Linux}" >> $config_host_mak
|
|
echo "QEMU_GA_VERSION=${QEMU_GA_VERSION-$(cat "$source_path"/VERSION)}" >> $config_host_mak
|
|
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 "$static" = "yes" ; then
|
|
echo "CONFIG_STATIC=y" >> $config_host_mak
|
|
fi
|
|
echo "SRC_PATH=$source_path" >> $config_host_mak
|
|
echo "TARGET_DIRS=$target_list" >> $config_host_mak
|
|
if test "$modules" = "yes"; then
|
|
echo "CONFIG_MODULES=y" >> $config_host_mak
|
|
fi
|
|
|
|
# XXX: suppress that
|
|
if [ "$bsd" = "yes" ] ; then
|
|
echo "CONFIG_BSD=y" >> $config_host_mak
|
|
fi
|
|
|
|
echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
|
|
|
|
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 "$plugins" = "yes" ; then
|
|
echo "CONFIG_PLUGIN=y" >> $config_host_mak
|
|
fi
|
|
|
|
if test -n "$gdb_bin"; then
|
|
gdb_version=$($gdb_bin --version | head -n 1)
|
|
if version_ge ${gdb_version##* } 9.1; then
|
|
echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
|
|
gdb_arches=$("$source_path/scripts/probe-gdb-support.py" $gdb_bin)
|
|
else
|
|
gdb_bin=""
|
|
fi
|
|
fi
|
|
|
|
if test "$container" != no; then
|
|
echo "ENGINE=$container" >> $config_host_mak
|
|
echo "RUNC=$runc" >> $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
|
|
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
|
|
echo "QEMU_OBJCFLAGS=$QEMU_OBJCFLAGS" >> $config_host_mak
|
|
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
|
|
echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
|
|
echo "GLIB_BINDIR=$glib_bindir" >> $config_host_mak
|
|
echo "GLIB_VERSION=$($pkg_config --modversion glib-2.0)" >> $config_host_mak
|
|
if test "$glib_has_gslice" = "yes" ; then
|
|
echo "HAVE_GLIB_WITH_SLICE_ALLOCATOR=y" >> $config_host_mak
|
|
fi
|
|
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
|
|
echo "EXESUF=$EXESUF" >> $config_host_mak
|
|
|
|
# use included Linux headers
|
|
if test "$linux" = "yes" ; then
|
|
mkdir -p linux-headers
|
|
case "$cpu" in
|
|
i386|x86_64)
|
|
linux_arch=x86
|
|
;;
|
|
ppc|ppc64)
|
|
linux_arch=powerpc
|
|
;;
|
|
s390x)
|
|
linux_arch=s390
|
|
;;
|
|
aarch64)
|
|
linux_arch=arm64
|
|
;;
|
|
loongarch*)
|
|
linux_arch=loongarch
|
|
;;
|
|
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)$EXESUF
|
|
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
|
|
|
|
if test "$default_targets" = "yes"; then
|
|
echo "CONFIG_DEFAULT_TARGETS=y" >> $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
|
|
|
|
# tests/tcg configuration
|
|
(config_host_mak=tests/tcg/config-host.mak
|
|
mkdir -p tests/tcg
|
|
echo "# Automatically generated by configure - do not modify" > $config_host_mak
|
|
echo "SRC_PATH=$source_path" >> $config_host_mak
|
|
echo "HOST_CC=$host_cc" >> $config_host_mak
|
|
|
|
# versioned checked in the main config_host.mak above
|
|
if test -n "$gdb_bin"; then
|
|
echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
|
|
fi
|
|
if test "$plugins" = "yes" ; then
|
|
echo "CONFIG_PLUGIN=y" >> $config_host_mak
|
|
fi
|
|
|
|
tcg_tests_targets=
|
|
for target in $target_list; do
|
|
arch=${target%%-*}
|
|
|
|
case $target in
|
|
xtensa*-linux-user)
|
|
# the toolchain is not complete with headers, only build softmmu tests
|
|
continue
|
|
;;
|
|
*-softmmu)
|
|
test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || continue
|
|
qemu="qemu-system-$arch"
|
|
;;
|
|
*-linux-user|*-bsd-user)
|
|
qemu="qemu-$arch"
|
|
;;
|
|
esac
|
|
|
|
if probe_target_compiler $target || test -n "$container_image"; then
|
|
test -n "$container_image" && build_static=y
|
|
mkdir -p "tests/tcg/$target"
|
|
config_target_mak=tests/tcg/$target/config-target.mak
|
|
ln -sf "$source_path/tests/tcg/Makefile.target" "tests/tcg/$target/Makefile"
|
|
echo "# Automatically generated by configure - do not modify" > "$config_target_mak"
|
|
echo "TARGET_NAME=$arch" >> "$config_target_mak"
|
|
echo "TARGET=$target" >> "$config_target_mak"
|
|
write_target_makefile "build-tcg-tests-$target" >> "$config_target_mak"
|
|
echo "BUILD_STATIC=$build_static" >> "$config_target_mak"
|
|
echo "QEMU=$PWD/$qemu" >> "$config_target_mak"
|
|
|
|
# will GDB work with these binaries?
|
|
if test "${gdb_arches#*$arch}" != "$gdb_arches"; then
|
|
echo "HOST_GDB_SUPPORTS_ARCH=y" >> "$config_target_mak"
|
|
fi
|
|
|
|
echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> Makefile.prereqs
|
|
tcg_tests_targets="$tcg_tests_targets $target"
|
|
fi
|
|
done
|
|
|
|
if test "$tcg" = "enabled"; then
|
|
echo "TCG_TESTS_TARGETS=$tcg_tests_targets" >> config-host.mak
|
|
fi
|
|
)
|
|
|
|
if test "$skip_meson" = no; then
|
|
cross="config-meson.cross.new"
|
|
meson_quote() {
|
|
test $# = 0 && return
|
|
echo "'$(echo $* | sed "s/ /','/g")'"
|
|
}
|
|
|
|
echo "# Automatically generated by configure - do not modify" > $cross
|
|
echo "[properties]" >> $cross
|
|
|
|
# unroll any custom device configs
|
|
for a in $device_archs; do
|
|
eval "c=\$devices_${a}"
|
|
echo "${a}-softmmu = '$c'" >> $cross
|
|
done
|
|
|
|
echo "[built-in options]" >> $cross
|
|
echo "c_args = [$(meson_quote $CFLAGS $EXTRA_CFLAGS)]" >> $cross
|
|
echo "cpp_args = [$(meson_quote $CXXFLAGS $EXTRA_CXXFLAGS)]" >> $cross
|
|
test -n "$objcc" && echo "objc_args = [$(meson_quote $OBJCFLAGS $EXTRA_OBJCFLAGS)]" >> $cross
|
|
echo "c_link_args = [$(meson_quote $CFLAGS $LDFLAGS $EXTRA_CFLAGS $EXTRA_LDFLAGS)]" >> $cross
|
|
echo "cpp_link_args = [$(meson_quote $CXXFLAGS $LDFLAGS $EXTRA_CXXFLAGS $EXTRA_LDFLAGS)]" >> $cross
|
|
echo "[binaries]" >> $cross
|
|
echo "c = [$(meson_quote $cc $CPU_CFLAGS)]" >> $cross
|
|
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx $CPU_CFLAGS)]" >> $cross
|
|
test -n "$objcc" && echo "objc = [$(meson_quote $objcc $CPU_CFLAGS)]" >> $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 "widl = [$(meson_quote $widl)]" >> $cross
|
|
echo "windres = [$(meson_quote $windres)]" >> $cross
|
|
echo "windmc = [$(meson_quote $windmc)]" >> $cross
|
|
if test "$cross_compile" = "yes"; then
|
|
cross_arg="--cross-file config-meson.cross"
|
|
echo "[host_machine]" >> $cross
|
|
echo "system = '$targetos'" >> $cross
|
|
case "$cpu" in
|
|
i386)
|
|
echo "cpu_family = 'x86'" >> $cross
|
|
;;
|
|
*)
|
|
echo "cpu_family = '$cpu'" >> $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
|
|
|
|
# Built-in options
|
|
test "$bindir" != "bin" && meson_option_add "-Dbindir=$bindir"
|
|
test "$default_feature" = no && meson_option_add -Dauto_features=disabled
|
|
test "$pie" = no && meson_option_add -Db_pie=false
|
|
test "$werror" = yes && meson_option_add -Dwerror=true
|
|
|
|
# QEMU options
|
|
test "$cfi" != false && meson_option_add "-Dcfi=$cfi"
|
|
test "$fdt" != auto && meson_option_add "-Dfdt=$fdt"
|
|
test -n "${LIB_FUZZING_ENGINE+xxx}" && meson_option_add "-Dfuzzing_engine=$LIB_FUZZING_ENGINE"
|
|
test "$qemu_suffix" != qemu && meson_option_add "-Dqemu_suffix=$qemu_suffix"
|
|
test "$smbd" != '' && meson_option_add "-Dsmbd=$smbd"
|
|
test "$tcg" != enabled && meson_option_add "-Dtcg=$tcg"
|
|
test "$vfio_user_server" != auto && meson_option_add "-Dvfio_user_server=$vfio_user_server"
|
|
run_meson() {
|
|
NINJA=$ninja $meson setup --prefix "$prefix" "$@" $cross_arg "$PWD" "$source_path"
|
|
}
|
|
eval run_meson $meson_options
|
|
if test "$?" -ne 0 ; then
|
|
error_exit "meson setup failed"
|
|
fi
|
|
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 CFLAGS
|
|
preserve_env CXX
|
|
preserve_env CXXFLAGS
|
|
preserve_env LD
|
|
preserve_env LDFLAGS
|
|
preserve_env LD_LIBRARY_PATH
|
|
preserve_env MAKE
|
|
preserve_env NM
|
|
preserve_env OBJCFLAGS
|
|
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 QEMU_GA_MANUFACTURER
|
|
preserve_env QEMU_GA_DISTRO
|
|
preserve_env QEMU_GA_VERSION
|
|
preserve_env SDL2_CONFIG
|
|
preserve_env SMBD
|
|
preserve_env STRIP
|
|
preserve_env WIDL
|
|
preserve_env WINDRES
|
|
preserve_env WINDMC
|
|
|
|
printf "exec" >>config.status
|
|
for i in "$0" "$@"; do
|
|
test "$i" = --skip-meson || printf " %s" "$(quote_sh "$i")" >>config.status
|
|
done
|
|
echo ' "$@"' >>config.status
|
|
chmod +x config.status
|
|
|
|
rm -r "$TMPDIR1"
|