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