scripts/nsis.py: Automatically package required DLLs of QEMU executables
[qemu/ar7.git] / meson.build
blobd0a186e7f5e685f913b985a007e062e6cc21bd1d
1 project('qemu', ['c'], meson_version: '>=0.61.3',
2         default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3                           'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
4         version: files('VERSION'))
6 add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
7 add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8 add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
10 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
12 not_found = dependency('', required: false)
13 keyval = import('keyval')
14 ss = import('sourceset')
15 fs = import('fs')
17 sh = find_program('sh')
18 cc = meson.get_compiler('c')
19 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
20 enable_modules = 'CONFIG_MODULES' in config_host
21 enable_static = 'CONFIG_STATIC' in config_host
23 # Allow both shared and static libraries unless --enable-static
24 static_kwargs = enable_static ? {'static': true} : {}
26 # Temporary directory used for files created while
27 # configure runs. Since it is in the build directory
28 # we can safely blow away any previous version of it
29 # (and we need not jump through hoops to try to delete
30 # it when configure exits.)
31 tmpdir = meson.current_build_dir() / 'meson-private/temp'
33 if get_option('qemu_suffix').startswith('/')
34   error('qemu_suffix cannot start with a /')
35 endif
37 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
38 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
39 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
40 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
42 qemu_desktopdir = get_option('datadir') / 'applications'
43 qemu_icondir = get_option('datadir') / 'icons'
45 config_host_data = configuration_data()
46 genh = []
47 qapi_trace_events = []
49 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
50 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
51 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
52   'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
54 cpu = host_machine.cpu_family()
56 # Unify riscv* to a single family.
57 if cpu in ['riscv32', 'riscv64']
58   cpu = 'riscv'
59 endif
61 targetos = host_machine.system()
63 target_dirs = config_host['TARGET_DIRS'].split()
64 have_linux_user = false
65 have_bsd_user = false
66 have_system = false
67 foreach target : target_dirs
68   have_linux_user = have_linux_user or target.endswith('linux-user')
69   have_bsd_user = have_bsd_user or target.endswith('bsd-user')
70   have_system = have_system or target.endswith('-softmmu')
71 endforeach
72 have_user = have_linux_user or have_bsd_user
73 have_tools = get_option('tools') \
74   .disable_auto_if(not have_system) \
75   .allowed()
76 have_ga = get_option('guest_agent') \
77   .disable_auto_if(not have_system and not have_tools) \
78   .require(targetos in ['sunos', 'linux', 'windows', 'freebsd'],
79            error_message: 'unsupported OS for QEMU guest agent') \
80   .allowed()
81 have_block = have_system or have_tools
83 python = import('python').find_installation()
85 if cpu not in supported_cpus
86   host_arch = 'unknown'
87 elif cpu == 'x86'
88   host_arch = 'i386'
89 elif cpu == 'mips64'
90   host_arch = 'mips'
91 else
92   host_arch = cpu
93 endif
95 if cpu in ['x86', 'x86_64']
96   kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
97 elif cpu == 'aarch64'
98   kvm_targets = ['aarch64-softmmu']
99 elif cpu == 's390x'
100   kvm_targets = ['s390x-softmmu']
101 elif cpu in ['ppc', 'ppc64']
102   kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
103 elif cpu in ['mips', 'mips64']
104   kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
105 elif cpu in ['riscv']
106   kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
107 else
108   kvm_targets = []
109 endif
111 kvm_targets_c = '""'
112 if get_option('kvm').allowed() and targetos == 'linux'
113   kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
114 endif
115 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
117 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
119 if cpu in ['aarch64']
120   accelerator_targets += {
121     'CONFIG_HVF': ['aarch64-softmmu']
122   }
123 endif
125 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
126   # i386 emulator provides xenpv machine type for multiple architectures
127   accelerator_targets += {
128     'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
129   }
130 endif
131 if cpu in ['x86', 'x86_64']
132   accelerator_targets += {
133     'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
134     'CONFIG_HVF': ['x86_64-softmmu'],
135     'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
136     'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
137   }
138 endif
140 modular_tcg = []
141 # Darwin does not support references to thread-local variables in modules
142 if targetos != 'darwin'
143   modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
144 endif
146 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
147 unpack_edk2_blobs = false
148 foreach target : edk2_targets
149   if target in target_dirs
150     bzip2 = find_program('bzip2', required: get_option('install_blobs'))
151     unpack_edk2_blobs = bzip2.found()
152     break
153   endif
154 endforeach
156 dtrace = not_found
157 stap = not_found
158 if 'dtrace' in get_option('trace_backends')
159   dtrace = find_program('dtrace', required: true)
160   stap = find_program('stap', required: false)
161   if stap.found()
162     # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
163     # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
164     # instead. QEMU --enable-modules depends on this because the SystemTap
165     # semaphores are linked into the main binary and not the module's shared
166     # object.
167     add_global_arguments('-DSTAP_SDT_V2',
168                          native: false, language: ['c', 'cpp', 'objc'])
169   endif
170 endif
172 if get_option('iasl') == ''
173   iasl = find_program('iasl', required: false)
174 else
175   iasl = find_program(get_option('iasl'), required: true)
176 endif
178 ##################
179 # Compiler flags #
180 ##################
182 qemu_cflags = config_host['QEMU_CFLAGS'].split()
183 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
184 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
186 if enable_static
187   qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
188 endif
190 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
191 # The combination is known as "full relro", because .got.plt is read-only too.
192 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
194 if targetos == 'windows'
195   qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
196   # Disable ASLR for debug builds to allow debugging with gdb
197   if get_option('optimization') == '0'
198     qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase')
199   endif
200 endif
202 if get_option('gprof')
203   qemu_cflags += ['-p']
204   qemu_objcflags += ['-p']
205   qemu_ldflags += ['-p']
206 endif
208 # Specify linker-script with add_project_link_arguments so that it is not placed
209 # within a linker --start-group/--end-group pair
210 if get_option('fuzzing')
211   add_project_link_arguments(['-Wl,-T,',
212                               (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
213                              native: false, language: ['c', 'cpp', 'objc'])
215   # Specify a filter to only instrument code that is directly related to
216   # virtual-devices.
217   configure_file(output: 'instrumentation-filter',
218                  input: 'scripts/oss-fuzz/instrumentation-filter-template',
219                  copy: true)
221   if cc.compiles('int main () { return 0; }',
222                   name: '-fsanitize-coverage-allowlist=/dev/null',
223                  args: ['-fsanitize-coverage-allowlist=/dev/null',
224                         '-fsanitize-coverage=trace-pc'] )
225     add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
226                          native: false, language: ['c', 'cpp', 'objc'])
227   endif
229   if get_option('fuzzing_engine') == ''
230     # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
231     # compiled code.  To build non-fuzzer binaries with --enable-fuzzing, link
232     # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
233     # unable to bind the fuzzer-related callbacks added by instrumentation.
234     add_global_arguments('-fsanitize=fuzzer-no-link',
235                          native: false, language: ['c', 'cpp', 'objc'])
236     add_global_link_arguments('-fsanitize=fuzzer-no-link',
237                               native: false, language: ['c', 'cpp', 'objc'])
238     # For the actual fuzzer binaries, we need to link against the libfuzzer
239     # library. They need to be configurable, to support OSS-Fuzz
240     fuzz_exe_ldflags = ['-fsanitize=fuzzer']
241   else
242     # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
243     # the needed CFLAGS have already been provided
244     fuzz_exe_ldflags = get_option('fuzzing_engine').split()
245   endif
246 endif
248 add_global_arguments(qemu_cflags, native: false, language: ['c'])
249 add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
251 # Check that the C++ compiler exists and works with the C compiler.
252 link_language = 'c'
253 linker = cc
254 qemu_cxxflags = []
255 if add_languages('cpp', required: false, native: false)
256   cxx = meson.get_compiler('cpp')
257   add_global_arguments(['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'],
258                        native: false, language: 'cpp')
259   foreach k: qemu_cflags
260     if k not in ['-Wstrict-prototypes', '-Wmissing-prototypes', '-Wnested-externs',
261                  '-Wold-style-declaration', '-Wold-style-definition', '-Wredundant-decls']
262       qemu_cxxflags += [k]
263     endif
264   endforeach
265   add_global_arguments(qemu_cxxflags, native: false, language: 'cpp')
267   if cxx.links(files('scripts/main.c'), args: qemu_cflags)
268     link_language = 'cpp'
269     linker = cxx
270   else
271     message('C++ compiler does not work with C compiler')
272     message('Disabling C++-specific optional code')
273   endif
274 endif
276 # Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
277 if targetos != 'sunos' and not config_host.has_key('CONFIG_TSAN')
278   qemu_ldflags += linker.get_supported_link_arguments('-Wl,--warn-common')
279 endif
281 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
283 if targetos == 'linux'
284   add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
285                         '-isystem', 'linux-headers',
286                         language: ['c', 'cpp'])
287 endif
289 add_project_arguments('-iquote', '.',
290                       '-iquote', meson.current_source_dir(),
291                       '-iquote', meson.current_source_dir() / 'include',
292                       language: ['c', 'cpp', 'objc'])
294 if host_machine.system() == 'darwin'
295   add_languages('objc', required: false, native: false)
296 endif
298 sparse = find_program('cgcc', required: get_option('sparse'))
299 if sparse.found()
300   run_target('sparse',
301              command: [find_program('scripts/check_sparse.py'),
302                        'compile_commands.json', sparse.full_path(), '-Wbitwise',
303                        '-Wno-transparent-union', '-Wno-old-initializer',
304                        '-Wno-non-pointer-null'])
305 endif
307 ###########################################
308 # Target-specific checks and dependencies #
309 ###########################################
311 # Fuzzing
312 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
313     not cc.links('''
314           #include <stdint.h>
315           #include <sys/types.h>
316           int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
317           int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
318         ''',
319         args: ['-Werror', '-fsanitize=fuzzer'])
320   error('Your compiler does not support -fsanitize=fuzzer')
321 endif
323 # Tracing backends
324 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
325   error('ftrace is supported only on Linux')
326 endif
327 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
328     #include <syslog.h>
329     int main(void) {
330         openlog("qemu", LOG_PID, LOG_DAEMON);
331         syslog(LOG_INFO, "configure");
332         return 0;
333     }''')
334   error('syslog is not supported on this system')
335 endif
337 # Miscellaneous Linux-only features
338 get_option('mpath') \
339   .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
341 multiprocess_allowed = get_option('multiprocess') \
342   .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
343   .allowed()
345 vfio_user_server_allowed = get_option('vfio_user_server') \
346   .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
347   .allowed()
349 have_tpm = get_option('tpm') \
350   .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
351   .allowed()
353 # vhost
354 have_vhost_user = get_option('vhost_user') \
355   .disable_auto_if(targetos != 'linux') \
356   .require(targetos != 'windows',
357            error_message: 'vhost-user is not available on Windows').allowed()
358 have_vhost_vdpa = get_option('vhost_vdpa') \
359   .require(targetos == 'linux',
360            error_message: 'vhost-vdpa is only available on Linux').allowed()
361 have_vhost_kernel = get_option('vhost_kernel') \
362   .require(targetos == 'linux',
363            error_message: 'vhost-kernel is only available on Linux').allowed()
364 have_vhost_user_crypto = get_option('vhost_crypto') \
365   .require(have_vhost_user,
366            error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
368 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
370 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
371 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
372 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
373 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
375 # Target-specific libraries and flags
376 libm = cc.find_library('m', required: false)
377 threads = dependency('threads')
378 util = cc.find_library('util', required: false)
379 winmm = []
380 socket = []
381 version_res = []
382 coref = []
383 iokit = []
384 emulator_link_args = []
385 nvmm =not_found
386 hvf = not_found
387 midl = not_found
388 widl = not_found
389 pathcch = not_found
390 host_dsosuf = '.so'
391 if targetos == 'windows'
392   midl = find_program('midl', required: false)
393   widl = find_program('widl', required: false)
394   pathcch = cc.find_library('pathcch')
395   socket = cc.find_library('ws2_32')
396   winmm = cc.find_library('winmm')
398   win = import('windows')
399   version_res = win.compile_resources('version.rc',
400                                       depend_files: files('pc-bios/qemu-nsis.ico'),
401                                       include_directories: include_directories('.'))
402   host_dsosuf = '.dll'
403 elif targetos == 'darwin'
404   coref = dependency('appleframeworks', modules: 'CoreFoundation')
405   iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
406   host_dsosuf = '.dylib'
407 elif targetos == 'sunos'
408   socket = [cc.find_library('socket'),
409             cc.find_library('nsl'),
410             cc.find_library('resolv')]
411 elif targetos == 'haiku'
412   socket = [cc.find_library('posix_error_mapper'),
413             cc.find_library('network'),
414             cc.find_library('bsd')]
415 elif targetos == 'openbsd'
416   if get_option('tcg').allowed() and target_dirs.length() > 0
417     # Disable OpenBSD W^X if available
418     emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
419   endif
420 endif
422 # Target-specific configuration of accelerators
423 accelerators = []
424 if get_option('kvm').allowed() and targetos == 'linux'
425   accelerators += 'CONFIG_KVM'
426 endif
427 if get_option('whpx').allowed() and targetos == 'windows'
428   if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
429     error('WHPX requires 64-bit host')
430   elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
431        cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
432     accelerators += 'CONFIG_WHPX'
433   endif
434 endif
435 if get_option('hvf').allowed()
436   hvf = dependency('appleframeworks', modules: 'Hypervisor',
437                    required: get_option('hvf'))
438   if hvf.found()
439     accelerators += 'CONFIG_HVF'
440   endif
441 endif
442 if get_option('hax').allowed()
443   if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
444     accelerators += 'CONFIG_HAX'
445   endif
446 endif
447 if targetos == 'netbsd'
448   nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
449   if nvmm.found()
450     accelerators += 'CONFIG_NVMM'
451   endif
452 endif
454 tcg_arch = host_arch
455 if get_option('tcg').allowed()
456   if host_arch == 'unknown'
457     if get_option('tcg_interpreter')
458       warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
459     else
460       error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
461     endif
462   elif get_option('tcg_interpreter')
463     warning('Use of the TCG interpreter is not recommended on this host')
464     warning('architecture. There is a native TCG execution backend available')
465     warning('which provides substantially better performance and reliability.')
466     warning('It is strongly recommended to remove the --enable-tcg-interpreter')
467     warning('configuration option on this architecture to use the native')
468     warning('backend.')
469   endif
470   if get_option('tcg_interpreter')
471     tcg_arch = 'tci'
472   elif host_arch == 'sparc64'
473     tcg_arch = 'sparc'
474   elif host_arch == 'x86_64'
475     tcg_arch = 'i386'
476   elif host_arch == 'ppc64'
477     tcg_arch = 'ppc'
478   endif
479   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
480                         language: ['c', 'cpp', 'objc'])
482   accelerators += 'CONFIG_TCG'
483   config_host += { 'CONFIG_TCG': 'y' }
484 endif
486 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
487   error('KVM not available on this platform')
488 endif
489 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
490   error('HVF not available on this platform')
491 endif
492 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
493   error('NVMM not available on this platform')
494 endif
495 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
496   error('WHPX not available on this platform')
497 endif
499 ################
500 # Dependencies #
501 ################
503 # The path to glib.h is added to all compilation commands.  This was
504 # grandfathered in from the QEMU Makefiles.
505 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
506                       native: false, language: ['c', 'cpp', 'objc'])
507 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
508                           link_args: config_host['GLIB_LIBS'].split(),
509                           version: config_host['GLIB_VERSION'],
510                           variables: {
511                             'bindir': config_host['GLIB_BINDIR'],
512                           })
513 # override glib dep with the configure results (for subprojects)
514 meson.override_dependency('glib-2.0', glib)
516 gio = not_found
517 gdbus_codegen = not_found
518 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
519 if not get_option('gio').auto() or have_system
520   gio = dependency('gio-2.0', required: get_option('gio'),
521                    method: 'pkg-config', kwargs: static_kwargs)
522   if gio.found() and not cc.links('''
523     #include <gio/gio.h>
524     int main(void)
525     {
526       g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
527       return 0;
528     }''', dependencies: [glib, gio])
529     if get_option('gio').enabled()
530       error('The installed libgio is broken for static linking')
531     endif
532     gio = not_found
533   endif
534   if gio.found()
535     gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
536                                  required: get_option('gio'))
537     gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
538                           method: 'pkg-config', kwargs: static_kwargs)
539     gio = declare_dependency(dependencies: [gio, gio_unix],
540                              version: gio.version())
541   endif
542 endif
543 if gdbus_codegen.found() and get_option('cfi')
544   gdbus_codegen = not_found
545   gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
546 endif
548 lttng = not_found
549 if 'ust' in get_option('trace_backends')
550   lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
551                      method: 'pkg-config', kwargs: static_kwargs)
552 endif
553 pixman = not_found
554 if have_system or have_tools
555   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
556                       method: 'pkg-config', kwargs: static_kwargs)
557 endif
558 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
560 libaio = not_found
561 if not get_option('linux_aio').auto() or have_block
562   libaio = cc.find_library('aio', has_headers: ['libaio.h'],
563                            required: get_option('linux_aio'),
564                            kwargs: static_kwargs)
565 endif
567 linux_io_uring_test = '''
568   #include <liburing.h>
569   #include <linux/errqueue.h>
571   int main(void) { return 0; }'''
573 linux_io_uring = not_found
574 if not get_option('linux_io_uring').auto() or have_block
575   linux_io_uring = dependency('liburing', version: '>=0.3',
576                               required: get_option('linux_io_uring'),
577                               method: 'pkg-config', kwargs: static_kwargs)
578   if not cc.links(linux_io_uring_test)
579     linux_io_uring = not_found
580   endif
581 endif
583 libnfs = not_found
584 if not get_option('libnfs').auto() or have_block
585   libnfs = dependency('libnfs', version: '>=1.9.3',
586                       required: get_option('libnfs'),
587                       method: 'pkg-config', kwargs: static_kwargs)
588 endif
590 libattr_test = '''
591   #include <stddef.h>
592   #include <sys/types.h>
593   #ifdef CONFIG_LIBATTR
594   #include <attr/xattr.h>
595   #else
596   #include <sys/xattr.h>
597   #endif
598   int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
600 libattr = not_found
601 have_old_libattr = false
602 if get_option('attr').allowed()
603   if cc.links(libattr_test)
604     libattr = declare_dependency()
605   else
606     libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
607                               required: get_option('attr'),
608                               kwargs: static_kwargs)
609     if libattr.found() and not \
610       cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
611       libattr = not_found
612       if get_option('attr').enabled()
613         error('could not link libattr')
614       else
615         warning('could not link libattr, disabling')
616       endif
617     else
618       have_old_libattr = libattr.found()
619     endif
620   endif
621 endif
623 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
624                    required: get_option('cocoa'))
626 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
627 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
628                                               'VMNET_BRIDGED_MODE',
629                                               dependencies: vmnet)
630   vmnet = not_found
631   if get_option('vmnet').enabled()
632     error('vmnet.framework API is outdated')
633   else
634     warning('vmnet.framework API is outdated, disabling')
635   endif
636 endif
638 seccomp = not_found
639 if not get_option('seccomp').auto() or have_system or have_tools
640   seccomp = dependency('libseccomp', version: '>=2.3.0',
641                        required: get_option('seccomp'),
642                        method: 'pkg-config', kwargs: static_kwargs)
643 endif
645 libcap_ng = not_found
646 if not get_option('cap_ng').auto() or have_system or have_tools
647   libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
648                               required: get_option('cap_ng'),
649                               kwargs: static_kwargs)
650 endif
651 if libcap_ng.found() and not cc.links('''
652    #include <cap-ng.h>
653    int main(void)
654    {
655      capng_capability_to_name(CAPNG_EFFECTIVE);
656      return 0;
657    }''', dependencies: libcap_ng)
658   libcap_ng = not_found
659   if get_option('cap_ng').enabled()
660     error('could not link libcap-ng')
661   else
662     warning('could not link libcap-ng, disabling')
663   endif
664 endif
666 if get_option('xkbcommon').auto() and not have_system and not have_tools
667   xkbcommon = not_found
668 else
669   xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
670                          method: 'pkg-config', kwargs: static_kwargs)
671 endif
673 slirp = not_found
674 if not get_option('slirp').auto() or have_system
675   slirp = dependency('slirp', required: get_option('slirp'),
676                      method: 'pkg-config', kwargs: static_kwargs)
677   # slirp < 4.7 is incompatible with CFI support in QEMU.  This is because
678   # it passes function pointers within libslirp as callbacks for timers.
679   # When using a system-wide shared libslirp, the type information for the
680   # callback is missing and the timer call produces a false positive with CFI.
681   # Do not use the "version" keyword argument to produce a better error.
682   # with control-flow integrity.
683   if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
684     if get_option('slirp').enabled()
685       error('Control-Flow Integrity requires libslirp 4.7.')
686     else
687       warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
688       slirp = not_found
689     endif
690   endif
691 endif
693 vde = not_found
694 if not get_option('vde').auto() or have_system or have_tools
695   vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
696                            required: get_option('vde'),
697                            kwargs: static_kwargs)
698 endif
699 if vde.found() and not cc.links('''
700    #include <libvdeplug.h>
701    int main(void)
702    {
703      struct vde_open_args a = {0, 0, 0};
704      char s[] = "";
705      vde_open(s, s, &a);
706      return 0;
707    }''', dependencies: vde)
708   vde = not_found
709   if get_option('cap_ng').enabled()
710     error('could not link libvdeplug')
711   else
712     warning('could not link libvdeplug, disabling')
713   endif
714 endif
716 pulse = not_found
717 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
718   pulse = dependency('libpulse', required: get_option('pa'),
719                      method: 'pkg-config', kwargs: static_kwargs)
720 endif
721 alsa = not_found
722 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
723   alsa = dependency('alsa', required: get_option('alsa'),
724                     method: 'pkg-config', kwargs: static_kwargs)
725 endif
726 jack = not_found
727 if not get_option('jack').auto() or have_system
728   jack = dependency('jack', required: get_option('jack'),
729                     method: 'pkg-config', kwargs: static_kwargs)
730 endif
731 sndio = not_found
732 if not get_option('sndio').auto() or have_system
733   sndio = dependency('sndio', required: get_option('sndio'),
734                     method: 'pkg-config', kwargs: static_kwargs)
735 endif
737 spice_protocol = not_found
738 if not get_option('spice_protocol').auto() or have_system
739   spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
740                               required: get_option('spice_protocol'),
741                               method: 'pkg-config', kwargs: static_kwargs)
742 endif
743 spice = not_found
744 if not get_option('spice').auto() or have_system
745   spice = dependency('spice-server', version: '>=0.12.5',
746                      required: get_option('spice'),
747                      method: 'pkg-config', kwargs: static_kwargs)
748 endif
749 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
751 rt = cc.find_library('rt', required: false)
753 libiscsi = not_found
754 if not get_option('libiscsi').auto() or have_block
755   libiscsi = dependency('libiscsi', version: '>=1.9.0',
756                          required: get_option('libiscsi'),
757                          method: 'pkg-config', kwargs: static_kwargs)
758 endif
759 zstd = not_found
760 if not get_option('zstd').auto() or have_block
761   zstd = dependency('libzstd', version: '>=1.4.0',
762                     required: get_option('zstd'),
763                     method: 'pkg-config', kwargs: static_kwargs)
764 endif
765 virgl = not_found
767 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
768 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
769   virgl = dependency('virglrenderer',
770                      method: 'pkg-config',
771                      required: get_option('virglrenderer'),
772                      kwargs: static_kwargs)
773 endif
774 blkio = not_found
775 if not get_option('blkio').auto() or have_block
776   blkio = dependency('blkio',
777                      method: 'pkg-config',
778                      required: get_option('blkio'),
779                      kwargs: static_kwargs)
780 endif
781 curl = not_found
782 if not get_option('curl').auto() or have_block
783   curl = dependency('libcurl', version: '>=7.29.0',
784                     method: 'pkg-config',
785                     required: get_option('curl'),
786                     kwargs: static_kwargs)
787 endif
788 libudev = not_found
789 if targetos == 'linux' and (have_system or have_tools)
790   libudev = dependency('libudev',
791                        method: 'pkg-config',
792                        required: get_option('libudev'),
793                        kwargs: static_kwargs)
794 endif
796 mpathlibs = [libudev]
797 mpathpersist = not_found
798 mpathpersist_new_api = false
799 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
800   mpath_test_source_new = '''
801     #include <libudev.h>
802     #include <mpath_persist.h>
803     unsigned mpath_mx_alloc_len = 1024;
804     int logsink;
805     static struct config *multipath_conf;
806     extern struct udev *udev;
807     extern struct config *get_multipath_config(void);
808     extern void put_multipath_config(struct config *conf);
809     struct udev *udev;
810     struct config *get_multipath_config(void) { return multipath_conf; }
811     void put_multipath_config(struct config *conf) { }
812     int main(void) {
813         udev = udev_new();
814         multipath_conf = mpath_lib_init();
815         return 0;
816     }'''
817   mpath_test_source_old = '''
818       #include <libudev.h>
819       #include <mpath_persist.h>
820       unsigned mpath_mx_alloc_len = 1024;
821       int logsink;
822       int main(void) {
823           struct udev *udev = udev_new();
824           mpath_lib_init(udev);
825           return 0;
826       }'''
827   libmpathpersist = cc.find_library('mpathpersist',
828                                     required: get_option('mpath'),
829                                     kwargs: static_kwargs)
830   if libmpathpersist.found()
831     mpathlibs += libmpathpersist
832     if enable_static
833       mpathlibs += cc.find_library('devmapper',
834                                      required: get_option('mpath'),
835                                      kwargs: static_kwargs)
836     endif
837     mpathlibs += cc.find_library('multipath',
838                                  required: get_option('mpath'),
839                                  kwargs: static_kwargs)
840     foreach lib: mpathlibs
841       if not lib.found()
842         mpathlibs = []
843         break
844       endif
845     endforeach
846     if mpathlibs.length() == 0
847       msg = 'Dependencies missing for libmpathpersist'
848     elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
849       mpathpersist = declare_dependency(dependencies: mpathlibs)
850       mpathpersist_new_api = true
851     elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
852       mpathpersist = declare_dependency(dependencies: mpathlibs)
853     else
854       msg = 'Cannot detect libmpathpersist API'
855     endif
856     if not mpathpersist.found()
857       if get_option('mpath').enabled()
858         error(msg)
859       else
860         warning(msg + ', disabling')
861       endif
862     endif
863   endif
864 endif
866 iconv = not_found
867 curses = not_found
868 if have_system and get_option('curses').allowed()
869   curses_test = '''
870     #if defined(__APPLE__) || defined(__OpenBSD__)
871     #define _XOPEN_SOURCE_EXTENDED 1
872     #endif
873     #include <locale.h>
874     #include <curses.h>
875     #include <wchar.h>
876     int main(void) {
877       wchar_t wch = L'w';
878       setlocale(LC_ALL, "");
879       resize_term(0, 0);
880       addwstr(L"wide chars\n");
881       addnwstr(&wch, 1);
882       add_wch(WACS_DEGREE);
883       return 0;
884     }'''
886   curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
887   curses = dependency(curses_dep_list,
888                       required: false,
889                       method: 'pkg-config',
890                       kwargs: static_kwargs)
891   msg = get_option('curses').enabled() ? 'curses library not found' : ''
892   curses_compile_args = ['-DNCURSES_WIDECHAR=1']
893   if curses.found()
894     if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
895       curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
896     else
897       msg = 'curses package not usable'
898       curses = not_found
899     endif
900   endif
901   if not curses.found()
902     has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
903     if targetos != 'windows' and not has_curses_h
904       message('Trying with /usr/include/ncursesw')
905       curses_compile_args += ['-I/usr/include/ncursesw']
906       has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
907     endif
908     if has_curses_h
909       curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
910       foreach curses_libname : curses_libname_list
911         libcurses = cc.find_library(curses_libname,
912                                     required: false,
913                                     kwargs: static_kwargs)
914         if libcurses.found()
915           if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
916             curses = declare_dependency(compile_args: curses_compile_args,
917                                         dependencies: [libcurses])
918             break
919           else
920             msg = 'curses library not usable'
921           endif
922         endif
923       endforeach
924     endif
925   endif
926   if get_option('iconv').allowed()
927     foreach link_args : [ ['-liconv'], [] ]
928       # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
929       # We need to use libiconv if available because mixing libiconv's headers with
930       # the system libc does not work.
931       # However, without adding glib to the dependencies -L/usr/local/lib will not be
932       # included in the command line and libiconv will not be found.
933       if cc.links('''
934         #include <iconv.h>
935         int main(void) {
936           iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
937           return conv != (iconv_t) -1;
938         }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
939         iconv = declare_dependency(link_args: link_args, dependencies: glib)
940         break
941       endif
942     endforeach
943   endif
944   if curses.found() and not iconv.found()
945     if get_option('iconv').enabled()
946       error('iconv not available')
947     endif
948     msg = 'iconv required for curses UI but not available'
949     curses = not_found
950   endif
951   if not curses.found() and msg != ''
952     if get_option('curses').enabled()
953       error(msg)
954     else
955       warning(msg + ', disabling')
956     endif
957   endif
958 endif
960 brlapi = not_found
961 if not get_option('brlapi').auto() or have_system
962   brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
963                          required: get_option('brlapi'),
964                          kwargs: static_kwargs)
965   if brlapi.found() and not cc.links('''
966      #include <brlapi.h>
967      #include <stddef.h>
968      int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
969     brlapi = not_found
970     if get_option('brlapi').enabled()
971       error('could not link brlapi')
972     else
973       warning('could not link brlapi, disabling')
974     endif
975   endif
976 endif
978 sdl = not_found
979 if not get_option('sdl').auto() or have_system
980   sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
981   sdl_image = not_found
982 endif
983 if sdl.found()
984   # work around 2.0.8 bug
985   sdl = declare_dependency(compile_args: '-Wno-undef',
986                            dependencies: sdl)
987   sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
988                          method: 'pkg-config', kwargs: static_kwargs)
989 else
990   if get_option('sdl_image').enabled()
991     error('sdl-image required, but SDL was @0@'.format(
992           get_option('sdl').disabled() ? 'disabled' : 'not found'))
993   endif
994   sdl_image = not_found
995 endif
997 rbd = not_found
998 if not get_option('rbd').auto() or have_block
999   librados = cc.find_library('rados', required: get_option('rbd'),
1000                              kwargs: static_kwargs)
1001   librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1002                            required: get_option('rbd'),
1003                            kwargs: static_kwargs)
1004   if librados.found() and librbd.found()
1005     if cc.links('''
1006       #include <stdio.h>
1007       #include <rbd/librbd.h>
1008       int main(void) {
1009         rados_t cluster;
1010         rados_create(&cluster, NULL);
1011         #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1012         #error
1013         #endif
1014         return 0;
1015       }''', dependencies: [librbd, librados])
1016       rbd = declare_dependency(dependencies: [librbd, librados])
1017     elif get_option('rbd').enabled()
1018       error('librbd >= 1.12.0 required')
1019     else
1020       warning('librbd >= 1.12.0 not found, disabling')
1021     endif
1022   endif
1023 endif
1025 glusterfs = not_found
1026 glusterfs_ftruncate_has_stat = false
1027 glusterfs_iocb_has_stat = false
1028 if not get_option('glusterfs').auto() or have_block
1029   glusterfs = dependency('glusterfs-api', version: '>=3',
1030                          required: get_option('glusterfs'),
1031                          method: 'pkg-config', kwargs: static_kwargs)
1032   if glusterfs.found()
1033     glusterfs_ftruncate_has_stat = cc.links('''
1034       #include <glusterfs/api/glfs.h>
1036       int
1037       main(void)
1038       {
1039           /* new glfs_ftruncate() passes two additional args */
1040           return glfs_ftruncate(NULL, 0, NULL, NULL);
1041       }
1042     ''', dependencies: glusterfs)
1043     glusterfs_iocb_has_stat = cc.links('''
1044       #include <glusterfs/api/glfs.h>
1046       /* new glfs_io_cbk() passes two additional glfs_stat structs */
1047       static void
1048       glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1049       {}
1051       int
1052       main(void)
1053       {
1054           glfs_io_cbk iocb = &glusterfs_iocb;
1055           iocb(NULL, 0 , NULL, NULL, NULL);
1056           return 0;
1057       }
1058     ''', dependencies: glusterfs)
1059   endif
1060 endif
1062 libssh = not_found
1063 if not get_option('libssh').auto() or have_block
1064   libssh = dependency('libssh', version: '>=0.8.7',
1065                     method: 'pkg-config',
1066                     required: get_option('libssh'),
1067                     kwargs: static_kwargs)
1068 endif
1070 libbzip2 = not_found
1071 if not get_option('bzip2').auto() or have_block
1072   libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1073                              required: get_option('bzip2'),
1074                              kwargs: static_kwargs)
1075   if libbzip2.found() and not cc.links('''
1076      #include <bzlib.h>
1077      int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1078     libbzip2 = not_found
1079     if get_option('bzip2').enabled()
1080       error('could not link libbzip2')
1081     else
1082       warning('could not link libbzip2, disabling')
1083     endif
1084   endif
1085 endif
1087 liblzfse = not_found
1088 if not get_option('lzfse').auto() or have_block
1089   liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1090                              required: get_option('lzfse'),
1091                              kwargs: static_kwargs)
1092 endif
1093 if liblzfse.found() and not cc.links('''
1094    #include <lzfse.h>
1095    int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1096   liblzfse = not_found
1097   if get_option('lzfse').enabled()
1098     error('could not link liblzfse')
1099   else
1100     warning('could not link liblzfse, disabling')
1101   endif
1102 endif
1104 oss = not_found
1105 if get_option('oss').allowed() and have_system
1106   if not cc.has_header('sys/soundcard.h')
1107     # not found
1108   elif targetos == 'netbsd'
1109     oss = cc.find_library('ossaudio', required: get_option('oss'),
1110                           kwargs: static_kwargs)
1111   else
1112     oss = declare_dependency()
1113   endif
1115   if not oss.found()
1116     if get_option('oss').enabled()
1117       error('OSS not found')
1118     endif
1119   endif
1120 endif
1121 dsound = not_found
1122 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1123   if cc.has_header('dsound.h')
1124     dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1125   endif
1127   if not dsound.found()
1128     if get_option('dsound').enabled()
1129       error('DirectSound not found')
1130     endif
1131   endif
1132 endif
1134 coreaudio = not_found
1135 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1136   coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1137                          required: get_option('coreaudio'))
1138 endif
1140 opengl = not_found
1141 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1142   epoxy = dependency('epoxy', method: 'pkg-config',
1143                       required: get_option('opengl'), kwargs: static_kwargs)
1144   if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1145     opengl = epoxy
1146   elif get_option('opengl').enabled()
1147     error('epoxy/egl.h not found')
1148   endif
1149 endif
1150 gbm = not_found
1151 if (have_system or have_tools) and (virgl.found() or opengl.found())
1152   gbm = dependency('gbm', method: 'pkg-config', required: false,
1153                    kwargs: static_kwargs)
1154 endif
1155 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1157 gnutls = not_found
1158 gnutls_crypto = not_found
1159 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1160   # For general TLS support our min gnutls matches
1161   # that implied by our platform support matrix
1162   #
1163   # For the crypto backends, we look for a newer
1164   # gnutls:
1165   #
1166   #   Version 3.6.8  is needed to get XTS
1167   #   Version 3.6.13 is needed to get PBKDF
1168   #   Version 3.6.14 is needed to get HW accelerated XTS
1169   #
1170   # If newer enough gnutls isn't available, we can
1171   # still use a different crypto backend to satisfy
1172   # the platform support requirements
1173   gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1174                              method: 'pkg-config',
1175                              required: false,
1176                              kwargs: static_kwargs)
1177   if gnutls_crypto.found()
1178     gnutls = gnutls_crypto
1179   else
1180     # Our min version if all we need is TLS
1181     gnutls = dependency('gnutls', version: '>=3.5.18',
1182                         method: 'pkg-config',
1183                         required: get_option('gnutls'),
1184                         kwargs: static_kwargs)
1185   endif
1186 endif
1188 # We prefer use of gnutls for crypto, unless the options
1189 # explicitly asked for nettle or gcrypt.
1191 # If gnutls isn't available for crypto, then we'll prefer
1192 # gcrypt over nettle for performance reasons.
1193 gcrypt = not_found
1194 nettle = not_found
1195 hogweed = not_found
1196 xts = 'none'
1198 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1199   error('Only one of gcrypt & nettle can be enabled')
1200 endif
1202 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1203 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1204   gnutls_crypto = not_found
1205 endif
1207 if not gnutls_crypto.found()
1208   if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1209     gcrypt = dependency('libgcrypt', version: '>=1.8',
1210                         method: 'config-tool',
1211                         required: get_option('gcrypt'),
1212                         kwargs: static_kwargs)
1213     # Debian has removed -lgpg-error from libgcrypt-config
1214     # as it "spreads unnecessary dependencies" which in
1215     # turn breaks static builds...
1216     if gcrypt.found() and enable_static
1217       gcrypt = declare_dependency(dependencies: [
1218         gcrypt,
1219         cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1220     endif
1221   endif
1222   if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1223     nettle = dependency('nettle', version: '>=3.4',
1224                         method: 'pkg-config',
1225                         required: get_option('nettle'),
1226                         kwargs: static_kwargs)
1227     if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1228       xts = 'private'
1229     endif
1230   endif
1231 endif
1233 gmp = dependency('gmp', required: false, method: 'pkg-config', kwargs: static_kwargs)
1234 if nettle.found() and gmp.found()
1235   hogweed = dependency('hogweed', version: '>=3.4',
1236                        method: 'pkg-config',
1237                        required: get_option('nettle'),
1238                        kwargs: static_kwargs)
1239 endif
1242 gtk = not_found
1243 gtkx11 = not_found
1244 vte = not_found
1245 if not get_option('gtk').auto() or have_system
1246   gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1247                    method: 'pkg-config',
1248                    required: get_option('gtk'),
1249                    kwargs: static_kwargs)
1250   if gtk.found()
1251     gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1252                         method: 'pkg-config',
1253                         required: false,
1254                         kwargs: static_kwargs)
1255     gtk = declare_dependency(dependencies: [gtk, gtkx11])
1257     if not get_option('vte').auto() or have_system
1258       vte = dependency('vte-2.91',
1259                        method: 'pkg-config',
1260                        required: get_option('vte'),
1261                        kwargs: static_kwargs)
1262     endif
1263   endif
1264 endif
1266 x11 = not_found
1267 if gtkx11.found()
1268   x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1269                    kwargs: static_kwargs)
1270 endif
1271 png = not_found
1272 if get_option('png').allowed() and have_system
1273    png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1274                     method: 'pkg-config', kwargs: static_kwargs)
1275 endif
1276 vnc = not_found
1277 jpeg = not_found
1278 sasl = not_found
1279 if get_option('vnc').allowed() and have_system
1280   vnc = declare_dependency() # dummy dependency
1281   jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1282                     method: 'pkg-config', kwargs: static_kwargs)
1283   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1284                          required: get_option('vnc_sasl'),
1285                          kwargs: static_kwargs)
1286   if sasl.found()
1287     sasl = declare_dependency(dependencies: sasl,
1288                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
1289   endif
1290 endif
1292 pam = not_found
1293 if not get_option('auth_pam').auto() or have_system
1294   pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1295                         required: get_option('auth_pam'),
1296                         kwargs: static_kwargs)
1297 endif
1298 if pam.found() and not cc.links('''
1299    #include <stddef.h>
1300    #include <security/pam_appl.h>
1301    int main(void) {
1302      const char *service_name = "qemu";
1303      const char *user = "frank";
1304      const struct pam_conv pam_conv = { 0 };
1305      pam_handle_t *pamh = NULL;
1306      pam_start(service_name, user, &pam_conv, &pamh);
1307      return 0;
1308    }''', dependencies: pam)
1309   pam = not_found
1310   if get_option('auth_pam').enabled()
1311     error('could not link libpam')
1312   else
1313     warning('could not link libpam, disabling')
1314   endif
1315 endif
1317 snappy = not_found
1318 if not get_option('snappy').auto() or have_system
1319   snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1320                            required: get_option('snappy'),
1321                            kwargs: static_kwargs)
1322 endif
1323 if snappy.found() and not linker.links('''
1324    #include <snappy-c.h>
1325    int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1326   snappy = not_found
1327   if get_option('snappy').enabled()
1328     error('could not link libsnappy')
1329   else
1330     warning('could not link libsnappy, disabling')
1331   endif
1332 endif
1334 lzo = not_found
1335 if not get_option('lzo').auto() or have_system
1336   lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1337                         required: get_option('lzo'),
1338                         kwargs: static_kwargs)
1339 endif
1340 if lzo.found() and not cc.links('''
1341    #include <lzo/lzo1x.h>
1342    int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1343   lzo = not_found
1344   if get_option('lzo').enabled()
1345     error('could not link liblzo2')
1346   else
1347     warning('could not link liblzo2, disabling')
1348   endif
1349 endif
1351 numa = not_found
1352 if not get_option('numa').auto() or have_system or have_tools
1353   numa = cc.find_library('numa', has_headers: ['numa.h'],
1354                               required: get_option('numa'),
1355                               kwargs: static_kwargs)
1356 endif
1357 if numa.found() and not cc.links('''
1358    #include <numa.h>
1359    int main(void) { return numa_available(); }
1360    ''', dependencies: numa)
1361   numa = not_found
1362   if get_option('numa').enabled()
1363     error('could not link numa')
1364   else
1365     warning('could not link numa, disabling')
1366   endif
1367 endif
1369 rdma = not_found
1370 if not get_option('rdma').auto() or have_system
1371   libumad = cc.find_library('ibumad', required: get_option('rdma'))
1372   rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1373                                required: get_option('rdma'),
1374                                kwargs: static_kwargs),
1375                cc.find_library('ibverbs', required: get_option('rdma'),
1376                                kwargs: static_kwargs),
1377                libumad]
1378   rdma = declare_dependency(dependencies: rdma_libs)
1379   foreach lib: rdma_libs
1380     if not lib.found()
1381       rdma = not_found
1382     endif
1383   endforeach
1384 endif
1386 xen = not_found
1387 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
1388   xencontrol = dependency('xencontrol', required: false,
1389                           method: 'pkg-config', kwargs: static_kwargs)
1390   if xencontrol.found()
1391     xen_pc = declare_dependency(version: xencontrol.version(),
1392       dependencies: [
1393         xencontrol,
1394         # disabler: true makes xen_pc.found() return false if any is not found
1395         dependency('xenstore', required: false,
1396                    method: 'pkg-config', kwargs: static_kwargs,
1397                    disabler: true),
1398         dependency('xenforeignmemory', required: false,
1399                    method: 'pkg-config', kwargs: static_kwargs,
1400                    disabler: true),
1401         dependency('xengnttab', required: false,
1402                    method: 'pkg-config', kwargs: static_kwargs,
1403                    disabler: true),
1404         dependency('xenevtchn', required: false,
1405                    method: 'pkg-config', kwargs: static_kwargs,
1406                    disabler: true),
1407         dependency('xendevicemodel', required: false,
1408                    method: 'pkg-config', kwargs: static_kwargs,
1409                    disabler: true),
1410         # optional, no "disabler: true"
1411         dependency('xentoolcore', required: false,
1412                    method: 'pkg-config', kwargs: static_kwargs)])
1413     if xen_pc.found()
1414       xen = xen_pc
1415     endif
1416   endif
1417   if not xen.found()
1418     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' ]
1419     xen_libs = {
1420       '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1421       '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1422       '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1423       '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1424       '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1425       '4.6.0': [ 'xenstore', 'xenctrl' ],
1426       '4.5.0': [ 'xenstore', 'xenctrl' ],
1427       '4.2.0': [ 'xenstore', 'xenctrl' ],
1428     }
1429     xen_deps = {}
1430     foreach ver: xen_tests
1431       # cache the various library tests to avoid polluting the logs
1432       xen_test_deps = []
1433       foreach l: xen_libs[ver]
1434         if l not in xen_deps
1435           xen_deps += { l: cc.find_library(l, required: false) }
1436         endif
1437         xen_test_deps += xen_deps[l]
1438       endforeach
1440       # Use -D to pick just one of the test programs in scripts/xen-detect.c
1441       xen_version = ver.split('.')
1442       xen_ctrl_version = xen_version[0] + \
1443         ('0' + xen_version[1]).substring(-2) + \
1444         ('0' + xen_version[2]).substring(-2)
1445       if cc.links(files('scripts/xen-detect.c'),
1446                   args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
1447                   dependencies: xen_test_deps)
1448         xen = declare_dependency(version: ver, dependencies: xen_test_deps)
1449         break
1450       endif
1451     endforeach
1452   endif
1453   if xen.found()
1454     accelerators += 'CONFIG_XEN'
1455   elif get_option('xen').enabled()
1456     error('could not compile and link Xen test program')
1457   endif
1458 endif
1459 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
1460   .require(xen.found(),
1461            error_message: 'Xen PCI passthrough requested but Xen not enabled') \
1462   .require(targetos == 'linux',
1463            error_message: 'Xen PCI passthrough not available on this platform') \
1464   .allowed()
1467 cacard = not_found
1468 if not get_option('smartcard').auto() or have_system
1469   cacard = dependency('libcacard', required: get_option('smartcard'),
1470                       version: '>=2.5.1', method: 'pkg-config',
1471                       kwargs: static_kwargs)
1472 endif
1473 u2f = not_found
1474 if have_system
1475   u2f = dependency('u2f-emu', required: get_option('u2f'),
1476                    method: 'pkg-config',
1477                    kwargs: static_kwargs)
1478 endif
1479 canokey = not_found
1480 if have_system
1481   canokey = dependency('canokey-qemu', required: get_option('canokey'),
1482                    method: 'pkg-config',
1483                    kwargs: static_kwargs)
1484 endif
1485 usbredir = not_found
1486 if not get_option('usb_redir').auto() or have_system
1487   usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1488                         version: '>=0.6', method: 'pkg-config',
1489                         kwargs: static_kwargs)
1490 endif
1491 libusb = not_found
1492 if not get_option('libusb').auto() or have_system
1493   libusb = dependency('libusb-1.0', required: get_option('libusb'),
1494                       version: '>=1.0.13', method: 'pkg-config',
1495                       kwargs: static_kwargs)
1496 endif
1498 libpmem = not_found
1499 if not get_option('libpmem').auto() or have_system
1500   libpmem = dependency('libpmem', required: get_option('libpmem'),
1501                        method: 'pkg-config', kwargs: static_kwargs)
1502 endif
1503 libdaxctl = not_found
1504 if not get_option('libdaxctl').auto() or have_system
1505   libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1506                          version: '>=57', method: 'pkg-config',
1507                          kwargs: static_kwargs)
1508 endif
1509 tasn1 = not_found
1510 if gnutls.found()
1511   tasn1 = dependency('libtasn1',
1512                      method: 'pkg-config',
1513                      kwargs: static_kwargs)
1514 endif
1515 keyutils = dependency('libkeyutils', required: false,
1516                       method: 'pkg-config', kwargs: static_kwargs)
1518 has_gettid = cc.has_function('gettid')
1520 # libselinux
1521 selinux = dependency('libselinux',
1522                      required: get_option('selinux'),
1523                      method: 'pkg-config', kwargs: static_kwargs)
1525 # Malloc tests
1527 malloc = []
1528 if get_option('malloc') == 'system'
1529   has_malloc_trim = \
1530     get_option('malloc_trim').allowed() and \
1531     cc.links('''#include <malloc.h>
1532                 int main(void) { malloc_trim(0); return 0; }''')
1533 else
1534   has_malloc_trim = false
1535   malloc = cc.find_library(get_option('malloc'), required: true)
1536 endif
1537 if not has_malloc_trim and get_option('malloc_trim').enabled()
1538   if get_option('malloc') == 'system'
1539     error('malloc_trim not available on this platform.')
1540   else
1541     error('malloc_trim not available with non-libc memory allocator')
1542   endif
1543 endif
1545 # Check whether the glibc provides statx()
1547 gnu_source_prefix = '''
1548   #ifndef _GNU_SOURCE
1549   #define _GNU_SOURCE
1550   #endif
1552 statx_test = gnu_source_prefix + '''
1553   #include <sys/stat.h>
1554   int main(void) {
1555     struct statx statxbuf;
1556     statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1557     return 0;
1558   }'''
1560 has_statx = cc.links(statx_test)
1562 # Check whether statx() provides mount ID information
1564 statx_mnt_id_test = gnu_source_prefix + '''
1565   #include <sys/stat.h>
1566   int main(void) {
1567     struct statx statxbuf;
1568     statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1569     return statxbuf.stx_mnt_id;
1570   }'''
1572 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1574 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1575   .require(targetos == 'linux',
1576            error_message: 'vhost_user_blk_server requires linux') \
1577   .require(have_vhost_user,
1578            error_message: 'vhost_user_blk_server requires vhost-user support') \
1579   .disable_auto_if(not have_tools and not have_system) \
1580   .allowed()
1582 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1583   error('Cannot enable fuse-lseek while fuse is disabled')
1584 endif
1586 fuse = dependency('fuse3', required: get_option('fuse'),
1587                   version: '>=3.1', method: 'pkg-config',
1588                   kwargs: static_kwargs)
1590 fuse_lseek = not_found
1591 if get_option('fuse_lseek').allowed()
1592   if fuse.version().version_compare('>=3.8')
1593     # Dummy dependency
1594     fuse_lseek = declare_dependency()
1595   elif get_option('fuse_lseek').enabled()
1596     if fuse.found()
1597       error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1598     else
1599       error('fuse-lseek requires libfuse, which was not found')
1600     endif
1601   endif
1602 endif
1604 have_libvduse = (targetos == 'linux')
1605 if get_option('libvduse').enabled()
1606     if targetos != 'linux'
1607         error('libvduse requires linux')
1608     endif
1609 elif get_option('libvduse').disabled()
1610     have_libvduse = false
1611 endif
1613 have_vduse_blk_export = (have_libvduse and targetos == 'linux')
1614 if get_option('vduse_blk_export').enabled()
1615     if targetos != 'linux'
1616         error('vduse_blk_export requires linux')
1617     elif not have_libvduse
1618         error('vduse_blk_export requires libvduse support')
1619     endif
1620 elif get_option('vduse_blk_export').disabled()
1621     have_vduse_blk_export = false
1622 endif
1624 # libbpf
1625 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1626 if libbpf.found() and not cc.links('''
1627    #include <bpf/libbpf.h>
1628    int main(void)
1629    {
1630      bpf_object__destroy_skeleton(NULL);
1631      return 0;
1632    }''', dependencies: libbpf)
1633   libbpf = not_found
1634   if get_option('bpf').enabled()
1635     error('libbpf skeleton test failed')
1636   else
1637     warning('libbpf skeleton test failed, disabling')
1638   endif
1639 endif
1641 #################
1642 # config-host.h #
1643 #################
1645 audio_drivers_selected = []
1646 if have_system
1647   audio_drivers_available = {
1648     'alsa': alsa.found(),
1649     'coreaudio': coreaudio.found(),
1650     'dsound': dsound.found(),
1651     'jack': jack.found(),
1652     'oss': oss.found(),
1653     'pa': pulse.found(),
1654     'sdl': sdl.found(),
1655     'sndio': sndio.found(),
1656   }
1657   foreach k, v: audio_drivers_available
1658     config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1659   endforeach
1661   # Default to native drivers first, OSS second, SDL third
1662   audio_drivers_priority = \
1663     [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
1664     (targetos == 'linux' ? [] : [ 'sdl' ])
1665   audio_drivers_default = []
1666   foreach k: audio_drivers_priority
1667     if audio_drivers_available[k]
1668       audio_drivers_default += k
1669     endif
1670   endforeach
1672   foreach k: get_option('audio_drv_list')
1673     if k == 'default'
1674       audio_drivers_selected += audio_drivers_default
1675     elif not audio_drivers_available[k]
1676       error('Audio driver "@0@" not available.'.format(k))
1677     else
1678       audio_drivers_selected += k
1679     endif
1680   endforeach
1681 endif
1682 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1683                      '"' + '", "'.join(audio_drivers_selected) + '", ')
1685 if get_option('cfi')
1686   cfi_flags=[]
1687   # Check for dependency on LTO
1688   if not get_option('b_lto')
1689     error('Selected Control-Flow Integrity but LTO is disabled')
1690   endif
1691   if config_host.has_key('CONFIG_MODULES')
1692     error('Selected Control-Flow Integrity is not compatible with modules')
1693   endif
1694   # Check for cfi flags. CFI requires LTO so we can't use
1695   # get_supported_arguments, but need a more complex "compiles" which allows
1696   # custom arguments
1697   if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1698                  args: ['-flto', '-fsanitize=cfi-icall'] )
1699     cfi_flags += '-fsanitize=cfi-icall'
1700   else
1701     error('-fsanitize=cfi-icall is not supported by the compiler')
1702   endif
1703   if cc.compiles('int main () { return 0; }',
1704                  name: '-fsanitize-cfi-icall-generalize-pointers',
1705                  args: ['-flto', '-fsanitize=cfi-icall',
1706                         '-fsanitize-cfi-icall-generalize-pointers'] )
1707     cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1708   else
1709     error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1710   endif
1711   if get_option('cfi_debug')
1712     if cc.compiles('int main () { return 0; }',
1713                    name: '-fno-sanitize-trap=cfi-icall',
1714                    args: ['-flto', '-fsanitize=cfi-icall',
1715                           '-fno-sanitize-trap=cfi-icall'] )
1716       cfi_flags += '-fno-sanitize-trap=cfi-icall'
1717     else
1718       error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1719     endif
1720   endif
1721   add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1722   add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1723 endif
1725 have_host_block_device = (targetos != 'darwin' or
1726     cc.has_header('IOKit/storage/IOMedia.h'))
1728 dbus_display = get_option('dbus_display') \
1729   .require(gio.version().version_compare('>=2.64'),
1730            error_message: '-display dbus requires glib>=2.64') \
1731   .require(gdbus_codegen.found(),
1732            error_message: gdbus_codegen_error.format('-display dbus')) \
1733   .require(opengl.found() and gbm.found(),
1734            error_message: '-display dbus requires epoxy/egl and gbm') \
1735   .allowed()
1737 have_virtfs = get_option('virtfs') \
1738     .require(targetos == 'linux' or targetos == 'darwin',
1739              error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1740     .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1741              error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1742     .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1743              error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1744     .disable_auto_if(not have_tools and not have_system) \
1745     .allowed()
1747 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1749 if get_option('block_drv_ro_whitelist') == ''
1750   config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
1751 else
1752   config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
1753         '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
1754 endif
1755 if get_option('block_drv_rw_whitelist') == ''
1756   config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
1757 else
1758   config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
1759         '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
1760 endif
1762 foreach k : get_option('trace_backends')
1763   config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1764 endforeach
1765 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1766 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
1767 if iasl.found()
1768   config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
1769 endif
1770 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1771 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1772 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1773 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1774 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1776 qemu_firmwarepath = ''
1777 foreach k : get_option('qemu_firmwarepath')
1778   qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
1779 endforeach
1780 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
1782 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1783 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1784 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1785 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1786 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1787 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1789 if config_host.has_key('CONFIG_MODULES')
1790   config_host_data.set('CONFIG_STAMP', run_command(
1791       meson.current_source_dir() / 'scripts/qemu-stamp.py',
1792       meson.project_version(), get_option('pkgversion'), '--',
1793       meson.current_source_dir() / 'configure',
1794       capture: true, check: true).stdout().strip())
1795 endif
1797 have_slirp_smbd = get_option('slirp_smbd') \
1798   .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1799   .allowed()
1800 if have_slirp_smbd
1801   smbd_path = get_option('smbd')
1802   if smbd_path == ''
1803     smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1804   endif
1805   config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1806 endif
1808 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1810 if get_option('module_upgrades') and not enable_modules
1811   error('Cannot enable module-upgrades as modules are not enabled')
1812 endif
1813 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1815 config_host_data.set('CONFIG_ATTR', libattr.found())
1816 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1817 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1818 config_host_data.set('CONFIG_COCOA', cocoa.found())
1819 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1820 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1821 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1822 config_host_data.set('CONFIG_LZO', lzo.found())
1823 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1824 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1825 config_host_data.set('CONFIG_BLKIO', blkio.found())
1826 config_host_data.set('CONFIG_CURL', curl.found())
1827 config_host_data.set('CONFIG_CURSES', curses.found())
1828 config_host_data.set('CONFIG_GBM', gbm.found())
1829 config_host_data.set('CONFIG_GIO', gio.found())
1830 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1831 if glusterfs.found()
1832   config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1833   config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1834   config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1835   config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1836   config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1837   config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1838 endif
1839 config_host_data.set('CONFIG_GTK', gtk.found())
1840 config_host_data.set('CONFIG_VTE', vte.found())
1841 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1842 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1843 config_host_data.set('CONFIG_EBPF', libbpf.found())
1844 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1845 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1846 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1847 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1848 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1849 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1850 config_host_data.set('CONFIG_LIBURING_REGISTER_RING_FD', cc.has_function('io_uring_register_ring_fd', prefix: '#include <liburing.h>', dependencies:linux_io_uring))
1851 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1852 config_host_data.set('CONFIG_NUMA', numa.found())
1853 config_host_data.set('CONFIG_OPENGL', opengl.found())
1854 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1855 config_host_data.set('CONFIG_RBD', rbd.found())
1856 config_host_data.set('CONFIG_RDMA', rdma.found())
1857 config_host_data.set('CONFIG_SDL', sdl.found())
1858 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1859 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1860 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1861 config_host_data.set('CONFIG_TPM', have_tpm)
1862 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1863 config_host_data.set('CONFIG_VDE', vde.found())
1864 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
1865 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
1866 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
1867 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
1868 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
1869 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
1870 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
1871 config_host_data.set('CONFIG_VMNET', vmnet.found())
1872 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1873 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
1874 config_host_data.set('CONFIG_PNG', png.found())
1875 config_host_data.set('CONFIG_VNC', vnc.found())
1876 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1877 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1878 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1879 config_host_data.set('CONFIG_VTE', vte.found())
1880 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1881 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1882 config_host_data.set('CONFIG_GETTID', has_gettid)
1883 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1884 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1885 config_host_data.set('CONFIG_TASN1', tasn1.found())
1886 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1887 config_host_data.set('CONFIG_NETTLE', nettle.found())
1888 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
1889 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1890 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1891 config_host_data.set('CONFIG_STATX', has_statx)
1892 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1893 config_host_data.set('CONFIG_ZSTD', zstd.found())
1894 config_host_data.set('CONFIG_FUSE', fuse.found())
1895 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1896 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1897 if spice_protocol.found()
1898 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1899 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1900 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1901 endif
1902 config_host_data.set('CONFIG_SPICE', spice.found())
1903 config_host_data.set('CONFIG_X11', x11.found())
1904 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1905 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1906 config_host_data.set('CONFIG_SELINUX', selinux.found())
1907 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1908 if xen.found()
1909   # protect from xen.version() having less than three components
1910   xen_version = xen.version().split('.') + ['0', '0']
1911   xen_ctrl_version = xen_version[0] + \
1912     ('0' + xen_version[1]).substring(-2) + \
1913     ('0' + xen_version[2]).substring(-2)
1914   config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1915 endif
1916 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1917 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1918 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1919 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1921 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1922 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1924 have_coroutine_pool = get_option('coroutine_pool')
1925 if get_option('debug_stack_usage') and have_coroutine_pool
1926   message('Disabling coroutine pool to measure stack usage')
1927   have_coroutine_pool = false
1928 endif
1929 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1930 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1931 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1932 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1933 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1934 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1935 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
1937 # has_header
1938 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1939 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1940 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1941 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1942 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1943 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1944 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1945 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1946 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1947 if targetos == 'windows'
1948   config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
1949 endif
1951 # has_function
1952 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1953 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1954 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1955 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1956 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1957 # Note that we need to specify prefix: here to avoid incorrectly
1958 # thinking that Windows has posix_memalign()
1959 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1960 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1961 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1962 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1963 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1964 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1965 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1966 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1967 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1968 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1969 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1970 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1971 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1972 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1973 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1974 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1975 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1976 if rbd.found()
1977   config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
1978                        cc.has_function('rbd_namespace_exists',
1979                                        dependencies: rbd,
1980                                        prefix: '#include <rbd/librbd.h>'))
1981 endif
1982 if rdma.found()
1983   config_host_data.set('HAVE_IBV_ADVISE_MR',
1984                        cc.has_function('ibv_advise_mr',
1985                                        dependencies: rdma,
1986                                        prefix: '#include <infiniband/verbs.h>'))
1987 endif
1989 # has_header_symbol
1990 config_host_data.set('CONFIG_BYTESWAP_H',
1991                      cc.has_header_symbol('byteswap.h', 'bswap_32'))
1992 config_host_data.set('CONFIG_EPOLL_CREATE1',
1993                      cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1994 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1995                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1996                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1997 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1998                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1999 config_host_data.set('CONFIG_FIEMAP',
2000                      cc.has_header('linux/fiemap.h') and
2001                      cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2002 config_host_data.set('CONFIG_GETRANDOM',
2003                      cc.has_function('getrandom') and
2004                      cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2005 config_host_data.set('CONFIG_INOTIFY',
2006                      cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
2007 config_host_data.set('CONFIG_INOTIFY1',
2008                      cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
2009 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
2010                      cc.has_header_symbol('machine/bswap.h', 'bswap32',
2011                                           prefix: '''#include <sys/endian.h>
2012                                                      #include <sys/types.h>'''))
2013 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2014                      cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2015 config_host_data.set('CONFIG_RTNETLINK',
2016                      cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2017 config_host_data.set('CONFIG_SYSMACROS',
2018                      cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2019 config_host_data.set('HAVE_OPTRESET',
2020                      cc.has_header_symbol('getopt.h', 'optreset'))
2021 config_host_data.set('HAVE_IPPROTO_MPTCP',
2022                      cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2023 config_host_data.set('HAVE_SYS_MOUNT_FSCONFIG',
2024                      cc.has_header_symbol('sys/mount.h', 'FSCONFIG_SET_FLAG'))
2026 # has_member
2027 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2028                      cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2029                                    prefix: '#include <signal.h>'))
2030 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2031                      cc.has_member('struct stat', 'st_atim',
2032                                    prefix: '#include <sys/stat.h>'))
2034 # has_type
2035 config_host_data.set('CONFIG_IOVEC',
2036                      cc.has_type('struct iovec',
2037                                  prefix: '#include <sys/uio.h>'))
2038 config_host_data.set('HAVE_UTMPX',
2039                      cc.has_type('struct utmpx',
2040                                  prefix: '#include <utmpx.h>'))
2042 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2043   #include <sys/eventfd.h>
2044   int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2045 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2046   #include <unistd.h>
2047   int main(void) {
2048   #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2049   return fdatasync(0);
2050   #else
2051   #error Not supported
2052   #endif
2053   }'''))
2055 has_madvise = cc.links(gnu_source_prefix + '''
2056   #include <sys/types.h>
2057   #include <sys/mman.h>
2058   #include <stddef.h>
2059   int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2060 missing_madvise_proto = false
2061 if has_madvise
2062   # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2063   # but forget to prototype it. In this case, has_madvise will be true (the
2064   # test program links despite a compile warning). To detect the
2065   # missing-prototype case, we try again with a definitely-bogus prototype.
2066   # This will only compile if the system headers don't provide the prototype;
2067   # otherwise the conflicting prototypes will cause a compiler error.
2068   missing_madvise_proto = cc.links(gnu_source_prefix + '''
2069     #include <sys/types.h>
2070     #include <sys/mman.h>
2071     #include <stddef.h>
2072     extern int madvise(int);
2073     int main(void) { return madvise(0); }''')
2074 endif
2075 config_host_data.set('CONFIG_MADVISE', has_madvise)
2076 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2078 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2079   #include <sys/mman.h>
2080   int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2081 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2082   #include <fcntl.h>
2083   #if !defined(AT_EMPTY_PATH)
2084   # error missing definition
2085   #else
2086   int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2087   #endif'''))
2088 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2089   #include <sys/mman.h>
2090   #include <stddef.h>
2091   int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2093 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2094   #include <pthread.h>
2096   static void *f(void *p) { return NULL; }
2097   int main(void)
2098   {
2099     pthread_t thread;
2100     pthread_create(&thread, 0, f, 0);
2101     pthread_setname_np(thread, "QEMU");
2102     return 0;
2103   }''', dependencies: threads))
2104 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2105   #include <pthread.h>
2107   static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2108   int main(void)
2109   {
2110     pthread_t thread;
2111     pthread_create(&thread, 0, f, 0);
2112     return 0;
2113   }''', dependencies: threads))
2114 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2115   #include <pthread.h>
2116   #include <time.h>
2118   int main(void)
2119   {
2120     pthread_condattr_t attr
2121     pthread_condattr_init(&attr);
2122     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2123     return 0;
2124   }''', dependencies: threads))
2126 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2127   #include <sys/signalfd.h>
2128   #include <stddef.h>
2129   int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2130 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2131   #include <unistd.h>
2132   #include <fcntl.h>
2133   #include <limits.h>
2135   int main(void)
2136   {
2137     int len, fd = 0;
2138     len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2139     splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2140     return 0;
2141   }'''))
2143 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2144   #include <sys/mman.h>
2145   int main(int argc, char *argv[]) {
2146     return mlockall(MCL_FUTURE);
2147   }'''))
2149 have_l2tpv3 = false
2150 if get_option('l2tpv3').allowed() and have_system
2151   have_l2tpv3 = cc.has_type('struct mmsghdr',
2152     prefix: gnu_source_prefix + '''
2153       #include <sys/socket.h>
2154       #include <linux/ip.h>''')
2155 endif
2156 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2158 have_netmap = false
2159 if get_option('netmap').allowed() and have_system
2160   have_netmap = cc.compiles('''
2161     #include <inttypes.h>
2162     #include <net/if.h>
2163     #include <net/netmap.h>
2164     #include <net/netmap_user.h>
2165     #if (NETMAP_API < 11) || (NETMAP_API > 15)
2166     #error
2167     #endif
2168     int main(void) { return 0; }''')
2169   if not have_netmap and get_option('netmap').enabled()
2170     error('Netmap headers not available')
2171   endif
2172 endif
2173 config_host_data.set('CONFIG_NETMAP', have_netmap)
2175 # Work around a system header bug with some kernel/XFS header
2176 # versions where they both try to define 'struct fsxattr':
2177 # xfs headers will not try to redefine structs from linux headers
2178 # if this macro is set.
2179 config_host_data.set('HAVE_FSXATTR', cc.links('''
2180   #include <linux/fs.h>
2181   struct fsxattr foo;
2182   int main(void) {
2183     return 0;
2184   }'''))
2186 # Some versions of Mac OS X incorrectly define SIZE_MAX
2187 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2188     #include <stdint.h>
2189     #include <stdio.h>
2190     int main(int argc, char *argv[]) {
2191         return printf("%zu", SIZE_MAX);
2192     }''', args: ['-Werror']))
2194 atomic_test = '''
2195   #include <stdint.h>
2196   int main(void)
2197   {
2198     @0@ x = 0, y = 0;
2199     y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2200     __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2201     __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2202     __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2203     __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2204     return 0;
2205   }'''
2207 # See if 64-bit atomic operations are supported.
2208 # Note that without __atomic builtins, we can only
2209 # assume atomic loads/stores max at pointer size.
2210 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
2212 has_int128 = cc.links('''
2213   __int128_t a;
2214   __uint128_t b;
2215   int main (void) {
2216     a = a + b;
2217     b = a * b;
2218     a = a * a;
2219     return 0;
2220   }''')
2222 config_host_data.set('CONFIG_INT128', has_int128)
2224 if has_int128
2225   # "do we have 128-bit atomics which are handled inline and specifically not
2226   # via libatomic". The reason we can't use libatomic is documented in the
2227   # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2228   has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
2230   config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2232   if not has_atomic128
2233     has_cmpxchg128 = cc.links('''
2234       int main(void)
2235       {
2236         unsigned __int128 x = 0, y = 0;
2237         __sync_val_compare_and_swap_16(&x, y, x);
2238         return 0;
2239       }
2240     ''')
2242     config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
2243   endif
2244 endif
2246 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2247   #include <sys/auxv.h>
2248   int main(void) {
2249     return getauxval(AT_HWCAP) == 0;
2250   }'''))
2252 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2253   #include <linux/usbdevice_fs.h>
2255   #ifndef USBDEVFS_GET_CAPABILITIES
2256   #error "USBDEVFS_GET_CAPABILITIES undefined"
2257   #endif
2259   #ifndef USBDEVFS_DISCONNECT_CLAIM
2260   #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2261   #endif
2263   int main(void) { return 0; }'''))
2265 have_keyring = get_option('keyring') \
2266   .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2267   .require(cc.compiles('''
2268     #include <errno.h>
2269     #include <asm/unistd.h>
2270     #include <linux/keyctl.h>
2271     #include <sys/syscall.h>
2272     #include <unistd.h>
2273     int main(void) {
2274         return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2275     }'''), error_message: 'keyctl syscall not available on this system').allowed()
2276 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2278 have_cpuid_h = cc.links('''
2279   #include <cpuid.h>
2280   int main(void) {
2281     unsigned a, b, c, d;
2282     unsigned max = __get_cpuid_max(0, 0);
2284     if (max >= 1) {
2285         __cpuid(1, a, b, c, d);
2286     }
2288     if (max >= 7) {
2289         __cpuid_count(7, 0, a, b, c, d);
2290     }
2292     return 0;
2293   }''')
2294 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2296 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2297   .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2298   .require(cc.links('''
2299     #pragma GCC push_options
2300     #pragma GCC target("avx2")
2301     #include <cpuid.h>
2302     #include <immintrin.h>
2303     static int bar(void *a) {
2304       __m256i x = *(__m256i *)a;
2305       return _mm256_testz_si256(x, x);
2306     }
2307     int main(int argc, char *argv[]) { return bar(argv[0]); }
2308   '''), error_message: 'AVX2 not available').allowed())
2310 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2311   .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2312   .require(cc.links('''
2313     #pragma GCC push_options
2314     #pragma GCC target("avx512f")
2315     #include <cpuid.h>
2316     #include <immintrin.h>
2317     static int bar(void *a) {
2318       __m512i x = *(__m512i *)a;
2319       return _mm512_test_epi64_mask(x, x);
2320     }
2321     int main(int argc, char *argv[]) { return bar(argv[0]); }
2322   '''), error_message: 'AVX512F not available').allowed())
2324 have_pvrdma = get_option('pvrdma') \
2325   .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2326   .require(cc.compiles(gnu_source_prefix + '''
2327     #include <sys/mman.h>
2328     int main(void)
2329     {
2330       char buf = 0;
2331       void *addr = &buf;
2332       addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2334       return 0;
2335     }'''), error_message: 'PVRDMA requires mremap').allowed()
2337 if have_pvrdma
2338   config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2339     #include <infiniband/verbs.h>
2340     int main(void)
2341     {
2342       struct ibv_mr *mr;
2343       struct ibv_pd *pd = NULL;
2344       size_t length = 10;
2345       uint64_t iova = 0;
2346       int access = 0;
2347       void *addr = NULL;
2349       mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2350       ibv_dereg_mr(mr);
2351       return 0;
2352     }'''))
2353 endif
2355 if get_option('membarrier').disabled()
2356   have_membarrier = false
2357 elif targetos == 'windows'
2358   have_membarrier = true
2359 elif targetos == 'linux'
2360   have_membarrier = cc.compiles('''
2361     #include <linux/membarrier.h>
2362     #include <sys/syscall.h>
2363     #include <unistd.h>
2364     #include <stdlib.h>
2365     int main(void) {
2366         syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2367         syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2368         exit(0);
2369     }''')
2370 endif
2371 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2372   .require(have_membarrier, error_message: 'membarrier system call not available') \
2373   .allowed())
2375 have_afalg = get_option('crypto_afalg') \
2376   .require(cc.compiles(gnu_source_prefix + '''
2377     #include <errno.h>
2378     #include <sys/types.h>
2379     #include <sys/socket.h>
2380     #include <linux/if_alg.h>
2381     int main(void) {
2382       int sock;
2383       sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2384       return sock;
2385     }
2386   '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2387 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2389 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2390   'linux/vm_sockets.h', 'AF_VSOCK',
2391   prefix: '#include <sys/socket.h>',
2394 have_vss = false
2395 have_vss_sdk = false # old xp/2003 SDK
2396 if targetos == 'windows' and link_language == 'cpp'
2397   have_vss = cxx.compiles('''
2398     #define __MIDL_user_allocate_free_DEFINED__
2399     #include <vss.h>
2400     int main(void) { return VSS_CTX_BACKUP; }''')
2401   have_vss_sdk = cxx.has_header('vscoordint.h')
2402 endif
2403 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2405 foreach k, v: config_host
2406   if k.startswith('CONFIG_')
2407     config_host_data.set(k, v == 'y' ? 1 : v)
2408   endif
2409 endforeach
2411 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2412 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2413 if targetos == 'windows'
2414   config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2415     #include <stdio.h>
2416     int main(void) {
2417       _lock_file(NULL);
2418       _unlock_file(NULL);
2419       return 0;
2420     }''', name: '_lock_file and _unlock_file'))
2421 endif
2423 ########################
2424 # Target configuration #
2425 ########################
2427 minikconf = find_program('scripts/minikconf.py')
2428 config_all = {}
2429 config_all_devices = {}
2430 config_all_disas = {}
2431 config_devices_mak_list = []
2432 config_devices_h = {}
2433 config_target_h = {}
2434 config_target_mak = {}
2436 disassemblers = {
2437   'alpha' : ['CONFIG_ALPHA_DIS'],
2438   'avr' : ['CONFIG_AVR_DIS'],
2439   'cris' : ['CONFIG_CRIS_DIS'],
2440   'hexagon' : ['CONFIG_HEXAGON_DIS'],
2441   'hppa' : ['CONFIG_HPPA_DIS'],
2442   'i386' : ['CONFIG_I386_DIS'],
2443   'x86_64' : ['CONFIG_I386_DIS'],
2444   'm68k' : ['CONFIG_M68K_DIS'],
2445   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2446   'mips' : ['CONFIG_MIPS_DIS'],
2447   'nios2' : ['CONFIG_NIOS2_DIS'],
2448   'or1k' : ['CONFIG_OPENRISC_DIS'],
2449   'ppc' : ['CONFIG_PPC_DIS'],
2450   'riscv' : ['CONFIG_RISCV_DIS'],
2451   'rx' : ['CONFIG_RX_DIS'],
2452   's390' : ['CONFIG_S390_DIS'],
2453   'sh4' : ['CONFIG_SH4_DIS'],
2454   'sparc' : ['CONFIG_SPARC_DIS'],
2455   'xtensa' : ['CONFIG_XTENSA_DIS'],
2456   'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2458 if link_language == 'cpp'
2459   disassemblers += {
2460     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2461   }
2462 endif
2464 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2465 host_kconfig = \
2466   (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2467   (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2468   (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2469   (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2470   (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2471   (x11.found() ? ['CONFIG_X11=y'] : []) + \
2472   (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2473   (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2474   (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2475   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2476   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2477   (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2478   (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2479   (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : [])
2481 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2483 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2484 actual_target_dirs = []
2485 fdt_required = []
2486 foreach target : target_dirs
2487   config_target = { 'TARGET_NAME': target.split('-')[0] }
2488   if target.endswith('linux-user')
2489     if targetos != 'linux'
2490       if default_targets
2491         continue
2492       endif
2493       error('Target @0@ is only available on a Linux host'.format(target))
2494     endif
2495     config_target += { 'CONFIG_LINUX_USER': 'y' }
2496   elif target.endswith('bsd-user')
2497     if 'CONFIG_BSD' not in config_host
2498       if default_targets
2499         continue
2500       endif
2501       error('Target @0@ is only available on a BSD host'.format(target))
2502     endif
2503     config_target += { 'CONFIG_BSD_USER': 'y' }
2504   elif target.endswith('softmmu')
2505     config_target += { 'CONFIG_SOFTMMU': 'y' }
2506   endif
2507   if target.endswith('-user')
2508     config_target += {
2509       'CONFIG_USER_ONLY': 'y',
2510       'CONFIG_QEMU_INTERP_PREFIX':
2511         get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2512     }
2513   endif
2515   accel_kconfig = []
2516   foreach sym: accelerators
2517     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2518       config_target += { sym: 'y' }
2519       config_all += { sym: 'y' }
2520       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2521         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2522       endif
2523       if target in modular_tcg
2524         config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2525       else
2526         config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2527       endif
2528       accel_kconfig += [ sym + '=y' ]
2529     endif
2530   endforeach
2531   if accel_kconfig.length() == 0
2532     if default_targets
2533       continue
2534     endif
2535     error('No accelerator available for target @0@'.format(target))
2536   endif
2538   actual_target_dirs += target
2539   config_target += keyval.load('configs/targets' / target + '.mak')
2540   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2542   if 'TARGET_NEED_FDT' in config_target
2543     fdt_required += target
2544   endif
2546   # Add default keys
2547   if 'TARGET_BASE_ARCH' not in config_target
2548     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2549   endif
2550   if 'TARGET_ABI_DIR' not in config_target
2551     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2552   endif
2553   if 'TARGET_BIG_ENDIAN' not in config_target
2554     config_target += {'TARGET_BIG_ENDIAN': 'n'}
2555   endif
2557   foreach k, v: disassemblers
2558     if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2559       foreach sym: v
2560         config_target += { sym: 'y' }
2561         config_all_disas += { sym: 'y' }
2562       endforeach
2563     endif
2564   endforeach
2566   config_target_data = configuration_data()
2567   foreach k, v: config_target
2568     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2569       # do nothing
2570     elif ignored.contains(k)
2571       # do nothing
2572     elif k == 'TARGET_BASE_ARCH'
2573       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2574       # not used to select files from sourcesets.
2575       config_target_data.set('TARGET_' + v.to_upper(), 1)
2576     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2577       config_target_data.set_quoted(k, v)
2578     elif v == 'y'
2579       config_target_data.set(k, 1)
2580     elif v == 'n'
2581       config_target_data.set(k, 0)
2582     else
2583       config_target_data.set(k, v)
2584     endif
2585   endforeach
2586   config_target_data.set('QEMU_ARCH',
2587                          'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2588   config_target_h += {target: configure_file(output: target + '-config-target.h',
2589                                                configuration: config_target_data)}
2591   if target.endswith('-softmmu')
2592     config_input = meson.get_external_property(target, 'default')
2593     config_devices_mak = target + '-config-devices.mak'
2594     config_devices_mak = configure_file(
2595       input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2596       output: config_devices_mak,
2597       depfile: config_devices_mak + '.d',
2598       capture: true,
2599       command: [minikconf,
2600                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2601                 config_devices_mak, '@DEPFILE@', '@INPUT@',
2602                 host_kconfig, accel_kconfig,
2603                 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2605     config_devices_data = configuration_data()
2606     config_devices = keyval.load(config_devices_mak)
2607     foreach k, v: config_devices
2608       config_devices_data.set(k, 1)
2609     endforeach
2610     config_devices_mak_list += config_devices_mak
2611     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2612                                                 configuration: config_devices_data)}
2613     config_target += config_devices
2614     config_all_devices += config_devices
2615   endif
2616   config_target_mak += {target: config_target}
2617 endforeach
2618 target_dirs = actual_target_dirs
2620 # This configuration is used to build files that are shared by
2621 # multiple binaries, and then extracted out of the "common"
2622 # static_library target.
2624 # We do not use all_sources()/all_dependencies(), because it would
2625 # build literally all source files, including devices only used by
2626 # targets that are not built for this compilation.  The CONFIG_ALL
2627 # pseudo symbol replaces it.
2629 config_all += config_all_devices
2630 config_all += config_host
2631 config_all += config_all_disas
2632 config_all += {
2633   'CONFIG_XEN': xen.found(),
2634   'CONFIG_SOFTMMU': have_system,
2635   'CONFIG_USER_ONLY': have_user,
2636   'CONFIG_ALL': true,
2639 target_configs_h = []
2640 foreach target: target_dirs
2641   target_configs_h += config_target_h[target]
2642   target_configs_h += config_devices_h.get(target, [])
2643 endforeach
2644 genh += custom_target('config-poison.h',
2645                       input: [target_configs_h],
2646                       output: 'config-poison.h',
2647                       capture: true,
2648                       command: [find_program('scripts/make-config-poison.sh'),
2649                                 target_configs_h])
2651 ##############
2652 # Submodules #
2653 ##############
2655 capstone = not_found
2656 if not get_option('capstone').auto() or have_system or have_user
2657   capstone = dependency('capstone', version: '>=3.0.5',
2658                         kwargs: static_kwargs, method: 'pkg-config',
2659                         required: get_option('capstone'))
2661   # Some versions of capstone have broken pkg-config file
2662   # that reports a wrong -I path, causing the #include to
2663   # fail later. If the system has such a broken version
2664   # do not use it.
2665   if capstone.found() and not cc.compiles('#include <capstone.h>',
2666                                           dependencies: [capstone])
2667     capstone = not_found
2668     if get_option('capstone').enabled()
2669       error('capstone requested, but it does not appear to work')
2670     endif
2671   endif
2672 endif
2674 libvfio_user_dep = not_found
2675 if have_system and vfio_user_server_allowed
2676   have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
2678   if not have_internal
2679     error('libvfio-user source not found - please pull git submodule')
2680   endif
2682   libvfio_user_proj = subproject('libvfio-user')
2684   libvfio_user_lib = libvfio_user_proj.get_variable('libvfio_user_dep')
2686   libvfio_user_dep = declare_dependency(dependencies: [libvfio_user_lib])
2687 endif
2689 fdt = not_found
2690 if have_system
2691   fdt_opt = get_option('fdt')
2692   if fdt_opt in ['enabled', 'auto', 'system']
2693     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2694     fdt = cc.find_library('fdt', kwargs: static_kwargs,
2695                           required: fdt_opt == 'system' or
2696                                     fdt_opt == 'enabled' and not have_internal)
2697     if fdt.found() and cc.links('''
2698        #include <libfdt.h>
2699        #include <libfdt_env.h>
2700        int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2701          dependencies: fdt)
2702       fdt_opt = 'system'
2703     elif fdt_opt == 'system'
2704        error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2705     elif have_internal
2706       fdt_opt = 'internal'
2707     else
2708       fdt_opt = 'disabled'
2709       fdt = not_found
2710     endif
2711   endif
2712   if fdt_opt == 'internal'
2713     fdt_files = files(
2714       'dtc/libfdt/fdt.c',
2715       'dtc/libfdt/fdt_ro.c',
2716       'dtc/libfdt/fdt_wip.c',
2717       'dtc/libfdt/fdt_sw.c',
2718       'dtc/libfdt/fdt_rw.c',
2719       'dtc/libfdt/fdt_strerror.c',
2720       'dtc/libfdt/fdt_empty_tree.c',
2721       'dtc/libfdt/fdt_addresses.c',
2722       'dtc/libfdt/fdt_overlay.c',
2723       'dtc/libfdt/fdt_check.c',
2724     )
2726     fdt_inc = include_directories('dtc/libfdt')
2727     libfdt = static_library('fdt',
2728                             build_by_default: false,
2729                             sources: fdt_files,
2730                             include_directories: fdt_inc)
2731     fdt = declare_dependency(link_with: libfdt,
2732                              include_directories: fdt_inc)
2733   endif
2734 else
2735   fdt_opt = 'disabled'
2736 endif
2737 if not fdt.found() and fdt_required.length() > 0
2738   error('fdt not available but required by targets ' + ', '.join(fdt_required))
2739 endif
2741 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2742 config_host_data.set('CONFIG_FDT', fdt.found())
2743 config_host_data.set('CONFIG_SLIRP', slirp.found())
2745 #####################
2746 # Generated sources #
2747 #####################
2749 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2751 hxtool = find_program('scripts/hxtool')
2752 shaderinclude = find_program('scripts/shaderinclude.pl')
2753 qapi_gen = find_program('scripts/qapi-gen.py')
2754 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2755                      meson.current_source_dir() / 'scripts/qapi/commands.py',
2756                      meson.current_source_dir() / 'scripts/qapi/common.py',
2757                      meson.current_source_dir() / 'scripts/qapi/error.py',
2758                      meson.current_source_dir() / 'scripts/qapi/events.py',
2759                      meson.current_source_dir() / 'scripts/qapi/expr.py',
2760                      meson.current_source_dir() / 'scripts/qapi/gen.py',
2761                      meson.current_source_dir() / 'scripts/qapi/introspect.py',
2762                      meson.current_source_dir() / 'scripts/qapi/parser.py',
2763                      meson.current_source_dir() / 'scripts/qapi/schema.py',
2764                      meson.current_source_dir() / 'scripts/qapi/source.py',
2765                      meson.current_source_dir() / 'scripts/qapi/types.py',
2766                      meson.current_source_dir() / 'scripts/qapi/visit.py',
2767                      meson.current_source_dir() / 'scripts/qapi/common.py',
2768                      meson.current_source_dir() / 'scripts/qapi-gen.py'
2771 tracetool = [
2772   python, files('scripts/tracetool.py'),
2773    '--backend=' + ','.join(get_option('trace_backends'))
2775 tracetool_depends = files(
2776   'scripts/tracetool/backend/log.py',
2777   'scripts/tracetool/backend/__init__.py',
2778   'scripts/tracetool/backend/dtrace.py',
2779   'scripts/tracetool/backend/ftrace.py',
2780   'scripts/tracetool/backend/simple.py',
2781   'scripts/tracetool/backend/syslog.py',
2782   'scripts/tracetool/backend/ust.py',
2783   'scripts/tracetool/format/ust_events_c.py',
2784   'scripts/tracetool/format/ust_events_h.py',
2785   'scripts/tracetool/format/__init__.py',
2786   'scripts/tracetool/format/d.py',
2787   'scripts/tracetool/format/simpletrace_stap.py',
2788   'scripts/tracetool/format/c.py',
2789   'scripts/tracetool/format/h.py',
2790   'scripts/tracetool/format/log_stap.py',
2791   'scripts/tracetool/format/stap.py',
2792   'scripts/tracetool/__init__.py',
2793   'scripts/tracetool/transform.py',
2794   'scripts/tracetool/vcpu.py'
2797 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2798                     meson.current_source_dir(),
2799                     get_option('pkgversion'), meson.project_version()]
2800 qemu_version = custom_target('qemu-version.h',
2801                              output: 'qemu-version.h',
2802                              command: qemu_version_cmd,
2803                              capture: true,
2804                              build_by_default: true,
2805                              build_always_stale: true)
2806 genh += qemu_version
2808 hxdep = []
2809 hx_headers = [
2810   ['qemu-options.hx', 'qemu-options.def'],
2811   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2813 if have_system
2814   hx_headers += [
2815     ['hmp-commands.hx', 'hmp-commands.h'],
2816     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2817   ]
2818 endif
2819 foreach d : hx_headers
2820   hxdep += custom_target(d[1],
2821                 input: files(d[0]),
2822                 output: d[1],
2823                 capture: true,
2824                 build_by_default: true, # to be removed when added to a target
2825                 command: [hxtool, '-h', '@INPUT0@'])
2826 endforeach
2827 genh += hxdep
2829 ###################
2830 # Collect sources #
2831 ###################
2833 authz_ss = ss.source_set()
2834 blockdev_ss = ss.source_set()
2835 block_ss = ss.source_set()
2836 chardev_ss = ss.source_set()
2837 common_ss = ss.source_set()
2838 crypto_ss = ss.source_set()
2839 hwcore_ss = ss.source_set()
2840 io_ss = ss.source_set()
2841 qmp_ss = ss.source_set()
2842 qom_ss = ss.source_set()
2843 softmmu_ss = ss.source_set()
2844 specific_fuzz_ss = ss.source_set()
2845 specific_ss = ss.source_set()
2846 stub_ss = ss.source_set()
2847 trace_ss = ss.source_set()
2848 user_ss = ss.source_set()
2849 util_ss = ss.source_set()
2851 # accel modules
2852 qtest_module_ss = ss.source_set()
2853 tcg_module_ss = ss.source_set()
2855 modules = {}
2856 target_modules = {}
2857 hw_arch = {}
2858 target_arch = {}
2859 target_softmmu_arch = {}
2860 target_user_arch = {}
2862 ###############
2863 # Trace files #
2864 ###############
2866 # TODO: add each directory to the subdirs from its own meson.build, once
2867 # we have those
2868 trace_events_subdirs = [
2869   'crypto',
2870   'qapi',
2871   'qom',
2872   'monitor',
2873   'util',
2874   'gdbstub',
2876 if have_linux_user
2877   trace_events_subdirs += [ 'linux-user' ]
2878 endif
2879 if have_bsd_user
2880   trace_events_subdirs += [ 'bsd-user' ]
2881 endif
2882 if have_block
2883   trace_events_subdirs += [
2884     'authz',
2885     'block',
2886     'io',
2887     'nbd',
2888     'scsi',
2889   ]
2890 endif
2891 if have_system
2892   trace_events_subdirs += [
2893     'accel/kvm',
2894     'audio',
2895     'backends',
2896     'backends/tpm',
2897     'chardev',
2898     'ebpf',
2899     'hw/9pfs',
2900     'hw/acpi',
2901     'hw/adc',
2902     'hw/alpha',
2903     'hw/arm',
2904     'hw/audio',
2905     'hw/block',
2906     'hw/block/dataplane',
2907     'hw/char',
2908     'hw/display',
2909     'hw/dma',
2910     'hw/hyperv',
2911     'hw/i2c',
2912     'hw/i386',
2913     'hw/i386/xen',
2914     'hw/ide',
2915     'hw/input',
2916     'hw/intc',
2917     'hw/isa',
2918     'hw/mem',
2919     'hw/mips',
2920     'hw/misc',
2921     'hw/misc/macio',
2922     'hw/net',
2923     'hw/net/can',
2924     'hw/nubus',
2925     'hw/nvme',
2926     'hw/nvram',
2927     'hw/pci',
2928     'hw/pci-host',
2929     'hw/ppc',
2930     'hw/rdma',
2931     'hw/rdma/vmw',
2932     'hw/rtc',
2933     'hw/s390x',
2934     'hw/scsi',
2935     'hw/sd',
2936     'hw/sh4',
2937     'hw/sparc',
2938     'hw/sparc64',
2939     'hw/ssi',
2940     'hw/timer',
2941     'hw/tpm',
2942     'hw/usb',
2943     'hw/vfio',
2944     'hw/virtio',
2945     'hw/watchdog',
2946     'hw/xen',
2947     'hw/gpio',
2948     'migration',
2949     'net',
2950     'softmmu',
2951     'ui',
2952     'hw/remote',
2953   ]
2954 endif
2955 if have_system or have_user
2956   trace_events_subdirs += [
2957     'accel/tcg',
2958     'hw/core',
2959     'target/arm',
2960     'target/arm/hvf',
2961     'target/hppa',
2962     'target/i386',
2963     'target/i386/kvm',
2964     'target/mips/tcg',
2965     'target/nios2',
2966     'target/ppc',
2967     'target/riscv',
2968     'target/s390x',
2969     'target/s390x/kvm',
2970     'target/sparc',
2971   ]
2972 endif
2974 vhost_user = not_found
2975 if targetos == 'linux' and have_vhost_user
2976   libvhost_user = subproject('libvhost-user')
2977   vhost_user = libvhost_user.get_variable('vhost_user_dep')
2978 endif
2980 libvduse = not_found
2981 if have_libvduse
2982   libvduse_proj = subproject('libvduse')
2983   libvduse = libvduse_proj.get_variable('libvduse_dep')
2984 endif
2986 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2987 # that is filled in by qapi/.
2988 subdir('qapi')
2989 subdir('qobject')
2990 subdir('stubs')
2991 subdir('trace')
2992 subdir('util')
2993 subdir('qom')
2994 subdir('authz')
2995 subdir('crypto')
2996 subdir('ui')
2997 subdir('hw')
2998 subdir('gdbstub')
3001 if enable_modules
3002   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3003   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3004 endif
3006 qom_ss = qom_ss.apply(config_host, strict: false)
3007 libqom = static_library('qom', qom_ss.sources() + genh,
3008                         dependencies: [qom_ss.dependencies()],
3009                         name_suffix: 'fa')
3010 qom = declare_dependency(link_whole: libqom)
3012 event_loop_base = files('event-loop-base.c')
3013 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3014                                  build_by_default: true)
3015 event_loop_base = declare_dependency(link_whole: event_loop_base,
3016                                      dependencies: [qom])
3018 stub_ss = stub_ss.apply(config_all, strict: false)
3020 util_ss.add_all(trace_ss)
3021 util_ss = util_ss.apply(config_all, strict: false)
3022 libqemuutil = static_library('qemuutil',
3023                              sources: util_ss.sources() + stub_ss.sources() + genh,
3024                              dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3025 qemuutil = declare_dependency(link_with: libqemuutil,
3026                               sources: genh + version_res,
3027                               dependencies: [event_loop_base])
3029 if have_system or have_user
3030   decodetree = generator(find_program('scripts/decodetree.py'),
3031                          output: 'decode-@BASENAME@.c.inc',
3032                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3033   subdir('libdecnumber')
3034   subdir('target')
3035 endif
3037 subdir('audio')
3038 subdir('io')
3039 subdir('chardev')
3040 subdir('fsdev')
3041 subdir('dump')
3043 if have_block
3044   block_ss.add(files(
3045     'block.c',
3046     'blockjob.c',
3047     'job.c',
3048     'qemu-io-cmds.c',
3049   ))
3050   if config_host_data.get('CONFIG_REPLICATION')
3051     block_ss.add(files('replication.c'))
3052   endif
3054   subdir('nbd')
3055   subdir('scsi')
3056   subdir('block')
3058   blockdev_ss.add(files(
3059     'blockdev.c',
3060     'blockdev-nbd.c',
3061     'iothread.c',
3062     'job-qmp.c',
3063   ), gnutls)
3065   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3066   # os-win32.c does not
3067   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3068   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3069 endif
3071 common_ss.add(files('cpus-common.c'))
3073 subdir('softmmu')
3075 common_ss.add(capstone)
3076 specific_ss.add(files('cpu.c', 'disas.c'), capstone)
3078 # Work around a gcc bug/misfeature wherein constant propagation looks
3079 # through an alias:
3080 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3081 # to guess that a const variable is always zero.  Without lto, this is
3082 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
3083 # without lto, not even the alias is required -- we simply use different
3084 # declarations in different compilation units.
3085 pagevary = files('page-vary-common.c')
3086 if get_option('b_lto')
3087   pagevary_flags = ['-fno-lto']
3088   if get_option('cfi')
3089     pagevary_flags += '-fno-sanitize=cfi-icall'
3090   endif
3091   pagevary = static_library('page-vary-common', sources: pagevary + genh,
3092                             c_args: pagevary_flags)
3093   pagevary = declare_dependency(link_with: pagevary)
3094 endif
3095 common_ss.add(pagevary)
3096 specific_ss.add(files('page-vary.c'))
3098 subdir('backends')
3099 subdir('disas')
3100 subdir('migration')
3101 subdir('monitor')
3102 subdir('net')
3103 subdir('replay')
3104 subdir('semihosting')
3105 subdir('tcg')
3106 subdir('fpu')
3107 subdir('accel')
3108 subdir('plugins')
3109 subdir('ebpf')
3111 common_user_inc = []
3113 subdir('common-user')
3114 subdir('bsd-user')
3115 subdir('linux-user')
3117 # needed for fuzzing binaries
3118 subdir('tests/qtest/libqos')
3119 subdir('tests/qtest/fuzz')
3121 # accel modules
3122 tcg_real_module_ss = ss.source_set()
3123 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3124 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3125 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3126                                 'tcg': tcg_real_module_ss }}
3128 ########################
3129 # Library dependencies #
3130 ########################
3132 modinfo_collect = find_program('scripts/modinfo-collect.py')
3133 modinfo_generate = find_program('scripts/modinfo-generate.py')
3134 modinfo_files = []
3136 block_mods = []
3137 softmmu_mods = []
3138 foreach d, list : modules
3139   foreach m, module_ss : list
3140     if enable_modules and targetos != 'windows'
3141       module_ss = module_ss.apply(config_all, strict: false)
3142       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3143                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3144       if d == 'block'
3145         block_mods += sl
3146       else
3147         softmmu_mods += sl
3148       endif
3149       if module_ss.sources() != []
3150         # FIXME: Should use sl.extract_all_objects(recursive: true) as
3151         # input. Sources can be used multiple times but objects are
3152         # unique when it comes to lookup in compile_commands.json.
3153         # Depnds on a mesion version with
3154         # https://github.com/mesonbuild/meson/pull/8900
3155         modinfo_files += custom_target(d + '-' + m + '.modinfo',
3156                                        output: d + '-' + m + '.modinfo',
3157                                        input: module_ss.sources() + genh,
3158                                        capture: true,
3159                                        command: [modinfo_collect, module_ss.sources()])
3160       endif
3161     else
3162       if d == 'block'
3163         block_ss.add_all(module_ss)
3164       else
3165         softmmu_ss.add_all(module_ss)
3166       endif
3167     endif
3168   endforeach
3169 endforeach
3171 foreach d, list : target_modules
3172   foreach m, module_ss : list
3173     if enable_modules and targetos != 'windows'
3174       foreach target : target_dirs
3175         if target.endswith('-softmmu')
3176           config_target = config_target_mak[target]
3177           config_target += config_host
3178           target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3179           c_args = ['-DNEED_CPU_H',
3180                     '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3181                     '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3182           target_module_ss = module_ss.apply(config_target, strict: false)
3183           if target_module_ss.sources() != []
3184             module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3185             sl = static_library(module_name,
3186                                 [genh, target_module_ss.sources()],
3187                                 dependencies: [modulecommon, target_module_ss.dependencies()],
3188                                 include_directories: target_inc,
3189                                 c_args: c_args,
3190                                 pic: true)
3191             softmmu_mods += sl
3192             # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3193             modinfo_files += custom_target(module_name + '.modinfo',
3194                                            output: module_name + '.modinfo',
3195                                            input: target_module_ss.sources() + genh,
3196                                            capture: true,
3197                                            command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3198           endif
3199         endif
3200       endforeach
3201     else
3202       specific_ss.add_all(module_ss)
3203     endif
3204   endforeach
3205 endforeach
3207 if enable_modules
3208   foreach target : target_dirs
3209     if target.endswith('-softmmu')
3210       config_target = config_target_mak[target]
3211       config_devices_mak = target + '-config-devices.mak'
3212       modinfo_src = custom_target('modinfo-' + target + '.c',
3213                                   output: 'modinfo-' + target + '.c',
3214                                   input: modinfo_files,
3215                                   command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3216                                   capture: true)
3218       modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3219       modinfo_dep = declare_dependency(link_with: modinfo_lib)
3221       arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3222       hw_arch[arch].add(modinfo_dep)
3223     endif
3224   endforeach
3225 endif
3227 nm = find_program('nm')
3228 undefsym = find_program('scripts/undefsym.py')
3229 block_syms = custom_target('block.syms', output: 'block.syms',
3230                              input: [libqemuutil, block_mods],
3231                              capture: true,
3232                              command: [undefsym, nm, '@INPUT@'])
3233 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3234                              input: [libqemuutil, softmmu_mods],
3235                              capture: true,
3236                              command: [undefsym, nm, '@INPUT@'])
3238 authz_ss = authz_ss.apply(config_host, strict: false)
3239 libauthz = static_library('authz', authz_ss.sources() + genh,
3240                           dependencies: [authz_ss.dependencies()],
3241                           name_suffix: 'fa',
3242                           build_by_default: false)
3244 authz = declare_dependency(link_whole: libauthz,
3245                            dependencies: qom)
3247 crypto_ss = crypto_ss.apply(config_host, strict: false)
3248 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3249                            dependencies: [crypto_ss.dependencies()],
3250                            name_suffix: 'fa',
3251                            build_by_default: false)
3253 crypto = declare_dependency(link_whole: libcrypto,
3254                             dependencies: [authz, qom])
3256 io_ss = io_ss.apply(config_host, strict: false)
3257 libio = static_library('io', io_ss.sources() + genh,
3258                        dependencies: [io_ss.dependencies()],
3259                        link_with: libqemuutil,
3260                        name_suffix: 'fa',
3261                        build_by_default: false)
3263 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3265 libmigration = static_library('migration', sources: migration_files + genh,
3266                               name_suffix: 'fa',
3267                               build_by_default: false)
3268 migration = declare_dependency(link_with: libmigration,
3269                                dependencies: [zlib, qom, io])
3270 softmmu_ss.add(migration)
3272 block_ss = block_ss.apply(config_host, strict: false)
3273 libblock = static_library('block', block_ss.sources() + genh,
3274                           dependencies: block_ss.dependencies(),
3275                           link_depends: block_syms,
3276                           name_suffix: 'fa',
3277                           build_by_default: false)
3279 block = declare_dependency(link_whole: [libblock],
3280                            link_args: '@block.syms',
3281                            dependencies: [crypto, io])
3283 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3284 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3285                              dependencies: blockdev_ss.dependencies(),
3286                              name_suffix: 'fa',
3287                              build_by_default: false)
3289 blockdev = declare_dependency(link_whole: [libblockdev],
3290                               dependencies: [block, event_loop_base])
3292 qmp_ss = qmp_ss.apply(config_host, strict: false)
3293 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3294                         dependencies: qmp_ss.dependencies(),
3295                         name_suffix: 'fa',
3296                         build_by_default: false)
3298 qmp = declare_dependency(link_whole: [libqmp])
3300 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3301                             name_suffix: 'fa',
3302                             dependencies: chardev_ss.dependencies(),
3303                             build_by_default: false)
3305 chardev = declare_dependency(link_whole: libchardev)
3307 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3308 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3309                            name_suffix: 'fa',
3310                            build_by_default: false)
3311 hwcore = declare_dependency(link_whole: libhwcore)
3312 common_ss.add(hwcore)
3314 ###########
3315 # Targets #
3316 ###########
3318 emulator_modules = []
3319 foreach m : block_mods + softmmu_mods
3320   emulator_modules += shared_module(m.name(),
3321                 build_by_default: true,
3322                 name_prefix: '',
3323                 link_whole: m,
3324                 install: true,
3325                 install_dir: qemu_moddir)
3326 endforeach
3327 if emulator_modules.length() > 0
3328   alias_target('modules', emulator_modules)
3329 endif
3331 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3332 common_ss.add(qom, qemuutil)
3334 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3335 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3337 common_all = common_ss.apply(config_all, strict: false)
3338 common_all = static_library('common',
3339                             build_by_default: false,
3340                             sources: common_all.sources() + genh,
3341                             include_directories: common_user_inc,
3342                             implicit_include_directories: false,
3343                             dependencies: common_all.dependencies(),
3344                             name_suffix: 'fa')
3346 feature_to_c = find_program('scripts/feature_to_c.sh')
3348 if targetos == 'darwin'
3349   entitlement = find_program('scripts/entitlement.sh')
3350 endif
3352 emulators = {}
3353 foreach target : target_dirs
3354   config_target = config_target_mak[target]
3355   target_name = config_target['TARGET_NAME']
3356   target_base_arch = config_target['TARGET_BASE_ARCH']
3357   arch_srcs = [config_target_h[target]]
3358   arch_deps = []
3359   c_args = ['-DNEED_CPU_H',
3360             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3361             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3362   link_args = emulator_link_args
3364   config_target += config_host
3365   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3366   if targetos == 'linux'
3367     target_inc += include_directories('linux-headers', is_system: true)
3368   endif
3369   if target.endswith('-softmmu')
3370     target_type='system'
3371     t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3372     arch_srcs += t.sources()
3373     arch_deps += t.dependencies()
3375     hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3376     hw = hw_arch[hw_dir].apply(config_target, strict: false)
3377     arch_srcs += hw.sources()
3378     arch_deps += hw.dependencies()
3380     arch_srcs += config_devices_h[target]
3381     link_args += ['@block.syms', '@qemu.syms']
3382   else
3383     abi = config_target['TARGET_ABI_DIR']
3384     target_type='user'
3385     target_inc += common_user_inc
3386     if target_base_arch in target_user_arch
3387       t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3388       arch_srcs += t.sources()
3389       arch_deps += t.dependencies()
3390     endif
3391     if 'CONFIG_LINUX_USER' in config_target
3392       base_dir = 'linux-user'
3393     endif
3394     if 'CONFIG_BSD_USER' in config_target
3395       base_dir = 'bsd-user'
3396       target_inc += include_directories('bsd-user/' / targetos)
3397       target_inc += include_directories('bsd-user/host/' / host_arch)
3398       dir = base_dir / abi
3399       arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3400     endif
3401     target_inc += include_directories(
3402       base_dir,
3403       base_dir / abi,
3404     )
3405     if 'CONFIG_LINUX_USER' in config_target
3406       dir = base_dir / abi
3407       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3408       if config_target.has_key('TARGET_SYSTBL_ABI')
3409         arch_srcs += \
3410           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3411                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
3412       endif
3413     endif
3414   endif
3416   if 'TARGET_XML_FILES' in config_target
3417     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3418                                 output: target + '-gdbstub-xml.c',
3419                                 input: files(config_target['TARGET_XML_FILES'].split()),
3420                                 command: [feature_to_c, '@INPUT@'],
3421                                 capture: true)
3422     arch_srcs += gdbstub_xml
3423   endif
3425   t = target_arch[target_base_arch].apply(config_target, strict: false)
3426   arch_srcs += t.sources()
3427   arch_deps += t.dependencies()
3429   target_common = common_ss.apply(config_target, strict: false)
3430   objects = common_all.extract_objects(target_common.sources())
3431   deps = target_common.dependencies()
3433   target_specific = specific_ss.apply(config_target, strict: false)
3434   arch_srcs += target_specific.sources()
3435   arch_deps += target_specific.dependencies()
3437   lib = static_library('qemu-' + target,
3438                  sources: arch_srcs + genh,
3439                  dependencies: arch_deps,
3440                  objects: objects,
3441                  include_directories: target_inc,
3442                  c_args: c_args,
3443                  build_by_default: false,
3444                  name_suffix: 'fa')
3446   if target.endswith('-softmmu')
3447     execs = [{
3448       'name': 'qemu-system-' + target_name,
3449       'win_subsystem': 'console',
3450       'sources': files('softmmu/main.c'),
3451       'dependencies': []
3452     }]
3453     if targetos == 'windows' and (sdl.found() or gtk.found())
3454       execs += [{
3455         'name': 'qemu-system-' + target_name + 'w',
3456         'win_subsystem': 'windows',
3457         'sources': files('softmmu/main.c'),
3458         'dependencies': []
3459       }]
3460     endif
3461     if get_option('fuzzing')
3462       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3463       execs += [{
3464         'name': 'qemu-fuzz-' + target_name,
3465         'win_subsystem': 'console',
3466         'sources': specific_fuzz.sources(),
3467         'dependencies': specific_fuzz.dependencies(),
3468       }]
3469     endif
3470   else
3471     execs = [{
3472       'name': 'qemu-' + target_name,
3473       'win_subsystem': 'console',
3474       'sources': [],
3475       'dependencies': []
3476     }]
3477   endif
3478   foreach exe: execs
3479     exe_name = exe['name']
3480     if targetos == 'darwin'
3481       exe_name += '-unsigned'
3482     endif
3484     emulator = executable(exe_name, exe['sources'],
3485                install: true,
3486                c_args: c_args,
3487                dependencies: arch_deps + deps + exe['dependencies'],
3488                objects: lib.extract_all_objects(recursive: true),
3489                link_language: link_language,
3490                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3491                link_args: link_args,
3492                win_subsystem: exe['win_subsystem'])
3494     if targetos == 'darwin'
3495       icon = 'pc-bios/qemu.rsrc'
3496       build_input = [emulator, files(icon)]
3497       install_input = [
3498         get_option('bindir') / exe_name,
3499         meson.current_source_dir() / icon
3500       ]
3501       if 'CONFIG_HVF' in config_target
3502         entitlements = 'accel/hvf/entitlements.plist'
3503         build_input += files(entitlements)
3504         install_input += meson.current_source_dir() / entitlements
3505       endif
3507       emulators += {exe['name'] : custom_target(exe['name'],
3508                    input: build_input,
3509                    output: exe['name'],
3510                    command: [entitlement, '@OUTPUT@', '@INPUT@'])
3511       }
3513       meson.add_install_script(entitlement, '--install',
3514                                get_option('bindir') / exe['name'],
3515                                install_input)
3516     else
3517       emulators += {exe['name']: emulator}
3518     endif
3520     if stap.found()
3521       foreach stp: [
3522         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3523         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3524         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3525         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3526       ]
3527         custom_target(exe['name'] + stp['ext'],
3528                       input: trace_events_all,
3529                       output: exe['name'] + stp['ext'],
3530                       install: stp['install'],
3531                       install_dir: get_option('datadir') / 'systemtap/tapset',
3532                       command: [
3533                         tracetool, '--group=all', '--format=' + stp['fmt'],
3534                         '--binary=' + stp['bin'],
3535                         '--target-name=' + target_name,
3536                         '--target-type=' + target_type,
3537                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
3538                         '@INPUT@', '@OUTPUT@'
3539                       ],
3540                       depend_files: tracetool_depends)
3541       endforeach
3542     endif
3543   endforeach
3544 endforeach
3546 # Other build targets
3548 if 'CONFIG_PLUGIN' in config_host
3549   install_headers('include/qemu/qemu-plugin.h')
3550 endif
3552 subdir('qga')
3554 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3555 # when we don't build tools or system
3556 if xkbcommon.found()
3557   # used for the update-keymaps target, so include rules even if !have_tools
3558   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3559                            dependencies: [qemuutil, xkbcommon], install: have_tools)
3560 endif
3562 if have_tools
3563   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3564              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3565   qemu_io = executable('qemu-io', files('qemu-io.c'),
3566              dependencies: [block, qemuutil], install: true)
3567   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3568                dependencies: [blockdev, qemuutil, gnutls, selinux],
3569                install: true)
3571   subdir('storage-daemon')
3572   subdir('contrib/rdmacm-mux')
3573   subdir('contrib/elf2dmp')
3575   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3576              dependencies: qemuutil,
3577              install: true)
3579   if have_vhost_user
3580     subdir('contrib/vhost-user-blk')
3581     subdir('contrib/vhost-user-gpu')
3582     subdir('contrib/vhost-user-input')
3583     subdir('contrib/vhost-user-scsi')
3584   endif
3586   if targetos == 'linux'
3587     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3588                dependencies: [qemuutil, libcap_ng],
3589                install: true,
3590                install_dir: get_option('libexecdir'))
3592     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3593                dependencies: [authz, crypto, io, qom, qemuutil,
3594                               libcap_ng, mpathpersist],
3595                install: true)
3596   endif
3598   if have_ivshmem
3599     subdir('contrib/ivshmem-client')
3600     subdir('contrib/ivshmem-server')
3601   endif
3602 endif
3604 subdir('scripts')
3605 subdir('tools')
3606 subdir('pc-bios')
3607 subdir('docs')
3608 subdir('tests')
3609 if gtk.found()
3610   subdir('po')
3611 endif
3613 if host_machine.system() == 'windows'
3614   nsis_cmd = [
3615     find_program('scripts/nsis.py'),
3616     '@OUTPUT@',
3617     get_option('prefix'),
3618     meson.current_source_dir(),
3619     config_host['GLIB_BINDIR'],
3620     host_machine.cpu(),
3621     '--',
3622     '-DDISPLAYVERSION=' + meson.project_version(),
3623   ]
3624   if build_docs
3625     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3626   endif
3627   if gtk.found()
3628     nsis_cmd += '-DCONFIG_GTK=y'
3629   endif
3631   nsis = custom_target('nsis',
3632                        output: 'qemu-setup-' + meson.project_version() + '.exe',
3633                        input: files('qemu.nsi'),
3634                        build_always_stale: true,
3635                        command: nsis_cmd + ['@INPUT@'])
3636   alias_target('installer', nsis)
3637 endif
3639 #########################
3640 # Configuration summary #
3641 #########################
3643 # Directories
3644 summary_info = {}
3645 summary_info += {'Install prefix':    get_option('prefix')}
3646 summary_info += {'BIOS directory':    qemu_datadir}
3647 pathsep = targetos == 'windows' ? ';' : ':'
3648 summary_info += {'firmware path':     pathsep.join(get_option('qemu_firmwarepath'))}
3649 summary_info += {'binary directory':  get_option('prefix') / get_option('bindir')}
3650 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3651 summary_info += {'module directory':  qemu_moddir}
3652 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3653 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3654 summary_info += {'config directory':  get_option('prefix') / get_option('sysconfdir')}
3655 if targetos != 'windows'
3656   summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3657   summary_info += {'Manual directory':      get_option('prefix') / get_option('mandir')}
3658 else
3659   summary_info += {'local state directory': 'queried at runtime'}
3660 endif
3661 summary_info += {'Doc directory':     get_option('prefix') / get_option('docdir')}
3662 summary_info += {'Build directory':   meson.current_build_dir()}
3663 summary_info += {'Source path':       meson.current_source_dir()}
3664 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
3665 summary(summary_info, bool_yn: true, section: 'Directories')
3667 # Host binaries
3668 summary_info = {}
3669 summary_info += {'git':               config_host['GIT']}
3670 summary_info += {'make':              config_host['MAKE']}
3671 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3672 summary_info += {'sphinx-build':      sphinx_build}
3673 if config_host.has_key('HAVE_GDB_BIN')
3674   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
3675 endif
3676 summary_info += {'iasl':              iasl}
3677 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
3678 if targetos == 'windows' and have_ga
3679   summary_info += {'wixl':            wixl}
3680 endif
3681 if slirp.found() and have_system
3682   summary_info += {'smbd':            have_slirp_smbd ? smbd_path : false}
3683 endif
3684 summary(summary_info, bool_yn: true, section: 'Host binaries')
3686 # Configurable features
3687 summary_info = {}
3688 summary_info += {'Documentation':     build_docs}
3689 summary_info += {'system-mode emulation': have_system}
3690 summary_info += {'user-mode emulation': have_user}
3691 summary_info += {'block layer':       have_block}
3692 summary_info += {'Install blobs':     get_option('install_blobs')}
3693 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
3694 if config_host.has_key('CONFIG_MODULES')
3695   summary_info += {'alternative module path': get_option('module_upgrades')}
3696 endif
3697 summary_info += {'fuzzing support':   get_option('fuzzing')}
3698 if have_system
3699   summary_info += {'Audio drivers':     ' '.join(audio_drivers_selected)}
3700 endif
3701 summary_info += {'Trace backends':    ','.join(get_option('trace_backends'))}
3702 if 'simple' in get_option('trace_backends')
3703   summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3704 endif
3705 summary_info += {'D-Bus display':     dbus_display}
3706 summary_info += {'QOM debugging':     get_option('qom_cast_debug')}
3707 summary_info += {'vhost-kernel support': have_vhost_kernel}
3708 summary_info += {'vhost-net support': have_vhost_net}
3709 summary_info += {'vhost-user support': have_vhost_user}
3710 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3711 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3712 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3713 summary_info += {'build guest agent': have_ga}
3714 summary(summary_info, bool_yn: true, section: 'Configurable features')
3716 # Compilation information
3717 summary_info = {}
3718 summary_info += {'host CPU':          cpu}
3719 summary_info += {'host endianness':   build_machine.endian()}
3720 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
3721 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3722 if link_language == 'cpp'
3723   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
3724 else
3725   summary_info += {'C++ compiler':      false}
3726 endif
3727 if targetos == 'darwin'
3728   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3729 endif
3730 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
3731                                                + ['-O' + get_option('optimization')]
3732                                                + (get_option('debug') ? ['-g'] : []))}
3733 if link_language == 'cpp'
3734   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
3735                                                + ['-O' + get_option('optimization')]
3736                                                + (get_option('debug') ? ['-g'] : []))}
3737 endif
3738 if targetos == 'darwin'
3739   summary_info += {'OBJCFLAGS':       ' '.join(get_option('objc_args')
3740                                                + ['-O' + get_option('optimization')]
3741                                                + (get_option('debug') ? ['-g'] : []))}
3742 endif
3743 link_args = get_option(link_language + '_link_args')
3744 if link_args.length() > 0
3745   summary_info += {'LDFLAGS':         ' '.join(link_args)}
3746 endif
3747 summary_info += {'QEMU_CFLAGS':       ' '.join(qemu_cflags)}
3748 summary_info += {'QEMU_CXXFLAGS':     ' '.join(qemu_cxxflags)}
3749 summary_info += {'QEMU_OBJCFLAGS':    ' '.join(qemu_objcflags)}
3750 summary_info += {'QEMU_LDFLAGS':      ' '.join(qemu_ldflags)}
3751 summary_info += {'profiler':          get_option('profiler')}
3752 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3753 summary_info += {'PIE':               get_option('b_pie')}
3754 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
3755 summary_info += {'malloc trim support': has_malloc_trim}
3756 summary_info += {'membarrier':        have_membarrier}
3757 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3758 summary_info += {'mutex debugging':   get_option('debug_mutex')}
3759 summary_info += {'memory allocator':  get_option('malloc')}
3760 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3761 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3762 summary_info += {'gprof enabled':     get_option('gprof')}
3763 summary_info += {'gcov':              get_option('b_coverage')}
3764 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
3765 summary_info += {'CFI support':       get_option('cfi')}
3766 if get_option('cfi')
3767   summary_info += {'CFI debug support': get_option('cfi_debug')}
3768 endif
3769 summary_info += {'strip binaries':    get_option('strip')}
3770 summary_info += {'sparse':            sparse}
3771 summary_info += {'mingw32 support':   targetos == 'windows'}
3772 summary(summary_info, bool_yn: true, section: 'Compilation')
3774 # snarf the cross-compilation information for tests
3775 summary_info = {}
3776 have_cross = false
3777 foreach target: target_dirs
3778   tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
3779   if fs.exists(tcg_mak)
3780     config_cross_tcg = keyval.load(tcg_mak)
3781     if 'CC' in config_cross_tcg
3782       summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
3783       have_cross = true
3784     endif
3785   endif
3786 endforeach
3787 if have_cross
3788   summary(summary_info, bool_yn: true, section: 'Cross compilers')
3789 endif
3791 # Targets and accelerators
3792 summary_info = {}
3793 if have_system
3794   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
3795   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
3796   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
3797   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
3798   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
3799   summary_info += {'Xen support':       xen.found()}
3800   if xen.found()
3801     summary_info += {'xen ctrl version':  xen.version()}
3802   endif
3803 endif
3804 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
3805 if config_all.has_key('CONFIG_TCG')
3806   if get_option('tcg_interpreter')
3807     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, slow)'}
3808   else
3809     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
3810   endif
3811   summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3812   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3813 endif
3814 summary_info += {'target list':       ' '.join(target_dirs)}
3815 if have_system
3816   summary_info += {'default devices':   get_option('default_devices')}
3817   summary_info += {'out of process emulation': multiprocess_allowed}
3818   summary_info += {'vfio-user server': vfio_user_server_allowed}
3819 endif
3820 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3822 # Block layer
3823 summary_info = {}
3824 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3825 summary_info += {'coroutine pool':    have_coroutine_pool}
3826 if have_block
3827   summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3828   summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3829   summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3830   summary_info += {'VirtFS support':    have_virtfs}
3831   summary_info += {'build virtiofs daemon': have_virtiofsd}
3832   summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3833   summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3834   summary_info += {'bochs support':     get_option('bochs').allowed()}
3835   summary_info += {'cloop support':     get_option('cloop').allowed()}
3836   summary_info += {'dmg support':       get_option('dmg').allowed()}
3837   summary_info += {'qcow v1 support':   get_option('qcow1').allowed()}
3838   summary_info += {'vdi support':       get_option('vdi').allowed()}
3839   summary_info += {'vvfat support':     get_option('vvfat').allowed()}
3840   summary_info += {'qed support':       get_option('qed').allowed()}
3841   summary_info += {'parallels support': get_option('parallels').allowed()}
3842   summary_info += {'FUSE exports':      fuse}
3843   summary_info += {'VDUSE block exports': have_vduse_blk_export}
3844 endif
3845 summary(summary_info, bool_yn: true, section: 'Block layer support')
3847 # Crypto
3848 summary_info = {}
3849 summary_info += {'TLS priority':      get_option('tls_priority')}
3850 summary_info += {'GNUTLS support':    gnutls}
3851 if gnutls.found()
3852   summary_info += {'  GNUTLS crypto':   gnutls_crypto.found()}
3853 endif
3854 summary_info += {'libgcrypt':         gcrypt}
3855 summary_info += {'nettle':            nettle}
3856 if nettle.found()
3857    summary_info += {'  XTS':             xts != 'private'}
3858 endif
3859 summary_info += {'AF_ALG support':    have_afalg}
3860 summary_info += {'rng-none':          get_option('rng_none')}
3861 summary_info += {'Linux keyring':     have_keyring}
3862 summary(summary_info, bool_yn: true, section: 'Crypto')
3864 # Libraries
3865 summary_info = {}
3866 if targetos == 'darwin'
3867   summary_info += {'Cocoa support':           cocoa}
3868   summary_info += {'vmnet.framework support': vmnet}
3869 endif
3870 summary_info += {'SDL support':       sdl}
3871 summary_info += {'SDL image support': sdl_image}
3872 summary_info += {'GTK support':       gtk}
3873 summary_info += {'pixman':            pixman}
3874 summary_info += {'VTE support':       vte}
3875 summary_info += {'slirp support':     slirp}
3876 summary_info += {'libtasn1':          tasn1}
3877 summary_info += {'PAM':               pam}
3878 summary_info += {'iconv support':     iconv}
3879 summary_info += {'curses support':    curses}
3880 summary_info += {'virgl support':     virgl}
3881 summary_info += {'blkio support':     blkio}
3882 summary_info += {'curl support':      curl}
3883 summary_info += {'Multipath support': mpathpersist}
3884 summary_info += {'PNG support':       png}
3885 summary_info += {'VNC support':       vnc}
3886 if vnc.found()
3887   summary_info += {'VNC SASL support':  sasl}
3888   summary_info += {'VNC JPEG support':  jpeg}
3889 endif
3890 if targetos not in ['darwin', 'haiku', 'windows']
3891   summary_info += {'OSS support':     oss}
3892   summary_info += {'sndio support':   sndio}
3893 elif targetos == 'darwin'
3894   summary_info += {'CoreAudio support': coreaudio}
3895 elif targetos == 'windows'
3896   summary_info += {'DirectSound support': dsound}
3897 endif
3898 if targetos == 'linux'
3899   summary_info += {'ALSA support':    alsa}
3900   summary_info += {'PulseAudio support': pulse}
3901 endif
3902 summary_info += {'JACK support':      jack}
3903 summary_info += {'brlapi support':    brlapi}
3904 summary_info += {'vde support':       vde}
3905 summary_info += {'netmap support':    have_netmap}
3906 summary_info += {'l2tpv3 support':    have_l2tpv3}
3907 summary_info += {'Linux AIO support': libaio}
3908 summary_info += {'Linux io_uring support': linux_io_uring}
3909 summary_info += {'ATTR/XATTR support': libattr}
3910 summary_info += {'RDMA support':      rdma}
3911 summary_info += {'PVRDMA support':    have_pvrdma}
3912 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
3913 summary_info += {'libcap-ng support': libcap_ng}
3914 summary_info += {'bpf support':       libbpf}
3915 summary_info += {'spice protocol support': spice_protocol}
3916 if spice_protocol.found()
3917   summary_info += {'  spice server support': spice}
3918 endif
3919 summary_info += {'rbd support':       rbd}
3920 summary_info += {'smartcard support': cacard}
3921 summary_info += {'U2F support':       u2f}
3922 summary_info += {'libusb':            libusb}
3923 summary_info += {'usb net redir':     usbredir}
3924 summary_info += {'OpenGL support (epoxy)': opengl}
3925 summary_info += {'GBM':               gbm}
3926 summary_info += {'libiscsi support':  libiscsi}
3927 summary_info += {'libnfs support':    libnfs}
3928 if targetos == 'windows'
3929   if have_ga
3930     summary_info += {'QGA VSS support':   have_qga_vss}
3931   endif
3932 endif
3933 summary_info += {'seccomp support':   seccomp}
3934 summary_info += {'GlusterFS support': glusterfs}
3935 summary_info += {'TPM support':       have_tpm}
3936 summary_info += {'libssh support':    libssh}
3937 summary_info += {'lzo support':       lzo}
3938 summary_info += {'snappy support':    snappy}
3939 summary_info += {'bzip2 support':     libbzip2}
3940 summary_info += {'lzfse support':     liblzfse}
3941 summary_info += {'zstd support':      zstd}
3942 summary_info += {'NUMA host support': numa}
3943 summary_info += {'capstone':          capstone}
3944 summary_info += {'libpmem support':   libpmem}
3945 summary_info += {'libdaxctl support': libdaxctl}
3946 summary_info += {'libudev':           libudev}
3947 # Dummy dependency, keep .found()
3948 summary_info += {'FUSE lseek':        fuse_lseek.found()}
3949 summary_info += {'selinux':           selinux}
3950 summary(summary_info, bool_yn: true, section: 'Dependencies')
3952 if not supported_cpus.contains(cpu)
3953   message()
3954   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3955   message()
3956   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3957   message('The QEMU project intends to remove support for this host CPU in')
3958   message('a future release if nobody volunteers to maintain it and to')
3959   message('provide a build host for our continuous integration setup.')
3960   message('configure has succeeded and you can continue to build, but')
3961   message('if you care about QEMU on this platform you should contact')
3962   message('us upstream at qemu-devel@nongnu.org.')
3963 endif
3965 if not supported_oses.contains(targetos)
3966   message()
3967   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3968   message()
3969   message('Host OS ' + targetos + 'support is not currently maintained.')
3970   message('The QEMU project intends to remove support for this host OS in')
3971   message('a future release if nobody volunteers to maintain it and to')
3972   message('provide a build host for our continuous integration setup.')
3973   message('configure has succeeded and you can continue to build, but')
3974   message('if you care about QEMU on this platform you should contact')
3975   message('us upstream at qemu-devel@nongnu.org.')
3976 endif