targetos = host_machine.system()
sh = find_program('sh')
config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
-enable_modules = 'CONFIG_MODULES' in config_host
cc = meson.get_compiler('c')
all_languages = ['c']
-if add_languages('cpp', required: false, native: false)
+if targetos == 'windows' and add_languages('cpp', required: false, native: false)
all_languages += ['cpp']
cxx = meson.get_compiler('cpp')
endif
bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
-supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
+supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
cpu = host_machine.cpu_family()
-# Unify riscv* to a single family.
-if cpu in ['riscv32', 'riscv64']
- cpu = 'riscv'
-endif
-
target_dirs = config_host['TARGET_DIRS'].split()
have_linux_user = false
have_bsd_user = false
.require(targetos in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
error_message: 'unsupported OS for QEMU guest agent') \
.allowed()
+enable_modules = get_option('modules') \
+ .require(targetos != 'windows',
+ error_message: 'Modules are not available for Windows') \
+ .require(not get_option('prefer_static'),
+ error_message: 'Modules are incompatible with static linking') \
+ .allowed()
have_block = have_system or have_tools
python = import('python').find_installation()
host_arch = 'i386'
elif cpu == 'mips64'
host_arch = 'mips'
+elif cpu in ['riscv32', 'riscv64']
+ host_arch = 'riscv'
else
host_arch = cpu
endif
kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
elif cpu in ['mips', 'mips64']
kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
-elif cpu in ['riscv']
- kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
+elif cpu in ['riscv32']
+ kvm_targets = ['riscv32-softmmu']
+elif cpu in ['riscv64']
+ kvm_targets = ['riscv64-softmmu']
else
kvm_targets = []
endif
if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
# i386 emulator provides xenpv machine type for multiple architectures
accelerator_targets += {
- 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
+ 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu'],
}
endif
if cpu in ['x86', 'x86_64']
# Compiler flags #
##################
-qemu_cflags = config_host['QEMU_CFLAGS'].split()
-qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
-qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
+foreach lang : all_languages
+ compiler = meson.get_compiler(lang)
+ if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
+ # ok
+ elif compiler.get_id() == 'clang' and compiler.compiles('''
+ #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''')
+ # ok
+ else
+ error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v12.0) to compile QEMU')
+ endif
+endforeach
+
+# 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_common_flags = [
+ '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
+ '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
+qemu_cflags = []
+qemu_ldflags = []
+
+if targetos == 'darwin'
+ # 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_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+elif targetos == 'solaris'
+ # needed for CMSG_ macros in sys/socket.h
+ qemu_common_flags += '-D_XOPEN_SOURCE=600'
+ # needed for TIOCWIN* defines in termios.h
+ qemu_common_flags += '-D__EXTENSIONS__'
+elif targetos == 'haiku'
+ qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
+endif
+
+# __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 host_arch == 'i386' and not cc.links('''
+ 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;
+ }''')
+ qemu_common_flags = ['-march=i486'] + qemu_common_flags
+endif
+
+if get_option('gprof')
+ qemu_common_flags += ['-p']
+ qemu_ldflags += ['-p']
+endif
if get_option('prefer_static')
qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
endif
+# Meson currently only handles pie as a boolean for now, so if the user
+# has explicitly disabled PIE we need to extend our cflags.
+#
+# -no-pie is supposedly a linker flag that has no effect on the compiler
+# command line, but some distros, that didn't quite know what they were
+# doing, made local changes to gcc's specs file that turned it into
+# a compiler command-line flag.
+#
+# What about linker flags? For a static build, no PIE is implied by -static
+# which we added above (and if it's not because of the same specs patching,
+# there's nothing we can do: compilation will fail, report a bug to your
+# distro and do not use --disable-pie in the meanwhile). For dynamic linking,
+# instead, we can't add -no-pie because it overrides -shared: the linker then
+# tries to build an executable instead of a shared library and fails. So
+# don't add -no-pie anywhere and cross fingers. :(
+if not get_option('b_pie')
+ qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
+endif
+
+if not get_option('stack_protector').disabled()
+ stack_protector_probe = '''
+ int main(int argc, char *argv[])
+ {
+ char arr[64], *p = arr, *c = argv[argc - 1];
+ while (*c) {
+ *p++ = *c++;
+ }
+ return 0;
+ }'''
+ have_stack_protector = false
+ foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
+ # 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 cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
+ cc.links(stack_protector_probe, args: ['-Werror', arg])
+ have_stack_protector = true
+ qemu_cflags += arg
+ qemu_ldflags += arg
+ break
+ endif
+ endforeach
+ get_option('stack_protector') \
+ .require(have_stack_protector, error_message: 'Stack protector not supported')
+endif
+
+coroutine_backend = get_option('coroutine_backend')
+ucontext_probe = '''
+ #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; }'''
+
+# On Windows the only valid backend is the Windows specific one.
+# For POSIX prefer ucontext, but it's not always possible. The fallback
+# is sigcontext.
+supported_backends = []
+if targetos == 'windows'
+ supported_backends += ['windows']
+else
+ if targetos != 'darwin' and cc.links(ucontext_probe)
+ supported_backends += ['ucontext']
+ endif
+ supported_backends += ['sigaltstack']
+endif
+
+if coroutine_backend == 'auto'
+ coroutine_backend = supported_backends[0]
+elif coroutine_backend not in supported_backends
+ error('"@0@" backend requested but not available. Available backends: @1@' \
+ .format(coroutine_backend, ', '.join(supported_backends)))
+endif
+
+# Compiles if SafeStack *not* enabled
+safe_stack_probe = '''
+ int main(void)
+ {
+ #if defined(__has_feature)
+ #if __has_feature(safe_stack)
+ #error SafeStack Enabled
+ #endif
+ #endif
+ return 0;
+ }'''
+if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
+ safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
+ if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
+ error(get_option('safe_stack') \
+ ? 'SafeStack not supported by your compiler' \
+ : 'Cannot disable SafeStack')
+ endif
+ qemu_cflags += safe_stack_arg
+ qemu_ldflags += safe_stack_arg
+endif
+if get_option('safe_stack') and coroutine_backend != 'ucontext'
+ error('SafeStack is only supported with the ucontext coroutine backend')
+endif
+
+if get_option('sanitizers')
+ if cc.has_argument('-fsanitize=address')
+ qemu_cflags = ['-fsanitize=address'] + qemu_cflags
+ qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
+ endif
+
+ # Detect static linking issue with ubsan - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
+ if cc.links('int main(int argc, char **argv) { return argc + 1; }',
+ args: [qemu_ldflags, '-fsanitize=undefined'])
+ qemu_cflags = ['-fsanitize=undefined'] + qemu_cflags
+ qemu_ldflags = ['-fsanitize=undefined'] + qemu_ldflags
+ endif
+endif
+
+# Thread sanitizer is, for now, much noisier than the other sanitizers;
+# keep it separate until that is not the case.
+if get_option('tsan')
+ if get_option('sanitizers')
+ error('TSAN is not supported with other sanitizers')
+ endif
+ if not cc.has_function('__tsan_create_fiber',
+ args: '-fsanitize=thread',
+ prefix: '#include <sanitizer/tsan_interface.h>')
+ error('Cannot enable TSAN due to missing fiber annotation interface')
+ endif
+ qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
+ qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
+endif
+
# Detect support for PT_GNU_RELRO + DT_BIND_NOW.
# The combination is known as "full relro", because .got.plt is read-only too.
qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
endif
-if get_option('gprof')
- qemu_cflags += ['-p']
- qemu_objcflags += ['-p']
- qemu_ldflags += ['-p']
+# Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
+if targetos != 'sunos' and not get_option('tsan')
+ qemu_ldflags += cc.get_supported_link_arguments('-Wl,--warn-common')
endif
-# Specify linker-script with add_project_link_arguments so that it is not placed
-# within a linker --start-group/--end-group pair
if get_option('fuzzing')
# Specify a filter to only instrument code that is directly related to
# virtual-devices.
name: '-fsanitize-coverage-allowlist=/dev/null',
args: ['-fsanitize-coverage-allowlist=/dev/null',
'-fsanitize-coverage=trace-pc'] )
- add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
- native: false, language: all_languages)
+ qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
endif
if get_option('fuzzing_engine') == ''
# compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
# everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
# unable to bind the fuzzer-related callbacks added by instrumentation.
- add_global_arguments('-fsanitize=fuzzer-no-link',
- native: false, language: all_languages)
- add_global_link_arguments('-fsanitize=fuzzer-no-link',
- native: false, language: all_languages)
+ qemu_common_flags += ['-fsanitize=fuzzer-no-link']
+ qemu_ldflags += ['-fsanitize=fuzzer-no-link']
# For the actual fuzzer binaries, we need to link against the libfuzzer
# library. They need to be configurable, to support OSS-Fuzz
fuzz_exe_ldflags = ['-fsanitize=fuzzer']
endif
endif
-# Check that the C++ compiler exists and works with the C compiler.
-link_language = 'c'
-linker = cc
+add_global_arguments(qemu_common_flags, native: false, language: all_languages)
+add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
+
+# Collect warnings that we want to enable
+
+warn_flags = [
+ '-Wundef',
+ '-Wwrite-strings',
+ '-Wmissing-prototypes',
+ '-Wstrict-prototypes',
+ '-Wredundant-decls',
+ '-Wold-style-declaration',
+ '-Wold-style-definition',
+ '-Wtype-limits',
+ '-Wformat-security',
+ '-Wformat-y2k',
+ '-Winit-self',
+ '-Wignored-qualifiers',
+ '-Wempty-body',
+ '-Wnested-externs',
+ '-Wendif-labels',
+ '-Wexpansion-to-defined',
+ '-Wimplicit-fallthrough=2',
+ '-Wmissing-format-attribute',
+ '-Wno-initializer-overrides',
+ '-Wno-missing-include-dirs',
+ '-Wno-shift-negative-value',
+ '-Wno-string-plus-int',
+ '-Wno-typedef-redefinition',
+ '-Wno-tautological-type-limit-compare',
+ '-Wno-psabi',
+ '-Wno-gnu-variable-sized-type-not-at-end',
+]
+
+if targetos != 'darwin'
+ warn_flags += ['-Wthread-safety']
+endif
+
+# Set up C++ compiler flags
qemu_cxxflags = []
if 'cpp' in all_languages
- add_global_arguments(['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'],
- native: false, language: 'cpp')
- foreach k: qemu_cflags
- if k not in ['-Wstrict-prototypes', '-Wmissing-prototypes', '-Wnested-externs',
- '-Wold-style-declaration', '-Wold-style-definition', '-Wredundant-decls']
- qemu_cxxflags += [k]
- endif
- endforeach
+ qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
+endif
- if cxx.links(files('scripts/main.c'), args: qemu_cflags)
- link_language = 'cpp'
- linker = cxx
- else
- message('C++ compiler does not work with C compiler')
- message('Disabling C++-specific optional code')
+# clang does not support glibc + FORTIFY_SOURCE (is it still true?)
+if get_option('optimization') != '0' and targetos == 'linux'
+ if cc.get_id() == 'gcc'
+ qemu_cflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
+ endif
+ if 'cpp' in all_languages and cxx.get_id() == 'gcc'
+ qemu_cxxflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
endif
endif
-# Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
-if targetos != 'sunos' and not config_host.has_key('CONFIG_TSAN')
- qemu_ldflags += linker.get_supported_link_arguments('-Wl,--warn-common')
+add_project_arguments(qemu_cflags, native: false, language: 'c')
+add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
+if 'cpp' in all_languages
+ add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
+ add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
+endif
+if 'objc' in all_languages
+ # Note sanitizer flags are not applied to Objective-C sources!
+ add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
endif
-
-add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
-
-add_global_arguments(qemu_cflags, native: false, language: 'c')
-add_global_arguments(qemu_cxxflags, native: false, language: 'cpp')
-add_global_arguments(qemu_objcflags, native: false, language: 'objc')
if targetos == 'linux'
add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
'-isystem', 'linux-headers',
'-iquote', meson.current_source_dir() / 'include',
language: all_languages)
+# If a host-specific include directory exists, list that first...
+host_include = meson.current_source_dir() / 'host/include/'
+if fs.is_dir(host_include / host_arch)
+ add_project_arguments('-iquote', host_include / host_arch,
+ language: all_languages)
+endif
+# ... followed by the generic fallback.
+add_project_arguments('-iquote', host_include / 'generic',
+ language: all_languages)
+
sparse = find_program('cgcc', required: get_option('sparse'))
if sparse.found()
run_target('sparse',
if get_option('whpx').allowed() and targetos == 'windows'
if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
error('WHPX requires 64-bit host')
- elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
- cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
+ elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
+ cc.has_header('winhvemulation.h', required: get_option('whpx'))
accelerators += 'CONFIG_WHPX'
endif
endif
glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
method: 'pkg-config')
glib_cflags = []
-if config_host.has_key('CONFIG_MODULES')
+if enable_modules
gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
method: 'pkg-config')
elif config_host.has_key('CONFIG_PLUGIN')
g_free(f);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
- int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Werror'])
+ int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Wunused-function', '-Werror'])
glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
endif
glib = declare_dependency(dependencies: [glib_pc, gmodule],
gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
endif
+xml_pp = find_program('scripts/xml-preprocess.py')
+
lttng = not_found
if 'ust' in get_option('trace_backends')
lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
virgl = dependency('virglrenderer',
method: 'pkg-config',
required: get_option('virglrenderer'))
+ if virgl.found()
+ config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
+ cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
+ prefix: '#include <virglrenderer.h>',
+ dependencies: virgl))
+ endif
endif
blkio = not_found
if not get_option('blkio').auto() or have_block
mpathlibs = [libudev]
mpathpersist = not_found
-mpathpersist_new_api = false
if targetos == 'linux' and have_tools and get_option('mpath').allowed()
- mpath_test_source_new = '''
+ mpath_test_source = '''
#include <libudev.h>
#include <mpath_persist.h>
unsigned mpath_mx_alloc_len = 1024;
multipath_conf = mpath_lib_init();
return 0;
}'''
- mpath_test_source_old = '''
- #include <libudev.h>
- #include <mpath_persist.h>
- unsigned mpath_mx_alloc_len = 1024;
- int logsink;
- int main(void) {
- struct udev *udev = udev_new();
- mpath_lib_init(udev);
- return 0;
- }'''
libmpathpersist = cc.find_library('mpathpersist',
required: get_option('mpath'))
if libmpathpersist.found()
endforeach
if mpathlibs.length() == 0
msg = 'Dependencies missing for libmpathpersist'
- elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
- mpathpersist = declare_dependency(dependencies: mpathlibs)
- mpathpersist_new_api = true
- elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
+ elif cc.links(mpath_test_source, dependencies: mpathlibs)
mpathpersist = declare_dependency(dependencies: mpathlibs)
else
msg = 'Cannot detect libmpathpersist API'
sdl_image = not_found
endif
if sdl.found()
- # work around 2.0.8 bug
- sdl = declare_dependency(compile_args: '-Wno-undef',
- dependencies: sdl,
- version: sdl.version())
+ # Some versions of SDL have problems with -Wundef
+ if not cc.compiles('''
+ #include <SDL.h>
+ #include <SDL_syswm.h>
+ int main(int argc, char *argv[]) { return 0; }
+ ''', dependencies: sdl, args: '-Werror=undef')
+ sdl = declare_dependency(compile_args: '-Wno-undef',
+ dependencies: sdl,
+ version: sdl.version())
+ endif
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
method: 'pkg-config')
else
snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
required: get_option('snappy'))
endif
-if snappy.found() and not linker.links('''
+if snappy.found() and not cc.links('''
#include <snappy-c.h>
int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
snappy = not_found
endif
endif
if not xen.found()
- xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1', '4.6.0', '4.5.0', '4.2.0' ]
+ xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
xen_libs = {
'4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
'4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
'4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
'4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
'4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
- '4.6.0': [ 'xenstore', 'xenctrl' ],
- '4.5.0': [ 'xenstore', 'xenctrl' ],
- '4.2.0': [ 'xenstore', 'xenctrl' ],
}
xen_deps = {}
foreach ver: xen_tests
error_message: 'Xen PCI passthrough requested but Xen not enabled') \
.require(targetos == 'linux',
error_message: 'Xen PCI passthrough not available on this platform') \
+ .require(cpu == 'x86' or cpu == 'x86_64',
+ error_message: 'Xen PCI passthrough not available on this platform') \
.allowed()
tasn1 = dependency('libtasn1',
method: 'pkg-config')
endif
-keyutils = dependency('libkeyutils', required: false,
- method: 'pkg-config')
+keyutils = not_found
+if get_option('keyring').enabled()
+ keyutils = dependency('libkeyutils', required: false, method: 'pkg-config')
+endif
has_gettid = cc.has_function('gettid')
if get_option('malloc') == 'system'
has_malloc_trim = \
get_option('malloc_trim').allowed() and \
- cc.links('''#include <malloc.h>
- int main(void) { malloc_trim(0); return 0; }''')
+ cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
else
has_malloc_trim = false
malloc = cc.find_library(get_option('malloc'), required: true)
endif
endif
-# Check whether the glibc provides statx()
-
gnu_source_prefix = '''
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
'''
-statx_test = gnu_source_prefix + '''
- #include <sys/stat.h>
- int main(void) {
- struct statx statxbuf;
- statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
- return 0;
- }'''
-has_statx = cc.links(statx_test)
+# Check whether the glibc provides STATX_BASIC_STATS
-# Check whether statx() provides mount ID information
+has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
-statx_mnt_id_test = gnu_source_prefix + '''
- #include <sys/stat.h>
- int main(void) {
- struct statx statxbuf;
- statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
- return statxbuf.stx_mnt_id;
- }'''
+# Check whether statx() provides mount ID information
-has_statx_mnt_id = cc.links(statx_mnt_id_test)
+has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
.require(targetos == 'linux',
if not get_option('b_lto')
error('Selected Control-Flow Integrity but LTO is disabled')
endif
- if config_host.has_key('CONFIG_MODULES')
+ if enable_modules
error('Selected Control-Flow Integrity is not compatible with modules')
endif
# Check for cfi flags. CFI requires LTO so we can't use
error_message: '-display dbus requires glib>=2.64') \
.require(gdbus_codegen.found(),
error_message: gdbus_codegen_error.format('-display dbus')) \
- .require(targetos != 'windows',
- error_message: '-display dbus is not available on Windows') \
.allowed()
have_virtfs = get_option('virtfs') \
config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
-if config_host.has_key('CONFIG_MODULES')
+if enable_modules
config_host_data.set('CONFIG_STAMP', run_command(
meson.current_source_dir() / 'scripts/qemu-stamp.py',
meson.project_version(), get_option('pkgversion'), '--',
config_host_data.set('CONFIG_LIBUDEV', libudev.found())
config_host_data.set('CONFIG_LZO', lzo.found())
config_host_data.set('CONFIG_MPATH', mpathpersist.found())
-config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
config_host_data.set('CONFIG_BLKIO', blkio.found())
+if blkio.found()
+ config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
+ blkio.version().version_compare('>=1.3.0'))
+endif
config_host_data.set('CONFIG_CURL', curl.found())
config_host_data.set('CONFIG_CURSES', curses.found())
config_host_data.set('CONFIG_GBM', gbm.found())
config_host_data.set('CONFIG_GTK', gtk.found())
config_host_data.set('CONFIG_VTE', vte.found())
config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
+config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
config_host_data.set('CONFIG_EBPF', libbpf.found())
config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
+config_host_data.set('CONFIG_MODULES', enable_modules)
config_host_data.set('CONFIG_NUMA', numa.found())
if numa.found()
config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
dependencies: numa))
endif
config_host_data.set('CONFIG_OPENGL', opengl.found())
-config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
config_host_data.set('CONFIG_RBD', rbd.found())
config_host_data.set('CONFIG_RDMA', rdma.found())
+config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
config_host_data.set('CONFIG_SDL', sdl.found())
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
config_host_data.set('CONFIG_SECCOMP', seccomp.found())
endif
config_host_data.set('CONFIG_SNAPPY', snappy.found())
config_host_data.set('CONFIG_TPM', have_tpm)
+config_host_data.set('CONFIG_TSAN', get_option('tsan'))
config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
config_host_data.set('CONFIG_VDE', vde.found())
config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
+config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
+config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
# Note that we need to specify prefix: here to avoid incorrectly
# thinking that Windows has posix_memalign()
config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
prefix: '#include <infiniband/verbs.h>'))
endif
+have_asan_fiber = false
+if get_option('sanitizers') and \
+ not cc.has_function('__sanitizer_start_switch_fiber',
+ args: '-fsanitize=address',
+ prefix: '#include <sanitizer/asan_interface.h>')
+ warning('Missing ASAN due to missing fiber annotation interface')
+ warning('Without code annotation, the report may be inferior.')
+else
+ have_asan_fiber = true
+endif
+config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
+
# has_header_symbol
config_host_data.set('CONFIG_BLKZONED',
cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
return 0;
}'''))
-has_int128 = cc.links('''
+has_int128_type = cc.compiles('''
+ __int128_t a;
+ __uint128_t b;
+ int main(void) { b = a; }''')
+config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
+
+has_int128 = has_int128_type and cc.links('''
__int128_t a;
__uint128_t b;
int main (void) {
a = a * a;
return 0;
}''')
-
config_host_data.set('CONFIG_INT128', has_int128)
-if has_int128
+if has_int128_type
# "do we have 128-bit atomics which are handled inline and specifically not
# via libatomic". The reason we can't use libatomic is documented in the
# comment starting "GCC is a house divided" in include/qemu/atomic128.h.
# __alignof(unsigned __int128) for the host.
atomic_test_128 = '''
int main(int ac, char **av) {
- unsigned __int128 *p = __builtin_assume_aligned(av[ac - 1], sizeof(16));
+ __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
__atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
__atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
int main(void)
{
- unsigned __int128 x = 0, y = 0;
+ __uint128_t x = 0, y = 0;
__sync_val_compare_and_swap_16(&x, y, x);
return 0;
}
int main(int argc, char *argv[]) { return bar(argv[0]); }
'''), error_message: 'AVX512BW not available').allowed())
+# For both AArch64 and AArch32, detect if builtins are available.
+config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
+ #include <arm_neon.h>
+ #ifndef __ARM_FEATURE_AES
+ __attribute__((target("+crypto")))
+ #endif
+ void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
+ '''))
+
have_pvrdma = get_option('pvrdma') \
.require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
.require(cc.compiles(gnu_source_prefix + '''
have_vss = false
have_vss_sdk = false # old xp/2003 SDK
-if targetos == 'windows' and link_language == 'cpp'
+if targetos == 'windows' and 'cpp' in all_languages
have_vss = cxx.compiles('''
#define __MIDL_user_allocate_free_DEFINED__
#include <vss.h>
endif
config_target += { 'CONFIG_BSD_USER': 'y' }
elif target.endswith('softmmu')
+ config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
config_target += { 'CONFIG_SOFTMMU': 'y' }
endif
if target.endswith('-user')
config_all += config_all_disas
config_all += {
'CONFIG_XEN': xen.found(),
- 'CONFIG_SOFTMMU': have_system,
+ 'CONFIG_SYSTEM_ONLY': have_system,
'CONFIG_USER_ONLY': have_user,
'CONFIG_ALL': true,
}
libvfio_user_dep = not_found
if have_system and vfio_user_server_allowed
- have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
-
- if not have_internal
- error('libvfio-user source not found - please pull git submodule')
- endif
-
- libvfio_user_proj = subproject('libvfio-user')
-
+ libvfio_user_proj = subproject('libvfio-user', required: true)
libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
endif
fdt = not_found
-if have_system
- fdt_opt = get_option('fdt')
+fdt_opt = get_option('fdt')
+if fdt_required.length() > 0 or fdt_opt == 'enabled'
+ if fdt_opt == 'disabled'
+ error('fdt disabled but required by targets ' + ', '.join(fdt_required))
+ endif
+
if fdt_opt in ['enabled', 'auto', 'system']
- have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
- fdt = cc.find_library('fdt',
- required: fdt_opt == 'system' or
- fdt_opt == 'enabled' and not have_internal)
+ fdt = cc.find_library('fdt', required: fdt_opt == 'system')
if fdt.found() and cc.links('''
#include <libfdt.h>
#include <libfdt_env.h>
fdt_opt = 'system'
elif fdt_opt == 'system'
error('system libfdt requested, but it is too old (1.5.1 or newer required)')
- elif have_internal
- fdt_opt = 'internal'
else
- fdt_opt = 'disabled'
+ fdt_opt = 'internal'
fdt = not_found
endif
endif
- if fdt_opt == 'internal'
- fdt_files = files(
- 'dtc/libfdt/fdt.c',
- 'dtc/libfdt/fdt_ro.c',
- 'dtc/libfdt/fdt_wip.c',
- 'dtc/libfdt/fdt_sw.c',
- 'dtc/libfdt/fdt_rw.c',
- 'dtc/libfdt/fdt_strerror.c',
- 'dtc/libfdt/fdt_empty_tree.c',
- 'dtc/libfdt/fdt_addresses.c',
- 'dtc/libfdt/fdt_overlay.c',
- 'dtc/libfdt/fdt_check.c',
- )
-
- fdt_inc = include_directories('dtc/libfdt')
- libfdt = static_library('fdt',
- build_by_default: false,
- sources: fdt_files,
- include_directories: fdt_inc)
- fdt = declare_dependency(link_with: libfdt,
- include_directories: fdt_inc)
+ if not fdt.found()
+ assert(fdt_opt == 'internal')
+ libfdt_proj = subproject('dtc', required: true,
+ default_options: ['tools=false', 'yaml=disabled',
+ 'python=disabled', 'default_library=static'])
+ fdt = libfdt_proj.get_variable('libfdt_dep')
endif
else
fdt_opt = 'disabled'
endif
-if not fdt.found() and fdt_required.length() > 0
- error('fdt not available but required by targets ' + ', '.join(fdt_required))
-endif
config_host_data.set('CONFIG_CAPSTONE', capstone.found())
config_host_data.set('CONFIG_FDT', fdt.found())
io_ss = ss.source_set()
qmp_ss = ss.source_set()
qom_ss = ss.source_set()
-softmmu_ss = ss.source_set()
+system_ss = ss.source_set()
specific_fuzz_ss = ss.source_set()
specific_ss = ss.source_set()
stub_ss = ss.source_set()
# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
# os-win32.c does not
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
- softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
+ system_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
endif
common_ss.add(files('cpus-common.c'))
endif
foreach m, module_ss : list
- if enable_modules and targetos != 'windows'
+ if enable_modules
module_ss = module_ss.apply(config_all, strict: false)
sl = static_library(d + '-' + m, [genh, module_ss.sources()],
dependencies: [modulecommon, module_ss.dependencies()], pic: true)
if d == 'block'
block_ss.add_all(module_ss)
else
- softmmu_ss.add_all(module_ss)
+ system_ss.add_all(module_ss)
endif
endif
endforeach
foreach d, list : target_modules
foreach m, module_ss : list
- if enable_modules and targetos != 'windows'
+ if enable_modules
foreach target : target_dirs
if target.endswith('-softmmu')
config_target = config_target_mak[target]
build_by_default: false)
migration = declare_dependency(link_with: libmigration,
dependencies: [zlib, qom, io])
-softmmu_ss.add(migration)
+system_ss.add(migration)
block_ss = block_ss.apply(config_host, strict: false)
libblock = static_library('block', block_ss.sources() + genh,
alias_target('modules', emulator_modules)
endif
-softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
+system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
common_ss.add(qom, qemuutil)
-common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
+common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
common_all = common_ss.apply(config_all, strict: false)
c_args: c_args,
dependencies: arch_deps + deps + exe['dependencies'],
objects: lib.extract_all_objects(recursive: true),
- link_language: link_language,
link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
link_args: link_args,
win_subsystem: exe['win_subsystem'])
# Configuration summary #
#########################
-# Directories
+# Build environment
summary_info = {}
+summary_info += {'Build directory': meson.current_build_dir()}
+summary_info += {'Source path': meson.current_source_dir()}
+summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
+summary(summary_info, bool_yn: true, section: 'Build environment')
+
+# Directories
summary_info += {'Install prefix': get_option('prefix')}
summary_info += {'BIOS directory': qemu_datadir}
pathsep = targetos == 'windows' ? ';' : ':'
summary_info += {'local state directory': 'queried at runtime'}
endif
summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
-summary_info += {'Build directory': meson.current_build_dir()}
-summary_info += {'Source path': meson.current_source_dir()}
-summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
summary(summary_info, bool_yn: true, section: 'Directories')
# Host binaries
summary_info = {}
-summary_info += {'git': config_host['GIT']}
-summary_info += {'make': config_host['MAKE']}
summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
summary_info += {'sphinx-build': sphinx_build}
if config_host.has_key('HAVE_GDB_BIN')
summary_info += {'user-mode emulation': have_user}
summary_info += {'block layer': have_block}
summary_info += {'Install blobs': get_option('install_blobs')}
-summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
-if config_host.has_key('CONFIG_MODULES')
+summary_info += {'module support': enable_modules}
+if enable_modules
summary_info += {'alternative module path': get_option('module_upgrades')}
endif
summary_info += {'fuzzing support': get_option('fuzzing')}
summary_info += {'host endianness': build_machine.endian()}
summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
-if link_language == 'cpp'
+if 'cpp' in all_languages
summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
else
summary_info += {'C++ compiler': false}
option_cflags += ['-O' + get_option('optimization')]
endif
summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
-if link_language == 'cpp'
+if 'cpp' in all_languages
summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
endif
if targetos == 'darwin'
summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
endif
-link_args = get_option(link_language + '_link_args')
+link_args = get_option('c_link_args')
if link_args.length() > 0
summary_info += {'LDFLAGS': ' '.join(link_args)}
endif
-summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
+summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
if 'cpp' in all_languages
- summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
+ summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
endif
if 'objc' in all_languages
- summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
+ summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
endif
summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
-summary_info += {'profiler': get_option('profiler')}
summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
summary_info += {'PIE': get_option('b_pie')}
-summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
+summary_info += {'static build': get_option('prefer_static')}
summary_info += {'malloc trim support': has_malloc_trim}
summary_info += {'membarrier': have_membarrier}
summary_info += {'debug graph lock': get_option('debug_graph_lock')}
endif
summary_info += {'gprof': gprof_info}
summary_info += {'gcov': get_option('b_coverage')}
-summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
+summary_info += {'thread sanitizer': get_option('tsan')}
summary_info += {'CFI support': get_option('cfi')}
if get_option('cfi')
summary_info += {'CFI debug support': get_option('cfi_debug')}
# Block layer
summary_info = {}
-summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
+summary_info += {'coroutine backend': coroutine_backend}
summary_info += {'coroutine pool': have_coroutine_pool}
if have_block
summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
summary_info += {'VirtFS (9P) support': have_virtfs}
- summary_info += {'VirtFS (9P) Proxy Helper support': have_virtfs_proxy_helper}
+ summary_info += {'VirtFS (9P) Proxy Helper support (deprecated)': have_virtfs_proxy_helper}
summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
summary_info += {'bochs support': get_option('bochs').allowed()}
summary_info += {'Linux keyring': have_keyring}
summary(summary_info, bool_yn: true, section: 'Crypto')
-# Libraries
+# UI
summary_info = {}
if targetos == 'darwin'
summary_info += {'Cocoa support': cocoa}
- summary_info += {'vmnet.framework support': vmnet}
endif
summary_info += {'SDL support': sdl}
summary_info += {'SDL image support': sdl_image}
summary_info += {'GTK support': gtk}
summary_info += {'pixman': pixman}
summary_info += {'VTE support': vte}
-summary_info += {'slirp support': slirp}
-summary_info += {'libtasn1': tasn1}
-summary_info += {'PAM': pam}
-summary_info += {'iconv support': iconv}
-summary_info += {'curses support': curses}
-summary_info += {'virgl support': virgl}
-summary_info += {'blkio support': blkio}
-summary_info += {'curl support': curl}
-summary_info += {'Multipath support': mpathpersist}
summary_info += {'PNG support': png}
summary_info += {'VNC support': vnc}
if vnc.found()
summary_info += {'VNC SASL support': sasl}
summary_info += {'VNC JPEG support': jpeg}
endif
+summary_info += {'spice protocol support': spice_protocol}
+if spice_protocol.found()
+ summary_info += {' spice server support': spice}
+endif
+summary_info += {'curses support': curses}
+summary_info += {'brlapi support': brlapi}
+summary(summary_info, bool_yn: true, section: 'User interface')
+
+# Audio backends
+summary_info = {}
if targetos not in ['darwin', 'haiku', 'windows']
summary_info += {'OSS support': oss}
summary_info += {'sndio support': sndio}
summary_info += {'ALSA support': alsa}
summary_info += {'PulseAudio support': pulse}
endif
-summary_info += {'Pipewire support': pipewire}
+summary_info += {'Pipewire support': pipewire}
summary_info += {'JACK support': jack}
-summary_info += {'brlapi support': brlapi}
+summary(summary_info, bool_yn: true, section: 'Audio backends')
+
+# Network backends
+summary_info = {}
+if targetos == 'darwin'
+ summary_info += {'vmnet.framework support': vmnet}
+endif
+summary_info += {'slirp support': slirp}
summary_info += {'vde support': vde}
summary_info += {'netmap support': have_netmap}
summary_info += {'l2tpv3 support': have_l2tpv3}
+summary(summary_info, bool_yn: true, section: 'Network backends')
+
+# Libraries
+summary_info = {}
+summary_info += {'libtasn1': tasn1}
+summary_info += {'PAM': pam}
+summary_info += {'iconv support': iconv}
+summary_info += {'virgl support': virgl}
+summary_info += {'blkio support': blkio}
+summary_info += {'curl support': curl}
+summary_info += {'Multipath support': mpathpersist}
summary_info += {'Linux AIO support': libaio}
summary_info += {'Linux io_uring support': linux_io_uring}
summary_info += {'ATTR/XATTR support': libattr}
summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
summary_info += {'libcap-ng support': libcap_ng}
summary_info += {'bpf support': libbpf}
-summary_info += {'spice protocol support': spice_protocol}
-if spice_protocol.found()
- summary_info += {' spice server support': spice}
-endif
summary_info += {'rbd support': rbd}
summary_info += {'smartcard support': cacard}
summary_info += {'U2F support': u2f}