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