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