Newer
Older

Paolo Bonzini
committed
default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],

Paolo Bonzini
committed
version: files('VERSION'))
add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
not_found = dependency('', required: false)

Paolo Bonzini
committed
keyval = import('keyval')
config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
cc = meson.get_compiler('c')
all_languages = ['c']
if targetos == 'windows' and add_languages('cpp', required: false, native: false)
all_languages += ['cpp']
cxx = meson.get_compiler('cpp')
endif
if targetos == 'darwin' and \
add_languages('objc', required: get_option('cocoa'), native: false)
all_languages += ['objc']
objc = meson.get_compiler('objc')
endif
# 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.)
tmpdir = meson.current_build_dir() / 'meson-private/temp'
if get_option('qemu_suffix').startswith('/')
error('qemu_suffix cannot start with a /')
endif
qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
qemu_desktopdir = get_option('datadir') / 'applications'
qemu_icondir = get_option('datadir') / 'icons'
config_host_data = configuration_data()
genh = []
qapi_trace_events = []
bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']

Philippe Mathieu-Daudé
committed
supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
cpu = host_machine.cpu_family()
target_dirs = config_host['TARGET_DIRS'].split()
have_linux_user = false
have_bsd_user = false
have_system = false
foreach target : target_dirs
have_linux_user = have_linux_user or target.endswith('linux-user')
have_bsd_user = have_bsd_user or target.endswith('bsd-user')
have_system = have_system or target.endswith('-softmmu')
endforeach
have_user = have_linux_user or have_bsd_user
have_tools = get_option('tools') \
.disable_auto_if(not have_system) \
.allowed()
have_ga = get_option('guest_agent') \
.disable_auto_if(not have_system and not have_tools) \
.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()
if cpu not in supported_cpus
host_arch = 'unknown'
elif cpu == 'x86'
host_arch = 'i386'
elif cpu == 'mips64'
host_arch = 'mips'

Philippe Mathieu-Daudé
committed
elif cpu in ['riscv32', 'riscv64']
host_arch = 'riscv'
else
host_arch = cpu
endif
if cpu in ['x86', 'x86_64']
kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
elif cpu == 'aarch64'
kvm_targets = ['aarch64-softmmu']
elif cpu == 's390x'
kvm_targets = ['s390x-softmmu']
elif cpu in ['ppc', 'ppc64']
kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
elif cpu in ['mips', 'mips64']
kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
elif cpu in ['riscv32']
kvm_targets = ['riscv32-softmmu']
elif cpu in ['riscv64']
kvm_targets = ['riscv64-softmmu']
else
kvm_targets = []
endif
kvm_targets_c = '""'
if get_option('kvm').allowed() and targetos == 'linux'

Igor Mammedov
committed
kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
endif
config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
accelerator_targets = { 'CONFIG_KVM': kvm_targets }
if cpu in ['aarch64']
accelerator_targets += {
'CONFIG_HVF': ['aarch64-softmmu']
}
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', 'aarch64-softmmu'],
if cpu in ['x86', 'x86_64']
accelerator_targets += {
'CONFIG_HVF': ['x86_64-softmmu'],
'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
}
endif
modular_tcg = []
# Darwin does not support references to thread-local variables in modules
if targetos != 'darwin'
modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
endif

Philippe Mathieu-Daudé
committed
edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
unpack_edk2_blobs = false
foreach target : edk2_targets
if target in target_dirs
bzip2 = find_program('bzip2', required: get_option('install_blobs'))
unpack_edk2_blobs = bzip2.found()
break
endif
endforeach
dtrace = not_found
stap = not_found
if 'dtrace' in get_option('trace_backends')
dtrace = find_program('dtrace', required: true)
stap = find_program('stap', required: false)
if stap.found()
# Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
# visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
# instead. QEMU --enable-modules depends on this because the SystemTap
# semaphores are linked into the main binary and not the module's shared
# object.
add_global_arguments('-DSTAP_SDT_V2',
native: false, language: all_languages)
if get_option('iasl') == ''
iasl = find_program('iasl', required: false)
else
iasl = find_program(get_option('iasl'), required: true)
endif
##################
# Compiler flags #
##################
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' ]
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.
if compiler.get_id() == 'gcc'
qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
endif
elif targetos == 'sunos'
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# 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
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')
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
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
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
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')
if targetos == 'windows'
qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
# 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
if get_option('fuzzing')
# Specify a filter to only instrument code that is directly related to
# virtual-devices.
configure_file(output: 'instrumentation-filter',
input: 'scripts/oss-fuzz/instrumentation-filter-template',
copy: true)
if cc.compiles('int main () { return 0; }',
name: '-fsanitize-coverage-allowlist=/dev/null',
args: ['-fsanitize-coverage-allowlist=/dev/null',
'-fsanitize-coverage=trace-pc'] )
qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
if get_option('fuzzing_engine') == ''
# Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
# 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.
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']
else
# LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
# the needed CFLAGS have already been provided
fuzz_exe_ldflags = get_option('fuzzing_engine').split()
endif
add_global_arguments(qemu_common_flags, native: false, language: all_languages)
add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# 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 = []
qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
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
if targetos == 'linux'
add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
'-isystem', 'linux-headers',
add_project_arguments('-iquote', '.',
'-iquote', meson.current_source_dir(),
'-iquote', meson.current_source_dir() / 'include',
# 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',
command: [find_program('scripts/check_sparse.py'),
'compile_commands.json', sparse.full_path(), '-Wbitwise',
'-Wno-transparent-union', '-Wno-old-initializer',
'-Wno-non-pointer-null'])
###########################################
# Target-specific checks and dependencies #
###########################################
if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
not cc.links('''
#include <stdint.h>
#include <sys/types.h>
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
''',
args: ['-Werror', '-fsanitize=fuzzer'])
error('Your compiler does not support -fsanitize=fuzzer')
endif
# Tracing backends
if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
error('ftrace is supported only on Linux')
endif
if 'syslog' in get_option('trace_backends') and not cc.compiles('''
#include <syslog.h>
int main(void) {
openlog("qemu", LOG_PID, LOG_DAEMON);
syslog(LOG_INFO, "configure");
return 0;
}''')
error('syslog is not supported on this system')
endif
# Miscellaneous Linux-only features
get_option('mpath') \
.require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
multiprocess_allowed = get_option('multiprocess') \
.require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
.allowed()
vfio_user_server_allowed = get_option('vfio_user_server') \
.require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
.allowed()
have_tpm = get_option('tpm') \
.require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
.allowed()
have_vhost_user = get_option('vhost_user') \
.disable_auto_if(targetos != 'linux') \
.require(targetos != 'windows',
error_message: 'vhost-user is not available on Windows').allowed()
have_vhost_vdpa = get_option('vhost_vdpa') \
.require(targetos == 'linux',
error_message: 'vhost-vdpa is only available on Linux').allowed()
have_vhost_kernel = get_option('vhost_kernel') \
.require(targetos == 'linux',
error_message: 'vhost-kernel is only available on Linux').allowed()
have_vhost_user_crypto = get_option('vhost_crypto') \
.require(have_vhost_user,
error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
# Target-specific libraries and flags
libm = cc.find_library('m', required: false)
threads = dependency('threads')
util = cc.find_library('util', required: false)
midl = not_found
widl = not_found
midl = find_program('midl', required: false)
widl = find_program('widl', required: false)
socket = cc.find_library('ws2_32')
win = import('windows')
version_res = win.compile_resources('version.rc',
depend_files: files('pc-bios/qemu-nsis.ico'),
include_directories: include_directories('.'))
elif targetos == 'darwin'
coref = dependency('appleframeworks', modules: 'CoreFoundation')
iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
host_dsosuf = '.dylib'
elif targetos == 'sunos'
socket = [cc.find_library('socket'),
cc.find_library('nsl'),
cc.find_library('resolv')]
elif targetos == 'haiku'
socket = [cc.find_library('posix_error_mapper'),
cc.find_library('network'),
cc.find_library('bsd')]
if get_option('tcg').allowed() and target_dirs.length() > 0
# Disable OpenBSD W^X if available
emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
endif
# Target-specific configuration of accelerators
if get_option('kvm').allowed() and targetos == 'linux'
accelerators += 'CONFIG_KVM'
endif
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'))
accelerators += 'CONFIG_WHPX'
endif
endif
if get_option('hvf').allowed()
hvf = dependency('appleframeworks', modules: 'Hypervisor',
required: get_option('hvf'))
if hvf.found()
accelerators += 'CONFIG_HVF'
endif
endif
if targetos == 'netbsd'
nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
if nvmm.found()
accelerators += 'CONFIG_NVMM'
endif
endif
if get_option('tcg').allowed()
if not get_option('tcg_interpreter')
error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
endif
elif get_option('tcg_interpreter')
warning('Use of the TCG interpreter is not recommended on this host')
warning('architecture. There is a native TCG execution backend available')
warning('which provides substantially better performance and reliability.')
warning('It is strongly recommended to remove the --enable-tcg-interpreter')
warning('configuration option on this architecture to use the native')
warning('backend.')
if get_option('tcg_interpreter')
tcg_arch = 'tci'
tcg_arch = 'ppc'
endif
add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
accelerators += 'CONFIG_TCG'
endif
if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
error('KVM not available on this platform')
endif
if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
error('HVF not available on this platform')
endif
if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
error('NVMM not available on this platform')
endif
if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
error('WHPX not available on this platform')
endif
################
# Dependencies #
################
# When bumping glib minimum version, please check also whether to increase
# the _WIN32_WINNT setting in osdep.h according to the value from glib
glib_req_ver = '>=2.56.0'
glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
method: 'pkg-config')
glib_cflags = []
gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
method: 'pkg-config')
elif get_option('plugins')
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
method: 'pkg-config')
else
gmodule = not_found
endif
# 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 targetos == 'windows' and get_option('prefer_static')
glib_cflags += ['-DGLIB_STATIC_COMPILATION']
endif
# 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
if not cc.compiles('''
#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;
}''', dependencies: glib_pc, args: glib_cflags)
error('''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.''')
endif
# Silence clang warnings triggered by glib < 2.57.2
if not cc.compiles('''
#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; }''', dependencies: glib_pc, args: ['-Wunused-function', '-Werror'])
glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
glib = declare_dependency(dependencies: [glib_pc, gmodule],
compile_args: glib_cflags,
version: glib_pc.version())
# 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 >= 2.75.3
glib_has_gslice = glib.version().version_compare('<2.75.3')
# override glib dep to include the above refinements
meson.override_dependency('glib-2.0', glib)
# The path to glib.h is added to all compilation commands.
add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
native: false, language: all_languages)
gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
if not get_option('gio').auto() or have_system
gio = dependency('gio-2.0', required: get_option('gio'),
if gio.found() and not cc.links('''
#include <gio/gio.h>
int main(void)
{
g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
return 0;
}''', dependencies: [glib, gio])
if get_option('gio').enabled()
error('The installed libgio is broken for static linking')
endif
gio = not_found
endif
if gio.found()
gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
required: get_option('gio'))
gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
gio = declare_dependency(dependencies: [gio, gio_unix],
version: gio.version())
endif
if gdbus_codegen.found() and get_option('cfi')
gdbus_codegen = not_found
gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
endif
xml_pp = find_program('scripts/xml-preprocess.py')
if 'ust' in get_option('trace_backends')
lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
if not get_option('pixman').auto() or have_system or have_tools
pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
libaio = not_found
if not get_option('linux_aio').auto() or have_block
libaio = cc.find_library('aio', has_headers: ['libaio.h'],
linux_io_uring_test = '''
#include <liburing.h>
#include <linux/errqueue.h>
int main(void) { return 0; }'''
if not get_option('linux_io_uring').auto() or have_block
linux_io_uring = dependency('liburing', version: '>=0.3',
required: get_option('linux_io_uring'),
if not cc.links(linux_io_uring_test)
linux_io_uring = not_found
endif
if not get_option('libnfs').auto() or have_block
libnfs = dependency('libnfs', version: '>=1.9.3',
required: get_option('libnfs'),
libattr_test = '''
#include <stddef.h>
#include <sys/types.h>
#ifdef CONFIG_LIBATTR
#include <attr/xattr.h>
#else
#include <sys/xattr.h>
#endif
int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
if get_option('attr').allowed()
if cc.links(libattr_test)
libattr = declare_dependency()
else
libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
if libattr.found() and not \
cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
libattr = not_found
if get_option('attr').enabled()
error('could not link libattr')
else
warning('could not link libattr, disabling')
endif
else
have_old_libattr = libattr.found()
endif
endif
cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
required: get_option('cocoa'))
vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
'VMNET_BRIDGED_MODE',
dependencies: vmnet)
vmnet = not_found
if get_option('vmnet').enabled()
error('vmnet.framework API is outdated')
else
warning('vmnet.framework API is outdated, disabling')
endif
endif
seccomp_has_sysrawrc = false
if not get_option('seccomp').auto() or have_system or have_tools
seccomp = dependency('libseccomp', version: '>=2.3.0',
required: get_option('seccomp'),
if seccomp.found()
seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
'SCMP_FLTATR_API_SYSRAWRC',
dependencies: seccomp)
endif
if not get_option('cap_ng').auto() or have_system or have_tools
libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
endif
if libcap_ng.found() and not cc.links('''
#include <cap-ng.h>
int main(void)
{
capng_capability_to_name(CAPNG_EFFECTIVE);
return 0;
}''', dependencies: libcap_ng)
libcap_ng = not_found
if get_option('cap_ng').enabled()
error('could not link libcap-ng')
else
warning('could not link libcap-ng, disabling')
endif
if get_option('xkbcommon').auto() and not have_system and not have_tools
xkbcommon = not_found
else
xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
slirp = not_found
if not get_option('slirp').auto() or have_system
slirp = dependency('slirp', required: get_option('slirp'),
# slirp < 4.7 is incompatible with CFI support in QEMU. This is because
# it passes function pointers within libslirp as callbacks for timers.
# When using a system-wide shared libslirp, the type information for the
# callback is missing and the timer call produces a false positive with CFI.
# Do not use the "version" keyword argument to produce a better error.
# with control-flow integrity.
if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
if get_option('slirp').enabled()
error('Control-Flow Integrity requires libslirp 4.7.')
else
warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
slirp = not_found
endif
endif
endif
if not get_option('vde').auto() or have_system or have_tools
vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
endif
if vde.found() and not cc.links('''
#include <libvdeplug.h>
int main(void)
{
struct vde_open_args a = {0, 0, 0};
char s[] = "";
vde_open(s, s, &a);
return 0;
}''', dependencies: vde)
vde = not_found
if get_option('cap_ng').enabled()
error('could not link libvdeplug')
else
warning('could not link libvdeplug, disabling')
endif
if not get_option('pa').auto() or (targetos == 'linux' and have_system)
pulse = dependency('libpulse', required: get_option('pa'),
if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
alsa = dependency('alsa', required: get_option('alsa'),
if not get_option('jack').auto() or have_system
jack = dependency('jack', required: get_option('jack'),
pipewire = not_found
if not get_option('pipewire').auto() or (targetos == 'linux' and have_system)
pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
required: get_option('pipewire'),