]> git.proxmox.com Git - mirror_qemu.git/blob - meson.build
4b36637958e8f07003da2e3e2b4f0b5b48cba72c
[mirror_qemu.git] / meson.build
1 project('qemu', ['c'], meson_version: '>=0.55.0',
2 default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_colorout=auto'] +
3 (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
4 version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
5
6 not_found = dependency('', required: false)
7 if meson.version().version_compare('>=0.56.0')
8 keyval = import('keyval')
9 else
10 keyval = import('unstable-keyval')
11 endif
12 ss = import('sourceset')
13 fs = import('fs')
14
15 sh = find_program('sh')
16 cc = meson.get_compiler('c')
17 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18 enable_modules = 'CONFIG_MODULES' in config_host
19 enable_static = 'CONFIG_STATIC' in config_host
20
21 # Temporary directory used for files created while
22 # configure runs. Since it is in the build directory
23 # we can safely blow away any previous version of it
24 # (and we need not jump through hoops to try to delete
25 # it when configure exits.)
26 tmpdir = meson.current_build_dir() / 'meson-private/temp'
27
28 if get_option('qemu_suffix').startswith('/')
29 error('qemu_suffix cannot start with a /')
30 endif
31
32 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
33 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
34 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
35 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
36
37 qemu_desktopdir = get_option('datadir') / 'applications'
38 qemu_icondir = get_option('datadir') / 'icons'
39
40 config_host_data = configuration_data()
41 genh = []
42
43 target_dirs = config_host['TARGET_DIRS'].split()
44 have_user = false
45 have_system = false
46 foreach target : target_dirs
47 have_user = have_user or target.endswith('-user')
48 have_system = have_system or target.endswith('-softmmu')
49 endforeach
50 have_tools = 'CONFIG_TOOLS' in config_host
51 have_block = have_system or have_tools
52
53 python = import('python').find_installation()
54
55 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
56 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
57 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
58
59 cpu = host_machine.cpu_family()
60 targetos = host_machine.system()
61
62 if cpu in ['x86', 'x86_64']
63 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
64 elif cpu == 'aarch64'
65 kvm_targets = ['aarch64-softmmu']
66 elif cpu == 's390x'
67 kvm_targets = ['s390x-softmmu']
68 elif cpu in ['ppc', 'ppc64']
69 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
70 elif cpu in ['mips', 'mips64']
71 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
72 else
73 kvm_targets = []
74 endif
75
76 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
77 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
78 # i368 emulator provides xenpv machine type for multiple architectures
79 accelerator_targets += {
80 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
81 }
82 endif
83 if cpu in ['x86', 'x86_64']
84 accelerator_targets += {
85 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
86 'CONFIG_HVF': ['x86_64-softmmu'],
87 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
88 }
89 endif
90
91 ##################
92 # Compiler flags #
93 ##################
94
95 # Specify linker-script with add_project_link_arguments so that it is not placed
96 # within a linker --start-group/--end-group pair
97 if 'CONFIG_FUZZ' in config_host
98 add_project_link_arguments(['-Wl,-T,',
99 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
100 native: false, language: ['c', 'cpp', 'objc'])
101 endif
102
103 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
104 native: false, language: ['c', 'objc'])
105 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
106 native: false, language: 'cpp')
107 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
108 native: false, language: ['c', 'cpp', 'objc'])
109
110 if targetos == 'linux'
111 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
112 '-isystem', 'linux-headers',
113 language: ['c', 'cpp'])
114 endif
115
116 add_project_arguments('-iquote', '.',
117 '-iquote', meson.current_source_dir(),
118 '-iquote', meson.current_source_dir() / 'include',
119 '-iquote', meson.current_source_dir() / 'disas/libvixl',
120 language: ['c', 'cpp', 'objc'])
121
122 link_language = meson.get_external_property('link_language', 'cpp')
123 if link_language == 'cpp'
124 add_languages('cpp', required: true, native: false)
125 endif
126 if host_machine.system() == 'darwin'
127 add_languages('objc', required: false, native: false)
128 endif
129
130 sparse = find_program('cgcc', required: get_option('sparse'))
131 if sparse.found()
132 run_target('sparse',
133 command: [find_program('scripts/check_sparse.py'),
134 'compile_commands.json', sparse.full_path(), '-Wbitwise',
135 '-Wno-transparent-union', '-Wno-old-initializer',
136 '-Wno-non-pointer-null'])
137 endif
138
139 ###########################################
140 # Target-specific checks and dependencies #
141 ###########################################
142
143 if targetos != 'linux' and get_option('mpath').enabled()
144 error('Multipath is supported only on Linux')
145 endif
146
147 m = cc.find_library('m', required: false)
148 util = cc.find_library('util', required: false)
149 winmm = []
150 socket = []
151 version_res = []
152 coref = []
153 iokit = []
154 emulator_link_args = []
155 hvf = not_found
156 if targetos == 'windows'
157 socket = cc.find_library('ws2_32')
158 winmm = cc.find_library('winmm')
159
160 win = import('windows')
161 version_res = win.compile_resources('version.rc',
162 depend_files: files('pc-bios/qemu-nsis.ico'),
163 include_directories: include_directories('.'))
164 elif targetos == 'darwin'
165 coref = dependency('appleframeworks', modules: 'CoreFoundation')
166 iokit = dependency('appleframeworks', modules: 'IOKit')
167 elif targetos == 'sunos'
168 socket = [cc.find_library('socket'),
169 cc.find_library('nsl'),
170 cc.find_library('resolv')]
171 elif targetos == 'haiku'
172 socket = [cc.find_library('posix_error_mapper'),
173 cc.find_library('network'),
174 cc.find_library('bsd')]
175 elif targetos == 'openbsd'
176 if not get_option('tcg').disabled() and target_dirs.length() > 0
177 # Disable OpenBSD W^X if available
178 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
179 endif
180 endif
181
182 accelerators = []
183 if not get_option('kvm').disabled() and targetos == 'linux'
184 accelerators += 'CONFIG_KVM'
185 endif
186 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
187 accelerators += 'CONFIG_XEN'
188 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
189 else
190 have_xen_pci_passthrough = false
191 endif
192 if not get_option('whpx').disabled() and targetos == 'windows'
193 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
194 error('WHPX requires 64-bit host')
195 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
196 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
197 accelerators += 'CONFIG_WHPX'
198 endif
199 endif
200 if not get_option('hvf').disabled()
201 hvf = dependency('appleframeworks', modules: 'Hypervisor',
202 required: get_option('hvf'))
203 if hvf.found()
204 accelerators += 'CONFIG_HVF'
205 endif
206 endif
207 if not get_option('hax').disabled()
208 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
209 accelerators += 'CONFIG_HAX'
210 endif
211 endif
212
213 tcg_arch = config_host['ARCH']
214 if not get_option('tcg').disabled()
215 if cpu not in supported_cpus
216 if get_option('tcg_interpreter')
217 warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
218 else
219 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
220 endif
221 endif
222 if get_option('tcg_interpreter')
223 tcg_arch = 'tci'
224 elif config_host['ARCH'] == 'sparc64'
225 tcg_arch = 'sparc'
226 elif config_host['ARCH'] == 's390x'
227 tcg_arch = 's390'
228 elif config_host['ARCH'] in ['x86_64', 'x32']
229 tcg_arch = 'i386'
230 elif config_host['ARCH'] == 'ppc64'
231 tcg_arch = 'ppc'
232 elif config_host['ARCH'] in ['riscv32', 'riscv64']
233 tcg_arch = 'riscv'
234 endif
235 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
236 '-iquote', meson.current_source_dir() / 'accel/tcg',
237 language: ['c', 'cpp', 'objc'])
238
239 accelerators += 'CONFIG_TCG'
240 config_host += { 'CONFIG_TCG': 'y' }
241 endif
242
243 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
244 error('KVM not available on this platform')
245 endif
246 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
247 error('HVF not available on this platform')
248 endif
249 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
250 error('WHPX not available on this platform')
251 endif
252 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
253 if 'CONFIG_XEN' in accelerators
254 error('Xen PCI passthrough not available on this platform')
255 else
256 error('Xen PCI passthrough requested but Xen not enabled')
257 endif
258 endif
259
260 ################
261 # Dependencies #
262 ################
263
264 # The path to glib.h is added to all compilation commands. This was
265 # grandfathered in from the QEMU Makefiles.
266 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
267 native: false, language: ['c', 'cpp', 'objc'])
268 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
269 link_args: config_host['GLIB_LIBS'].split())
270 # override glib dep with the configure results (for subprojects)
271 meson.override_dependency('glib-2.0', glib)
272
273 gio = not_found
274 if 'CONFIG_GIO' in config_host
275 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
276 link_args: config_host['GIO_LIBS'].split())
277 endif
278 lttng = not_found
279 if 'CONFIG_TRACE_UST' in config_host
280 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
281 endif
282 urcubp = not_found
283 if 'CONFIG_TRACE_UST' in config_host
284 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
285 endif
286 gcrypt = not_found
287 if 'CONFIG_GCRYPT' in config_host
288 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
289 link_args: config_host['GCRYPT_LIBS'].split())
290 endif
291 nettle = not_found
292 if 'CONFIG_NETTLE' in config_host
293 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
294 link_args: config_host['NETTLE_LIBS'].split())
295 endif
296 gnutls = not_found
297 if 'CONFIG_GNUTLS' in config_host
298 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
299 link_args: config_host['GNUTLS_LIBS'].split())
300 endif
301 pixman = not_found
302 if have_system or have_tools
303 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
304 method: 'pkg-config', static: enable_static)
305 endif
306 pam = not_found
307 if 'CONFIG_AUTH_PAM' in config_host
308 pam = cc.find_library('pam')
309 endif
310 libaio = cc.find_library('aio', required: false)
311 zlib = dependency('zlib', required: true, static: enable_static)
312 linux_io_uring = not_found
313 if 'CONFIG_LINUX_IO_URING' in config_host
314 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
315 link_args: config_host['LINUX_IO_URING_LIBS'].split())
316 endif
317 libxml2 = not_found
318 if 'CONFIG_LIBXML2' in config_host
319 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
320 link_args: config_host['LIBXML2_LIBS'].split())
321 endif
322 libnfs = not_found
323 if not get_option('libnfs').auto() or have_block
324 libnfs = dependency('libnfs', version: '>=1.9.3',
325 required: get_option('libnfs'),
326 method: 'pkg-config', static: enable_static)
327 endif
328
329 libattr_test = '''
330 #include <stddef.h>
331 #include <sys/types.h>
332 #ifdef CONFIG_LIBATTR
333 #include <attr/xattr.h>
334 #else
335 #include <sys/xattr.h>
336 #endif
337 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
338
339 libattr = not_found
340 have_old_libattr = false
341 if not get_option('attr').disabled()
342 if cc.links(libattr_test)
343 libattr = declare_dependency()
344 else
345 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
346 required: get_option('attr'),
347 static: enable_static)
348 if libattr.found() and not \
349 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
350 libattr = not_found
351 if get_option('attr').enabled()
352 error('could not link libattr')
353 else
354 warning('could not link libattr, disabling')
355 endif
356 else
357 have_old_libattr = libattr.found()
358 endif
359 endif
360 endif
361
362 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
363 if cocoa.found() and get_option('sdl').enabled()
364 error('Cocoa and SDL cannot be enabled at the same time')
365 endif
366 if cocoa.found() and get_option('gtk').enabled()
367 error('Cocoa and GTK+ cannot be enabled at the same time')
368 endif
369
370 seccomp = not_found
371 if not get_option('seccomp').auto() or have_system or have_tools
372 seccomp = dependency('libseccomp', version: '>=2.3.0',
373 required: get_option('seccomp'),
374 method: 'pkg-config', static: enable_static)
375 endif
376
377 libcap_ng = not_found
378 if not get_option('cap_ng').auto() or have_system or have_tools
379 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
380 required: get_option('cap_ng'),
381 static: enable_static)
382 endif
383 if libcap_ng.found() and not cc.links('''
384 #include <cap-ng.h>
385 int main(void)
386 {
387 capng_capability_to_name(CAPNG_EFFECTIVE);
388 return 0;
389 }''', dependencies: libcap_ng)
390 libcap_ng = not_found
391 if get_option('cap_ng').enabled()
392 error('could not link libcap-ng')
393 else
394 warning('could not link libcap-ng, disabling')
395 endif
396 endif
397
398 if get_option('xkbcommon').auto() and not have_system and not have_tools
399 xkbcommon = not_found
400 else
401 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
402 method: 'pkg-config', static: enable_static)
403 endif
404 vde = not_found
405 if config_host.has_key('CONFIG_VDE')
406 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
407 endif
408 pulse = not_found
409 if 'CONFIG_LIBPULSE' in config_host
410 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
411 link_args: config_host['PULSE_LIBS'].split())
412 endif
413 alsa = not_found
414 if 'CONFIG_ALSA' in config_host
415 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
416 link_args: config_host['ALSA_LIBS'].split())
417 endif
418 jack = not_found
419 if 'CONFIG_LIBJACK' in config_host
420 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
421 endif
422 spice = not_found
423 spice_headers = not_found
424 if 'CONFIG_SPICE' in config_host
425 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
426 link_args: config_host['SPICE_LIBS'].split())
427 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
428 endif
429 rt = cc.find_library('rt', required: false)
430 libdl = not_found
431 if 'CONFIG_PLUGIN' in config_host
432 libdl = cc.find_library('dl', required: true)
433 endif
434 libiscsi = not_found
435 if not get_option('libiscsi').auto() or have_block
436 libiscsi = dependency('libiscsi', version: '>=1.9.0',
437 required: get_option('libiscsi'),
438 method: 'pkg-config', static: enable_static)
439 endif
440 zstd = not_found
441 if not get_option('zstd').auto() or have_block
442 zstd = dependency('libzstd', version: '>=1.4.0',
443 required: get_option('zstd'),
444 method: 'pkg-config', static: enable_static)
445 endif
446 gbm = not_found
447 if 'CONFIG_GBM' in config_host
448 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
449 link_args: config_host['GBM_LIBS'].split())
450 endif
451 virgl = not_found
452 if 'CONFIG_VIRGL' in config_host
453 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
454 link_args: config_host['VIRGL_LIBS'].split())
455 endif
456 curl = not_found
457 if not get_option('curl').auto() or have_block
458 curl = dependency('libcurl', version: '>=7.29.0',
459 method: 'pkg-config',
460 required: get_option('curl'),
461 static: enable_static)
462 endif
463 libudev = not_found
464 if targetos == 'linux' and (have_system or have_tools)
465 libudev = dependency('libudev',
466 method: 'pkg-config',
467 required: get_option('libudev'),
468 static: enable_static)
469 endif
470
471 mpathlibs = [libudev]
472 mpathpersist = not_found
473 mpathpersist_new_api = false
474 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
475 mpath_test_source_new = '''
476 #include <libudev.h>
477 #include <mpath_persist.h>
478 unsigned mpath_mx_alloc_len = 1024;
479 int logsink;
480 static struct config *multipath_conf;
481 extern struct udev *udev;
482 extern struct config *get_multipath_config(void);
483 extern void put_multipath_config(struct config *conf);
484 struct udev *udev;
485 struct config *get_multipath_config(void) { return multipath_conf; }
486 void put_multipath_config(struct config *conf) { }
487 int main(void) {
488 udev = udev_new();
489 multipath_conf = mpath_lib_init();
490 return 0;
491 }'''
492 mpath_test_source_old = '''
493 #include <libudev.h>
494 #include <mpath_persist.h>
495 unsigned mpath_mx_alloc_len = 1024;
496 int logsink;
497 int main(void) {
498 struct udev *udev = udev_new();
499 mpath_lib_init(udev);
500 return 0;
501 }'''
502 libmpathpersist = cc.find_library('mpathpersist',
503 required: get_option('mpath'),
504 static: enable_static)
505 if libmpathpersist.found()
506 mpathlibs += libmpathpersist
507 if enable_static
508 mpathlibs += cc.find_library('devmapper',
509 required: get_option('mpath'),
510 static: enable_static)
511 endif
512 mpathlibs += cc.find_library('multipath',
513 required: get_option('mpath'),
514 static: enable_static)
515 foreach lib: mpathlibs
516 if not lib.found()
517 mpathlibs = []
518 break
519 endif
520 endforeach
521 if mpathlibs.length() == 0
522 msg = 'Dependencies missing for libmpathpersist'
523 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
524 mpathpersist = declare_dependency(dependencies: mpathlibs)
525 mpathpersist_new_api = true
526 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
527 mpathpersist = declare_dependency(dependencies: mpathlibs)
528 else
529 msg = 'Cannot detect libmpathpersist API'
530 endif
531 if not mpathpersist.found()
532 if get_option('mpath').enabled()
533 error(msg)
534 else
535 warning(msg + ', disabling')
536 endif
537 endif
538 endif
539 endif
540
541 iconv = not_found
542 curses = not_found
543 if have_system and not get_option('curses').disabled()
544 curses_test = '''
545 #include <locale.h>
546 #include <curses.h>
547 #include <wchar.h>
548 int main(void) {
549 wchar_t wch = L'w';
550 setlocale(LC_ALL, "");
551 resize_term(0, 0);
552 addwstr(L"wide chars\n");
553 addnwstr(&wch, 1);
554 add_wch(WACS_DEGREE);
555 return 0;
556 }'''
557
558 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
559 foreach curses_dep : curses_dep_list
560 if not curses.found()
561 curses = dependency(curses_dep,
562 required: false,
563 method: 'pkg-config',
564 static: enable_static)
565 endif
566 endforeach
567 msg = get_option('curses').enabled() ? 'curses library not found' : ''
568 curses_compile_args = ['-DNCURSES_WIDECHAR']
569 if curses.found()
570 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
571 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
572 else
573 msg = 'curses package not usable'
574 curses = not_found
575 endif
576 endif
577 if not curses.found()
578 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
579 if targetos != 'windows' and not has_curses_h
580 message('Trying with /usr/include/ncursesw')
581 curses_compile_args += ['-I/usr/include/ncursesw']
582 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
583 endif
584 if has_curses_h
585 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
586 foreach curses_libname : curses_libname_list
587 libcurses = cc.find_library(curses_libname,
588 required: false,
589 static: enable_static)
590 if libcurses.found()
591 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
592 curses = declare_dependency(compile_args: curses_compile_args,
593 dependencies: [libcurses])
594 break
595 else
596 msg = 'curses library not usable'
597 endif
598 endif
599 endforeach
600 endif
601 endif
602 if not get_option('iconv').disabled()
603 foreach link_args : [ ['-liconv'], [] ]
604 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
605 # We need to use libiconv if available because mixing libiconv's headers with
606 # the system libc does not work.
607 # However, without adding glib to the dependencies -L/usr/local/lib will not be
608 # included in the command line and libiconv will not be found.
609 if cc.links('''
610 #include <iconv.h>
611 int main(void) {
612 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
613 return conv != (iconv_t) -1;
614 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
615 iconv = declare_dependency(link_args: link_args, dependencies: glib)
616 break
617 endif
618 endforeach
619 endif
620 if curses.found() and not iconv.found()
621 if get_option('iconv').enabled()
622 error('iconv not available')
623 endif
624 msg = 'iconv required for curses UI but not available'
625 curses = not_found
626 endif
627 if not curses.found() and msg != ''
628 if get_option('curses').enabled()
629 error(msg)
630 else
631 warning(msg + ', disabling')
632 endif
633 endif
634 endif
635
636 brlapi = not_found
637 if not get_option('brlapi').auto() or have_system
638 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
639 required: get_option('brlapi'),
640 static: enable_static)
641 if brlapi.found() and not cc.links('''
642 #include <brlapi.h>
643 #include <stddef.h>
644 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
645 brlapi = not_found
646 if get_option('brlapi').enabled()
647 error('could not link brlapi')
648 else
649 warning('could not link brlapi, disabling')
650 endif
651 endif
652 endif
653
654 sdl = not_found
655 if not get_option('sdl').auto() or (have_system and not cocoa.found())
656 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
657 sdl_image = not_found
658 endif
659 if sdl.found()
660 # work around 2.0.8 bug
661 sdl = declare_dependency(compile_args: '-Wno-undef',
662 dependencies: sdl)
663 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
664 method: 'pkg-config', static: enable_static)
665 else
666 if get_option('sdl_image').enabled()
667 error('sdl-image required, but SDL was @0@'.format(
668 get_option('sdl').disabled() ? 'disabled' : 'not found'))
669 endif
670 sdl_image = not_found
671 endif
672
673 rbd = not_found
674 if not get_option('rbd').auto() or have_block
675 librados = cc.find_library('rados', required: get_option('rbd'),
676 static: enable_static)
677 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
678 required: get_option('rbd'),
679 static: enable_static)
680 if librados.found() and librbd.found() and cc.links('''
681 #include <stdio.h>
682 #include <rbd/librbd.h>
683 int main(void) {
684 rados_t cluster;
685 rados_create(&cluster, NULL);
686 return 0;
687 }''', dependencies: [librbd, librados])
688 rbd = declare_dependency(dependencies: [librbd, librados])
689 endif
690 endif
691
692 glusterfs = not_found
693 glusterfs_ftruncate_has_stat = false
694 glusterfs_iocb_has_stat = false
695 if not get_option('glusterfs').auto() or have_block
696 glusterfs = dependency('glusterfs-api', version: '>=3',
697 required: get_option('glusterfs'),
698 method: 'pkg-config', static: enable_static)
699 if glusterfs.found()
700 glusterfs_ftruncate_has_stat = cc.links('''
701 #include <glusterfs/api/glfs.h>
702
703 int
704 main(void)
705 {
706 /* new glfs_ftruncate() passes two additional args */
707 return glfs_ftruncate(NULL, 0, NULL, NULL);
708 }
709 ''', dependencies: glusterfs)
710 glusterfs_iocb_has_stat = cc.links('''
711 #include <glusterfs/api/glfs.h>
712
713 /* new glfs_io_cbk() passes two additional glfs_stat structs */
714 static void
715 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
716 {}
717
718 int
719 main(void)
720 {
721 glfs_io_cbk iocb = &glusterfs_iocb;
722 iocb(NULL, 0 , NULL, NULL, NULL);
723 return 0;
724 }
725 ''', dependencies: glusterfs)
726 endif
727 endif
728 libssh = not_found
729 if 'CONFIG_LIBSSH' in config_host
730 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
731 link_args: config_host['LIBSSH_LIBS'].split())
732 endif
733 libbzip2 = not_found
734 if not get_option('bzip2').auto() or have_block
735 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
736 required: get_option('bzip2'),
737 static: enable_static)
738 if libbzip2.found() and not cc.links('''
739 #include <bzlib.h>
740 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
741 libbzip2 = not_found
742 if get_option('bzip2').enabled()
743 error('could not link libbzip2')
744 else
745 warning('could not link libbzip2, disabling')
746 endif
747 endif
748 endif
749
750 liblzfse = not_found
751 if not get_option('lzfse').auto() or have_block
752 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
753 required: get_option('lzfse'),
754 static: enable_static)
755 endif
756 if liblzfse.found() and not cc.links('''
757 #include <lzfse.h>
758 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
759 liblzfse = not_found
760 if get_option('lzfse').enabled()
761 error('could not link liblzfse')
762 else
763 warning('could not link liblzfse, disabling')
764 endif
765 endif
766
767 oss = not_found
768 if 'CONFIG_AUDIO_OSS' in config_host
769 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
770 endif
771 dsound = not_found
772 if 'CONFIG_AUDIO_DSOUND' in config_host
773 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
774 endif
775 coreaudio = not_found
776 if 'CONFIG_AUDIO_COREAUDIO' in config_host
777 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
778 endif
779 opengl = not_found
780 if 'CONFIG_OPENGL' in config_host
781 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
782 link_args: config_host['OPENGL_LIBS'].split())
783 endif
784
785 gtk = not_found
786 gtkx11 = not_found
787 if not get_option('gtk').auto() or (have_system and not cocoa.found())
788 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
789 method: 'pkg-config',
790 required: get_option('gtk'),
791 static: enable_static)
792 if gtk.found()
793 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
794 method: 'pkg-config',
795 required: false,
796 static: enable_static)
797 gtk = declare_dependency(dependencies: [gtk, gtkx11])
798 endif
799 endif
800
801 vte = not_found
802 if 'CONFIG_VTE' in config_host
803 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
804 link_args: config_host['VTE_LIBS'].split())
805 endif
806 x11 = not_found
807 if gtkx11.found() or 'lm32-softmmu' in target_dirs
808 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
809 static: enable_static)
810 endif
811 vnc = not_found
812 png = not_found
813 jpeg = not_found
814 sasl = not_found
815 if get_option('vnc').enabled()
816 vnc = declare_dependency() # dummy dependency
817 png = dependency('libpng', required: get_option('vnc_png'),
818 method: 'pkg-config', static: enable_static)
819 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
820 method: 'pkg-config', static: enable_static)
821 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
822 required: get_option('vnc_sasl'),
823 static: enable_static)
824 if sasl.found()
825 sasl = declare_dependency(dependencies: sasl,
826 compile_args: '-DSTRUCT_IOVEC_DEFINED')
827 endif
828 endif
829
830 snappy = not_found
831 if not get_option('snappy').auto() or have_system
832 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
833 required: get_option('snappy'),
834 static: enable_static)
835 endif
836 if snappy.found() and not cc.links('''
837 #include <snappy-c.h>
838 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
839 snappy = not_found
840 if get_option('snappy').enabled()
841 error('could not link libsnappy')
842 else
843 warning('could not link libsnappy, disabling')
844 endif
845 endif
846
847 lzo = not_found
848 if not get_option('lzo').auto() or have_system
849 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
850 required: get_option('lzo'),
851 static: enable_static)
852 endif
853 if lzo.found() and not cc.links('''
854 #include <lzo/lzo1x.h>
855 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
856 lzo = not_found
857 if get_option('lzo').enabled()
858 error('could not link liblzo2')
859 else
860 warning('could not link liblzo2, disabling')
861 endif
862 endif
863
864 rdma = not_found
865 if 'CONFIG_RDMA' in config_host
866 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
867 endif
868 numa = not_found
869 if 'CONFIG_NUMA' in config_host
870 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
871 endif
872 xen = not_found
873 if 'CONFIG_XEN_BACKEND' in config_host
874 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
875 link_args: config_host['XEN_LIBS'].split())
876 endif
877 cacard = not_found
878 if 'CONFIG_SMARTCARD' in config_host
879 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
880 link_args: config_host['SMARTCARD_LIBS'].split())
881 endif
882 u2f = not_found
883 if have_system
884 u2f = dependency('u2f-emu', required: get_option('u2f'),
885 method: 'pkg-config',
886 static: enable_static)
887 endif
888 usbredir = not_found
889 if 'CONFIG_USB_REDIR' in config_host
890 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
891 link_args: config_host['USB_REDIR_LIBS'].split())
892 endif
893 libusb = not_found
894 if 'CONFIG_USB_LIBUSB' in config_host
895 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
896 link_args: config_host['LIBUSB_LIBS'].split())
897 endif
898 libpmem = not_found
899 if 'CONFIG_LIBPMEM' in config_host
900 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
901 link_args: config_host['LIBPMEM_LIBS'].split())
902 endif
903 libdaxctl = not_found
904 if 'CONFIG_LIBDAXCTL' in config_host
905 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
906 endif
907 tasn1 = not_found
908 if 'CONFIG_TASN1' in config_host
909 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
910 link_args: config_host['TASN1_LIBS'].split())
911 endif
912 keyutils = dependency('libkeyutils', required: false,
913 method: 'pkg-config', static: enable_static)
914
915 has_gettid = cc.has_function('gettid')
916
917 # Malloc tests
918
919 malloc = []
920 if get_option('malloc') == 'system'
921 has_malloc_trim = \
922 not get_option('malloc_trim').disabled() and \
923 cc.links('''#include <malloc.h>
924 int main(void) { malloc_trim(0); return 0; }''')
925 else
926 has_malloc_trim = false
927 malloc = cc.find_library(get_option('malloc'), required: true)
928 endif
929 if not has_malloc_trim and get_option('malloc_trim').enabled()
930 if get_option('malloc') == 'system'
931 error('malloc_trim not available on this platform.')
932 else
933 error('malloc_trim not available with non-libc memory allocator')
934 endif
935 endif
936
937 # Check whether the glibc provides statx()
938
939 statx_test = '''
940 #ifndef _GNU_SOURCE
941 #define _GNU_SOURCE
942 #endif
943 #include <sys/stat.h>
944 int main(void) {
945 struct statx statxbuf;
946 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
947 return 0;
948 }'''
949
950 has_statx = cc.links(statx_test)
951
952 have_vhost_user_blk_server = (targetos == 'linux' and
953 'CONFIG_VHOST_USER' in config_host)
954
955 if get_option('vhost_user_blk_server').enabled()
956 if targetos != 'linux'
957 error('vhost_user_blk_server requires linux')
958 elif 'CONFIG_VHOST_USER' not in config_host
959 error('vhost_user_blk_server requires vhost-user support')
960 endif
961 elif get_option('vhost_user_blk_server').disabled() or not have_system
962 have_vhost_user_blk_server = false
963 endif
964
965
966 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
967 error('Cannot enable fuse-lseek while fuse is disabled')
968 endif
969
970 fuse = dependency('fuse3', required: get_option('fuse'),
971 version: '>=3.1', method: 'pkg-config',
972 static: enable_static)
973
974 fuse_lseek = not_found
975 if not get_option('fuse_lseek').disabled()
976 if fuse.version().version_compare('>=3.8')
977 # Dummy dependency
978 fuse_lseek = declare_dependency()
979 elif get_option('fuse_lseek').enabled()
980 if fuse.found()
981 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
982 else
983 error('fuse-lseek requires libfuse, which was not found')
984 endif
985 endif
986 endif
987
988 if get_option('cfi')
989 cfi_flags=[]
990 # Check for dependency on LTO
991 if not get_option('b_lto')
992 error('Selected Control-Flow Integrity but LTO is disabled')
993 endif
994 if config_host.has_key('CONFIG_MODULES')
995 error('Selected Control-Flow Integrity is not compatible with modules')
996 endif
997 # Check for cfi flags. CFI requires LTO so we can't use
998 # get_supported_arguments, but need a more complex "compiles" which allows
999 # custom arguments
1000 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1001 args: ['-flto', '-fsanitize=cfi-icall'] )
1002 cfi_flags += '-fsanitize=cfi-icall'
1003 else
1004 error('-fsanitize=cfi-icall is not supported by the compiler')
1005 endif
1006 if cc.compiles('int main () { return 0; }',
1007 name: '-fsanitize-cfi-icall-generalize-pointers',
1008 args: ['-flto', '-fsanitize=cfi-icall',
1009 '-fsanitize-cfi-icall-generalize-pointers'] )
1010 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1011 else
1012 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1013 endif
1014 if get_option('cfi_debug')
1015 if cc.compiles('int main () { return 0; }',
1016 name: '-fno-sanitize-trap=cfi-icall',
1017 args: ['-flto', '-fsanitize=cfi-icall',
1018 '-fno-sanitize-trap=cfi-icall'] )
1019 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1020 else
1021 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1022 endif
1023 endif
1024 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1025 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1026 endif
1027
1028 #################
1029 # config-host.h #
1030 #################
1031
1032 have_virtfs = (targetos == 'linux' and
1033 have_system and
1034 libattr.found() and
1035 libcap_ng.found())
1036
1037 have_virtfs_proxy_helper = have_virtfs and have_tools
1038
1039 if get_option('virtfs').enabled()
1040 if not have_virtfs
1041 if targetos != 'linux'
1042 error('virtio-9p (virtfs) requires Linux')
1043 elif not libcap_ng.found() or not libattr.found()
1044 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1045 elif not have_system
1046 error('virtio-9p (virtfs) needs system emulation support')
1047 endif
1048 endif
1049 elif get_option('virtfs').disabled()
1050 have_virtfs = false
1051 endif
1052
1053 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1054 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1055 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1056 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1057 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1058 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1059 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1060 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1061 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1062 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1063 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1064 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1065
1066 config_host_data.set('CONFIG_ATTR', libattr.found())
1067 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1068 config_host_data.set('CONFIG_COCOA', cocoa.found())
1069 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1070 config_host_data.set('CONFIG_LZO', lzo.found())
1071 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1072 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1073 config_host_data.set('CONFIG_CURL', curl.found())
1074 config_host_data.set('CONFIG_CURSES', curses.found())
1075 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1076 if glusterfs.found()
1077 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1078 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1079 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1080 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1081 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1082 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1083 endif
1084 config_host_data.set('CONFIG_GTK', gtk.found())
1085 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1086 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1087 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1088 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1089 config_host_data.set('CONFIG_RBD', rbd.found())
1090 config_host_data.set('CONFIG_SDL', sdl.found())
1091 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1092 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1093 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1094 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1095 config_host_data.set('CONFIG_VNC', vnc.found())
1096 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1097 config_host_data.set('CONFIG_VNC_PNG', png.found())
1098 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1099 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1100 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1101 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1102 config_host_data.set('CONFIG_GETTID', has_gettid)
1103 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1104 config_host_data.set('CONFIG_STATX', has_statx)
1105 config_host_data.set('CONFIG_ZSTD', zstd.found())
1106 config_host_data.set('CONFIG_FUSE', fuse.found())
1107 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1108 config_host_data.set('CONFIG_X11', x11.found())
1109 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1110 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1111 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1112 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1113 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1114
1115 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1116 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1117 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1118 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1119 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1120
1121 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1122 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1123 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1124 foreach k, v: config_host
1125 if ignored.contains(k)
1126 # do nothing
1127 elif arrays.contains(k)
1128 if v != ''
1129 v = '"' + '", "'.join(v.split()) + '", '
1130 endif
1131 config_host_data.set(k, v)
1132 elif k == 'ARCH'
1133 config_host_data.set('HOST_' + v.to_upper(), 1)
1134 elif strings.contains(k)
1135 if not k.startswith('CONFIG_')
1136 k = 'CONFIG_' + k.to_upper()
1137 endif
1138 config_host_data.set_quoted(k, v)
1139 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1140 config_host_data.set(k, v == 'y' ? 1 : v)
1141 endif
1142 endforeach
1143
1144 ########################
1145 # Target configuration #
1146 ########################
1147
1148 minikconf = find_program('scripts/minikconf.py')
1149 config_all = {}
1150 config_all_devices = {}
1151 config_all_disas = {}
1152 config_devices_mak_list = []
1153 config_devices_h = {}
1154 config_target_h = {}
1155 config_target_mak = {}
1156
1157 disassemblers = {
1158 'alpha' : ['CONFIG_ALPHA_DIS'],
1159 'arm' : ['CONFIG_ARM_DIS'],
1160 'avr' : ['CONFIG_AVR_DIS'],
1161 'cris' : ['CONFIG_CRIS_DIS'],
1162 'hppa' : ['CONFIG_HPPA_DIS'],
1163 'i386' : ['CONFIG_I386_DIS'],
1164 'x86_64' : ['CONFIG_I386_DIS'],
1165 'x32' : ['CONFIG_I386_DIS'],
1166 'lm32' : ['CONFIG_LM32_DIS'],
1167 'm68k' : ['CONFIG_M68K_DIS'],
1168 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1169 'mips' : ['CONFIG_MIPS_DIS'],
1170 'moxie' : ['CONFIG_MOXIE_DIS'],
1171 'nios2' : ['CONFIG_NIOS2_DIS'],
1172 'or1k' : ['CONFIG_OPENRISC_DIS'],
1173 'ppc' : ['CONFIG_PPC_DIS'],
1174 'riscv' : ['CONFIG_RISCV_DIS'],
1175 'rx' : ['CONFIG_RX_DIS'],
1176 's390' : ['CONFIG_S390_DIS'],
1177 'sh4' : ['CONFIG_SH4_DIS'],
1178 'sparc' : ['CONFIG_SPARC_DIS'],
1179 'xtensa' : ['CONFIG_XTENSA_DIS'],
1180 }
1181 if link_language == 'cpp'
1182 disassemblers += {
1183 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1184 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1185 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1186 }
1187 endif
1188
1189 host_kconfig = \
1190 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1191 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1192 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1193 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1194 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1195 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1196 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1197 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1198 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1199 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1200 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1201
1202 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1203
1204 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1205 actual_target_dirs = []
1206 fdt_required = []
1207 foreach target : target_dirs
1208 config_target = { 'TARGET_NAME': target.split('-')[0] }
1209 if target.endswith('linux-user')
1210 if targetos != 'linux'
1211 if default_targets
1212 continue
1213 endif
1214 error('Target @0@ is only available on a Linux host'.format(target))
1215 endif
1216 config_target += { 'CONFIG_LINUX_USER': 'y' }
1217 elif target.endswith('bsd-user')
1218 if 'CONFIG_BSD' not in config_host
1219 if default_targets
1220 continue
1221 endif
1222 error('Target @0@ is only available on a BSD host'.format(target))
1223 endif
1224 config_target += { 'CONFIG_BSD_USER': 'y' }
1225 elif target.endswith('softmmu')
1226 config_target += { 'CONFIG_SOFTMMU': 'y' }
1227 endif
1228 if target.endswith('-user')
1229 config_target += {
1230 'CONFIG_USER_ONLY': 'y',
1231 'CONFIG_QEMU_INTERP_PREFIX':
1232 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1233 }
1234 endif
1235
1236 accel_kconfig = []
1237 foreach sym: accelerators
1238 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1239 config_target += { sym: 'y' }
1240 config_all += { sym: 'y' }
1241 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1242 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1243 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1244 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1245 endif
1246 accel_kconfig += [ sym + '=y' ]
1247 endif
1248 endforeach
1249 if accel_kconfig.length() == 0
1250 if default_targets
1251 continue
1252 endif
1253 error('No accelerator available for target @0@'.format(target))
1254 endif
1255
1256 actual_target_dirs += target
1257 config_target += keyval.load('default-configs/targets' / target + '.mak')
1258 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1259
1260 if 'TARGET_NEED_FDT' in config_target
1261 fdt_required += target
1262 endif
1263
1264 # Add default keys
1265 if 'TARGET_BASE_ARCH' not in config_target
1266 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1267 endif
1268 if 'TARGET_ABI_DIR' not in config_target
1269 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1270 endif
1271
1272 foreach k, v: disassemblers
1273 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1274 foreach sym: v
1275 config_target += { sym: 'y' }
1276 config_all_disas += { sym: 'y' }
1277 endforeach
1278 endif
1279 endforeach
1280
1281 config_target_data = configuration_data()
1282 foreach k, v: config_target
1283 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1284 # do nothing
1285 elif ignored.contains(k)
1286 # do nothing
1287 elif k == 'TARGET_BASE_ARCH'
1288 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1289 # not used to select files from sourcesets.
1290 config_target_data.set('TARGET_' + v.to_upper(), 1)
1291 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1292 config_target_data.set_quoted(k, v)
1293 elif v == 'y'
1294 config_target_data.set(k, 1)
1295 else
1296 config_target_data.set(k, v)
1297 endif
1298 endforeach
1299 config_target_h += {target: configure_file(output: target + '-config-target.h',
1300 configuration: config_target_data)}
1301
1302 if target.endswith('-softmmu')
1303 config_devices_mak = target + '-config-devices.mak'
1304 config_devices_mak = configure_file(
1305 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1306 output: config_devices_mak,
1307 depfile: config_devices_mak + '.d',
1308 capture: true,
1309 command: [minikconf,
1310 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1311 config_devices_mak, '@DEPFILE@', '@INPUT@',
1312 host_kconfig, accel_kconfig])
1313
1314 config_devices_data = configuration_data()
1315 config_devices = keyval.load(config_devices_mak)
1316 foreach k, v: config_devices
1317 config_devices_data.set(k, 1)
1318 endforeach
1319 config_devices_mak_list += config_devices_mak
1320 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1321 configuration: config_devices_data)}
1322 config_target += config_devices
1323 config_all_devices += config_devices
1324 endif
1325 config_target_mak += {target: config_target}
1326 endforeach
1327 target_dirs = actual_target_dirs
1328
1329 # This configuration is used to build files that are shared by
1330 # multiple binaries, and then extracted out of the "common"
1331 # static_library target.
1332 #
1333 # We do not use all_sources()/all_dependencies(), because it would
1334 # build literally all source files, including devices only used by
1335 # targets that are not built for this compilation. The CONFIG_ALL
1336 # pseudo symbol replaces it.
1337
1338 config_all += config_all_devices
1339 config_all += config_host
1340 config_all += config_all_disas
1341 config_all += {
1342 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1343 'CONFIG_SOFTMMU': have_system,
1344 'CONFIG_USER_ONLY': have_user,
1345 'CONFIG_ALL': true,
1346 }
1347
1348 ##############
1349 # Submodules #
1350 ##############
1351
1352 capstone = not_found
1353 capstone_opt = get_option('capstone')
1354 if capstone_opt in ['enabled', 'auto', 'system']
1355 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1356 capstone = dependency('capstone', version: '>=4.0',
1357 static: enable_static, method: 'pkg-config',
1358 required: capstone_opt == 'system' or
1359 capstone_opt == 'enabled' and not have_internal)
1360 if capstone.found()
1361 capstone_opt = 'system'
1362 elif have_internal
1363 capstone_opt = 'internal'
1364 else
1365 capstone_opt = 'disabled'
1366 endif
1367 endif
1368 if capstone_opt == 'internal'
1369 capstone_data = configuration_data()
1370 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1371
1372 capstone_files = files(
1373 'capstone/cs.c',
1374 'capstone/MCInst.c',
1375 'capstone/MCInstrDesc.c',
1376 'capstone/MCRegisterInfo.c',
1377 'capstone/SStream.c',
1378 'capstone/utils.c'
1379 )
1380
1381 if 'CONFIG_ARM_DIS' in config_all_disas
1382 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1383 capstone_files += files(
1384 'capstone/arch/ARM/ARMDisassembler.c',
1385 'capstone/arch/ARM/ARMInstPrinter.c',
1386 'capstone/arch/ARM/ARMMapping.c',
1387 'capstone/arch/ARM/ARMModule.c'
1388 )
1389 endif
1390
1391 # FIXME: This config entry currently depends on a c++ compiler.
1392 # Which is needed for building libvixl, but not for capstone.
1393 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1394 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1395 capstone_files += files(
1396 'capstone/arch/AArch64/AArch64BaseInfo.c',
1397 'capstone/arch/AArch64/AArch64Disassembler.c',
1398 'capstone/arch/AArch64/AArch64InstPrinter.c',
1399 'capstone/arch/AArch64/AArch64Mapping.c',
1400 'capstone/arch/AArch64/AArch64Module.c'
1401 )
1402 endif
1403
1404 if 'CONFIG_PPC_DIS' in config_all_disas
1405 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1406 capstone_files += files(
1407 'capstone/arch/PowerPC/PPCDisassembler.c',
1408 'capstone/arch/PowerPC/PPCInstPrinter.c',
1409 'capstone/arch/PowerPC/PPCMapping.c',
1410 'capstone/arch/PowerPC/PPCModule.c'
1411 )
1412 endif
1413
1414 if 'CONFIG_S390_DIS' in config_all_disas
1415 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1416 capstone_files += files(
1417 'capstone/arch/SystemZ/SystemZDisassembler.c',
1418 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1419 'capstone/arch/SystemZ/SystemZMapping.c',
1420 'capstone/arch/SystemZ/SystemZModule.c',
1421 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1422 )
1423 endif
1424
1425 if 'CONFIG_I386_DIS' in config_all_disas
1426 capstone_data.set('CAPSTONE_HAS_X86', 1)
1427 capstone_files += files(
1428 'capstone/arch/X86/X86Disassembler.c',
1429 'capstone/arch/X86/X86DisassemblerDecoder.c',
1430 'capstone/arch/X86/X86ATTInstPrinter.c',
1431 'capstone/arch/X86/X86IntelInstPrinter.c',
1432 'capstone/arch/X86/X86InstPrinterCommon.c',
1433 'capstone/arch/X86/X86Mapping.c',
1434 'capstone/arch/X86/X86Module.c'
1435 )
1436 endif
1437
1438 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1439
1440 capstone_cargs = [
1441 # FIXME: There does not seem to be a way to completely replace the c_args
1442 # that come from add_project_arguments() -- we can only add to them.
1443 # So: disable all warnings with a big hammer.
1444 '-Wno-error', '-w',
1445
1446 # Include all configuration defines via a header file, which will wind up
1447 # as a dependency on the object file, and thus changes here will result
1448 # in a rebuild.
1449 '-include', 'capstone-defs.h'
1450 ]
1451
1452 libcapstone = static_library('capstone',
1453 sources: capstone_files,
1454 c_args: capstone_cargs,
1455 include_directories: 'capstone/include')
1456 capstone = declare_dependency(link_with: libcapstone,
1457 include_directories: 'capstone/include/capstone')
1458 endif
1459
1460 slirp = not_found
1461 slirp_opt = 'disabled'
1462 if have_system
1463 slirp_opt = get_option('slirp')
1464 if slirp_opt in ['enabled', 'auto', 'system']
1465 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1466 slirp = dependency('slirp', static: enable_static,
1467 method: 'pkg-config',
1468 required: slirp_opt == 'system' or
1469 slirp_opt == 'enabled' and not have_internal)
1470 if slirp.found()
1471 slirp_opt = 'system'
1472 elif have_internal
1473 slirp_opt = 'internal'
1474 else
1475 slirp_opt = 'disabled'
1476 endif
1477 endif
1478 if slirp_opt == 'internal'
1479 slirp_deps = []
1480 if targetos == 'windows'
1481 slirp_deps = cc.find_library('iphlpapi')
1482 endif
1483 slirp_conf = configuration_data()
1484 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1485 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1486 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1487 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1488 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1489 slirp_files = [
1490 'slirp/src/arp_table.c',
1491 'slirp/src/bootp.c',
1492 'slirp/src/cksum.c',
1493 'slirp/src/dhcpv6.c',
1494 'slirp/src/dnssearch.c',
1495 'slirp/src/if.c',
1496 'slirp/src/ip6_icmp.c',
1497 'slirp/src/ip6_input.c',
1498 'slirp/src/ip6_output.c',
1499 'slirp/src/ip_icmp.c',
1500 'slirp/src/ip_input.c',
1501 'slirp/src/ip_output.c',
1502 'slirp/src/mbuf.c',
1503 'slirp/src/misc.c',
1504 'slirp/src/ncsi.c',
1505 'slirp/src/ndp_table.c',
1506 'slirp/src/sbuf.c',
1507 'slirp/src/slirp.c',
1508 'slirp/src/socket.c',
1509 'slirp/src/state.c',
1510 'slirp/src/stream.c',
1511 'slirp/src/tcp_input.c',
1512 'slirp/src/tcp_output.c',
1513 'slirp/src/tcp_subr.c',
1514 'slirp/src/tcp_timer.c',
1515 'slirp/src/tftp.c',
1516 'slirp/src/udp.c',
1517 'slirp/src/udp6.c',
1518 'slirp/src/util.c',
1519 'slirp/src/version.c',
1520 'slirp/src/vmstate.c',
1521 ]
1522
1523 configure_file(
1524 input : 'slirp/src/libslirp-version.h.in',
1525 output : 'libslirp-version.h',
1526 configuration: slirp_conf)
1527
1528 slirp_inc = include_directories('slirp', 'slirp/src')
1529 libslirp = static_library('slirp',
1530 sources: slirp_files,
1531 c_args: slirp_cargs,
1532 include_directories: slirp_inc)
1533 slirp = declare_dependency(link_with: libslirp,
1534 dependencies: slirp_deps,
1535 include_directories: slirp_inc)
1536 endif
1537 endif
1538
1539 fdt = not_found
1540 fdt_opt = get_option('fdt')
1541 if have_system
1542 if fdt_opt in ['enabled', 'auto', 'system']
1543 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1544 fdt = cc.find_library('fdt', static: enable_static,
1545 required: fdt_opt == 'system' or
1546 fdt_opt == 'enabled' and not have_internal)
1547 if fdt.found() and cc.links('''
1548 #include <libfdt.h>
1549 #include <libfdt_env.h>
1550 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1551 dependencies: fdt)
1552 fdt_opt = 'system'
1553 elif have_internal
1554 fdt_opt = 'internal'
1555 else
1556 fdt_opt = 'disabled'
1557 endif
1558 endif
1559 if fdt_opt == 'internal'
1560 fdt_files = files(
1561 'dtc/libfdt/fdt.c',
1562 'dtc/libfdt/fdt_ro.c',
1563 'dtc/libfdt/fdt_wip.c',
1564 'dtc/libfdt/fdt_sw.c',
1565 'dtc/libfdt/fdt_rw.c',
1566 'dtc/libfdt/fdt_strerror.c',
1567 'dtc/libfdt/fdt_empty_tree.c',
1568 'dtc/libfdt/fdt_addresses.c',
1569 'dtc/libfdt/fdt_overlay.c',
1570 'dtc/libfdt/fdt_check.c',
1571 )
1572
1573 fdt_inc = include_directories('dtc/libfdt')
1574 libfdt = static_library('fdt',
1575 sources: fdt_files,
1576 include_directories: fdt_inc)
1577 fdt = declare_dependency(link_with: libfdt,
1578 include_directories: fdt_inc)
1579 endif
1580 endif
1581 if not fdt.found() and fdt_required.length() > 0
1582 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1583 endif
1584
1585 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1586 config_host_data.set('CONFIG_FDT', fdt.found())
1587 config_host_data.set('CONFIG_SLIRP', slirp.found())
1588
1589 #####################
1590 # Generated sources #
1591 #####################
1592
1593 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1594
1595 hxtool = find_program('scripts/hxtool')
1596 shaderinclude = find_program('scripts/shaderinclude.pl')
1597 qapi_gen = find_program('scripts/qapi-gen.py')
1598 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1599 meson.source_root() / 'scripts/qapi/commands.py',
1600 meson.source_root() / 'scripts/qapi/common.py',
1601 meson.source_root() / 'scripts/qapi/error.py',
1602 meson.source_root() / 'scripts/qapi/events.py',
1603 meson.source_root() / 'scripts/qapi/expr.py',
1604 meson.source_root() / 'scripts/qapi/gen.py',
1605 meson.source_root() / 'scripts/qapi/introspect.py',
1606 meson.source_root() / 'scripts/qapi/parser.py',
1607 meson.source_root() / 'scripts/qapi/schema.py',
1608 meson.source_root() / 'scripts/qapi/source.py',
1609 meson.source_root() / 'scripts/qapi/types.py',
1610 meson.source_root() / 'scripts/qapi/visit.py',
1611 meson.source_root() / 'scripts/qapi/common.py',
1612 meson.source_root() / 'scripts/qapi-gen.py'
1613 ]
1614
1615 tracetool = [
1616 python, files('scripts/tracetool.py'),
1617 '--backend=' + config_host['TRACE_BACKENDS']
1618 ]
1619
1620 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1621 meson.current_source_dir(),
1622 config_host['PKGVERSION'], meson.project_version()]
1623 qemu_version = custom_target('qemu-version.h',
1624 output: 'qemu-version.h',
1625 command: qemu_version_cmd,
1626 capture: true,
1627 build_by_default: true,
1628 build_always_stale: true)
1629 genh += qemu_version
1630
1631 hxdep = []
1632 hx_headers = [
1633 ['qemu-options.hx', 'qemu-options.def'],
1634 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1635 ]
1636 if have_system
1637 hx_headers += [
1638 ['hmp-commands.hx', 'hmp-commands.h'],
1639 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1640 ]
1641 endif
1642 foreach d : hx_headers
1643 hxdep += custom_target(d[1],
1644 input: files(d[0]),
1645 output: d[1],
1646 capture: true,
1647 build_by_default: true, # to be removed when added to a target
1648 command: [hxtool, '-h', '@INPUT0@'])
1649 endforeach
1650 genh += hxdep
1651
1652 ###################
1653 # Collect sources #
1654 ###################
1655
1656 authz_ss = ss.source_set()
1657 blockdev_ss = ss.source_set()
1658 block_ss = ss.source_set()
1659 bsd_user_ss = ss.source_set()
1660 chardev_ss = ss.source_set()
1661 common_ss = ss.source_set()
1662 crypto_ss = ss.source_set()
1663 io_ss = ss.source_set()
1664 linux_user_ss = ss.source_set()
1665 qmp_ss = ss.source_set()
1666 qom_ss = ss.source_set()
1667 softmmu_ss = ss.source_set()
1668 specific_fuzz_ss = ss.source_set()
1669 specific_ss = ss.source_set()
1670 stub_ss = ss.source_set()
1671 trace_ss = ss.source_set()
1672 user_ss = ss.source_set()
1673 util_ss = ss.source_set()
1674
1675 modules = {}
1676 hw_arch = {}
1677 target_arch = {}
1678 target_softmmu_arch = {}
1679
1680 ###############
1681 # Trace files #
1682 ###############
1683
1684 # TODO: add each directory to the subdirs from its own meson.build, once
1685 # we have those
1686 trace_events_subdirs = [
1687 'accel/kvm',
1688 'accel/tcg',
1689 'crypto',
1690 'monitor',
1691 ]
1692 if have_user
1693 trace_events_subdirs += [ 'linux-user' ]
1694 endif
1695 if have_block
1696 trace_events_subdirs += [
1697 'authz',
1698 'block',
1699 'io',
1700 'nbd',
1701 'scsi',
1702 ]
1703 endif
1704 if have_system
1705 trace_events_subdirs += [
1706 'audio',
1707 'backends',
1708 'backends/tpm',
1709 'chardev',
1710 'hw/9pfs',
1711 'hw/acpi',
1712 'hw/adc',
1713 'hw/alpha',
1714 'hw/arm',
1715 'hw/audio',
1716 'hw/block',
1717 'hw/block/dataplane',
1718 'hw/char',
1719 'hw/display',
1720 'hw/dma',
1721 'hw/hppa',
1722 'hw/hyperv',
1723 'hw/i2c',
1724 'hw/i386',
1725 'hw/i386/xen',
1726 'hw/ide',
1727 'hw/input',
1728 'hw/intc',
1729 'hw/isa',
1730 'hw/mem',
1731 'hw/mips',
1732 'hw/misc',
1733 'hw/misc/macio',
1734 'hw/net',
1735 'hw/net/can',
1736 'hw/nvram',
1737 'hw/pci',
1738 'hw/pci-host',
1739 'hw/ppc',
1740 'hw/rdma',
1741 'hw/rdma/vmw',
1742 'hw/rtc',
1743 'hw/s390x',
1744 'hw/scsi',
1745 'hw/sd',
1746 'hw/sparc',
1747 'hw/sparc64',
1748 'hw/ssi',
1749 'hw/timer',
1750 'hw/tpm',
1751 'hw/usb',
1752 'hw/vfio',
1753 'hw/virtio',
1754 'hw/watchdog',
1755 'hw/xen',
1756 'hw/gpio',
1757 'migration',
1758 'net',
1759 'softmmu',
1760 'ui',
1761 ]
1762 endif
1763 trace_events_subdirs += [
1764 'hw/core',
1765 'qapi',
1766 'qom',
1767 'target/arm',
1768 'target/hppa',
1769 'target/i386',
1770 'target/i386/kvm',
1771 'target/mips',
1772 'target/ppc',
1773 'target/riscv',
1774 'target/s390x',
1775 'target/sparc',
1776 'util',
1777 ]
1778
1779 vhost_user = not_found
1780 if 'CONFIG_VHOST_USER' in config_host
1781 libvhost_user = subproject('libvhost-user')
1782 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1783 endif
1784
1785 subdir('qapi')
1786 subdir('qobject')
1787 subdir('stubs')
1788 subdir('trace')
1789 subdir('util')
1790 subdir('qom')
1791 subdir('authz')
1792 subdir('crypto')
1793 subdir('ui')
1794
1795
1796 if enable_modules
1797 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1798 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1799 endif
1800
1801 stub_ss = stub_ss.apply(config_all, strict: false)
1802
1803 util_ss.add_all(trace_ss)
1804 util_ss = util_ss.apply(config_all, strict: false)
1805 libqemuutil = static_library('qemuutil',
1806 sources: util_ss.sources() + stub_ss.sources() + genh,
1807 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1808 qemuutil = declare_dependency(link_with: libqemuutil,
1809 sources: genh + version_res)
1810
1811 decodetree = generator(find_program('scripts/decodetree.py'),
1812 output: 'decode-@BASENAME@.c.inc',
1813 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1814
1815 subdir('audio')
1816 subdir('io')
1817 subdir('chardev')
1818 subdir('fsdev')
1819 subdir('libdecnumber')
1820 subdir('target')
1821 subdir('dump')
1822
1823 block_ss.add(files(
1824 'block.c',
1825 'blockjob.c',
1826 'job.c',
1827 'qemu-io-cmds.c',
1828 ))
1829 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1830
1831 subdir('nbd')
1832 subdir('scsi')
1833 subdir('block')
1834
1835 blockdev_ss.add(files(
1836 'blockdev.c',
1837 'blockdev-nbd.c',
1838 'iothread.c',
1839 'job-qmp.c',
1840 ), gnutls)
1841
1842 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1843 # os-win32.c does not
1844 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1845 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1846
1847 common_ss.add(files('cpus-common.c'))
1848
1849 subdir('softmmu')
1850
1851 common_ss.add(capstone)
1852 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1853 specific_ss.add(files('exec-vary.c'))
1854 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1855 'fpu/softfloat.c',
1856 'tcg/optimize.c',
1857 'tcg/tcg-common.c',
1858 'tcg/tcg-op-gvec.c',
1859 'tcg/tcg-op-vec.c',
1860 'tcg/tcg-op.c',
1861 'tcg/tcg.c',
1862 ))
1863 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1864
1865 subdir('backends')
1866 subdir('disas')
1867 subdir('migration')
1868 subdir('monitor')
1869 subdir('net')
1870 subdir('replay')
1871 subdir('hw')
1872 subdir('accel')
1873 subdir('plugins')
1874 subdir('bsd-user')
1875 subdir('linux-user')
1876
1877 bsd_user_ss.add(files('gdbstub.c'))
1878 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1879
1880 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1881 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1882
1883 # needed for fuzzing binaries
1884 subdir('tests/qtest/libqos')
1885 subdir('tests/qtest/fuzz')
1886
1887 ########################
1888 # Library dependencies #
1889 ########################
1890
1891 block_mods = []
1892 softmmu_mods = []
1893 foreach d, list : modules
1894 foreach m, module_ss : list
1895 if enable_modules and targetos != 'windows'
1896 module_ss = module_ss.apply(config_all, strict: false)
1897 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1898 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1899 if d == 'block'
1900 block_mods += sl
1901 else
1902 softmmu_mods += sl
1903 endif
1904 else
1905 if d == 'block'
1906 block_ss.add_all(module_ss)
1907 else
1908 softmmu_ss.add_all(module_ss)
1909 endif
1910 endif
1911 endforeach
1912 endforeach
1913
1914 nm = find_program('nm')
1915 undefsym = find_program('scripts/undefsym.py')
1916 block_syms = custom_target('block.syms', output: 'block.syms',
1917 input: [libqemuutil, block_mods],
1918 capture: true,
1919 command: [undefsym, nm, '@INPUT@'])
1920 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1921 input: [libqemuutil, softmmu_mods],
1922 capture: true,
1923 command: [undefsym, nm, '@INPUT@'])
1924
1925 qom_ss = qom_ss.apply(config_host, strict: false)
1926 libqom = static_library('qom', qom_ss.sources() + genh,
1927 dependencies: [qom_ss.dependencies()],
1928 name_suffix: 'fa')
1929
1930 qom = declare_dependency(link_whole: libqom)
1931
1932 authz_ss = authz_ss.apply(config_host, strict: false)
1933 libauthz = static_library('authz', authz_ss.sources() + genh,
1934 dependencies: [authz_ss.dependencies()],
1935 name_suffix: 'fa',
1936 build_by_default: false)
1937
1938 authz = declare_dependency(link_whole: libauthz,
1939 dependencies: qom)
1940
1941 crypto_ss = crypto_ss.apply(config_host, strict: false)
1942 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1943 dependencies: [crypto_ss.dependencies()],
1944 name_suffix: 'fa',
1945 build_by_default: false)
1946
1947 crypto = declare_dependency(link_whole: libcrypto,
1948 dependencies: [authz, qom])
1949
1950 io_ss = io_ss.apply(config_host, strict: false)
1951 libio = static_library('io', io_ss.sources() + genh,
1952 dependencies: [io_ss.dependencies()],
1953 link_with: libqemuutil,
1954 name_suffix: 'fa',
1955 build_by_default: false)
1956
1957 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1958
1959 libmigration = static_library('migration', sources: migration_files + genh,
1960 name_suffix: 'fa',
1961 build_by_default: false)
1962 migration = declare_dependency(link_with: libmigration,
1963 dependencies: [zlib, qom, io])
1964 softmmu_ss.add(migration)
1965
1966 block_ss = block_ss.apply(config_host, strict: false)
1967 libblock = static_library('block', block_ss.sources() + genh,
1968 dependencies: block_ss.dependencies(),
1969 link_depends: block_syms,
1970 name_suffix: 'fa',
1971 build_by_default: false)
1972
1973 block = declare_dependency(link_whole: [libblock],
1974 link_args: '@block.syms',
1975 dependencies: [crypto, io])
1976
1977 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1978 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1979 dependencies: blockdev_ss.dependencies(),
1980 name_suffix: 'fa',
1981 build_by_default: false)
1982
1983 blockdev = declare_dependency(link_whole: [libblockdev],
1984 dependencies: [block])
1985
1986 qmp_ss = qmp_ss.apply(config_host, strict: false)
1987 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1988 dependencies: qmp_ss.dependencies(),
1989 name_suffix: 'fa',
1990 build_by_default: false)
1991
1992 qmp = declare_dependency(link_whole: [libqmp])
1993
1994 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1995 name_suffix: 'fa',
1996 dependencies: [gnutls],
1997 build_by_default: false)
1998
1999 chardev = declare_dependency(link_whole: libchardev)
2000
2001 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2002 name_suffix: 'fa',
2003 build_by_default: false)
2004 hwcore = declare_dependency(link_whole: libhwcore)
2005 common_ss.add(hwcore)
2006
2007 ###########
2008 # Targets #
2009 ###########
2010
2011 foreach m : block_mods + softmmu_mods
2012 shared_module(m.name(),
2013 name_prefix: '',
2014 link_whole: m,
2015 install: true,
2016 install_dir: qemu_moddir)
2017 endforeach
2018
2019 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2020 common_ss.add(qom, qemuutil)
2021
2022 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2023 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2024
2025 common_all = common_ss.apply(config_all, strict: false)
2026 common_all = static_library('common',
2027 build_by_default: false,
2028 sources: common_all.sources() + genh,
2029 dependencies: common_all.dependencies(),
2030 name_suffix: 'fa')
2031
2032 feature_to_c = find_program('scripts/feature_to_c.sh')
2033
2034 emulators = {}
2035 foreach target : target_dirs
2036 config_target = config_target_mak[target]
2037 target_name = config_target['TARGET_NAME']
2038 arch = config_target['TARGET_BASE_ARCH']
2039 arch_srcs = [config_target_h[target]]
2040 arch_deps = []
2041 c_args = ['-DNEED_CPU_H',
2042 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2043 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2044 link_args = emulator_link_args
2045
2046 config_target += config_host
2047 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2048 if targetos == 'linux'
2049 target_inc += include_directories('linux-headers', is_system: true)
2050 endif
2051 if target.endswith('-softmmu')
2052 qemu_target_name = 'qemu-system-' + target_name
2053 target_type='system'
2054 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2055 arch_srcs += t.sources()
2056 arch_deps += t.dependencies()
2057
2058 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2059 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2060 arch_srcs += hw.sources()
2061 arch_deps += hw.dependencies()
2062
2063 arch_srcs += config_devices_h[target]
2064 link_args += ['@block.syms', '@qemu.syms']
2065 else
2066 abi = config_target['TARGET_ABI_DIR']
2067 target_type='user'
2068 qemu_target_name = 'qemu-' + target_name
2069 if 'CONFIG_LINUX_USER' in config_target
2070 base_dir = 'linux-user'
2071 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2072 else
2073 base_dir = 'bsd-user'
2074 target_inc += include_directories('bsd-user/freebsd')
2075 endif
2076 target_inc += include_directories(
2077 base_dir,
2078 base_dir / abi,
2079 )
2080 if 'CONFIG_LINUX_USER' in config_target
2081 dir = base_dir / abi
2082 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2083 if config_target.has_key('TARGET_SYSTBL_ABI')
2084 arch_srcs += \
2085 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2086 extra_args : config_target['TARGET_SYSTBL_ABI'])
2087 endif
2088 endif
2089 endif
2090
2091 if 'TARGET_XML_FILES' in config_target
2092 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2093 output: target + '-gdbstub-xml.c',
2094 input: files(config_target['TARGET_XML_FILES'].split()),
2095 command: [feature_to_c, '@INPUT@'],
2096 capture: true)
2097 arch_srcs += gdbstub_xml
2098 endif
2099
2100 t = target_arch[arch].apply(config_target, strict: false)
2101 arch_srcs += t.sources()
2102 arch_deps += t.dependencies()
2103
2104 target_common = common_ss.apply(config_target, strict: false)
2105 objects = common_all.extract_objects(target_common.sources())
2106 deps = target_common.dependencies()
2107
2108 target_specific = specific_ss.apply(config_target, strict: false)
2109 arch_srcs += target_specific.sources()
2110 arch_deps += target_specific.dependencies()
2111
2112 lib = static_library('qemu-' + target,
2113 sources: arch_srcs + genh,
2114 dependencies: arch_deps,
2115 objects: objects,
2116 include_directories: target_inc,
2117 c_args: c_args,
2118 build_by_default: false,
2119 name_suffix: 'fa')
2120
2121 if target.endswith('-softmmu')
2122 execs = [{
2123 'name': 'qemu-system-' + target_name,
2124 'gui': false,
2125 'sources': files('softmmu/main.c'),
2126 'dependencies': []
2127 }]
2128 if targetos == 'windows' and (sdl.found() or gtk.found())
2129 execs += [{
2130 'name': 'qemu-system-' + target_name + 'w',
2131 'gui': true,
2132 'sources': files('softmmu/main.c'),
2133 'dependencies': []
2134 }]
2135 endif
2136 if config_host.has_key('CONFIG_FUZZ')
2137 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2138 execs += [{
2139 'name': 'qemu-fuzz-' + target_name,
2140 'gui': false,
2141 'sources': specific_fuzz.sources(),
2142 'dependencies': specific_fuzz.dependencies(),
2143 }]
2144 endif
2145 else
2146 execs = [{
2147 'name': 'qemu-' + target_name,
2148 'gui': false,
2149 'sources': [],
2150 'dependencies': []
2151 }]
2152 endif
2153 foreach exe: execs
2154 emulators += {exe['name']:
2155 executable(exe['name'], exe['sources'],
2156 install: true,
2157 c_args: c_args,
2158 dependencies: arch_deps + deps + exe['dependencies'],
2159 objects: lib.extract_all_objects(recursive: true),
2160 link_language: link_language,
2161 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2162 link_args: link_args,
2163 gui_app: exe['gui'])
2164 }
2165
2166 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2167 foreach stp: [
2168 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2169 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2170 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2171 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2172 ]
2173 custom_target(exe['name'] + stp['ext'],
2174 input: trace_events_all,
2175 output: exe['name'] + stp['ext'],
2176 install: stp['install'],
2177 install_dir: get_option('datadir') / 'systemtap/tapset',
2178 command: [
2179 tracetool, '--group=all', '--format=' + stp['fmt'],
2180 '--binary=' + stp['bin'],
2181 '--target-name=' + target_name,
2182 '--target-type=' + target_type,
2183 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2184 '@INPUT@', '@OUTPUT@'
2185 ])
2186 endforeach
2187 endif
2188 endforeach
2189 endforeach
2190
2191 # Other build targets
2192
2193 if 'CONFIG_PLUGIN' in config_host
2194 install_headers('include/qemu/qemu-plugin.h')
2195 endif
2196
2197 if 'CONFIG_GUEST_AGENT' in config_host
2198 subdir('qga')
2199 elif get_option('guest_agent_msi').enabled()
2200 error('Guest agent MSI requested, but the guest agent is not being built')
2201 endif
2202
2203 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2204 # when we don't build tools or system
2205 if xkbcommon.found()
2206 # used for the update-keymaps target, so include rules even if !have_tools
2207 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2208 dependencies: [qemuutil, xkbcommon], install: have_tools)
2209 endif
2210
2211 if have_tools
2212 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2213 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2214 qemu_io = executable('qemu-io', files('qemu-io.c'),
2215 dependencies: [block, qemuutil], install: true)
2216 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2217 dependencies: [blockdev, qemuutil, gnutls], install: true)
2218
2219 subdir('storage-daemon')
2220 subdir('contrib/rdmacm-mux')
2221 subdir('contrib/elf2dmp')
2222
2223 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2224 dependencies: qemuutil,
2225 install: true)
2226
2227 if 'CONFIG_VHOST_USER' in config_host
2228 subdir('contrib/vhost-user-blk')
2229 subdir('contrib/vhost-user-gpu')
2230 subdir('contrib/vhost-user-input')
2231 subdir('contrib/vhost-user-scsi')
2232 endif
2233
2234 if targetos == 'linux'
2235 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2236 dependencies: [qemuutil, libcap_ng],
2237 install: true,
2238 install_dir: get_option('libexecdir'))
2239
2240 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2241 dependencies: [authz, crypto, io, qom, qemuutil,
2242 libcap_ng, mpathpersist],
2243 install: true)
2244 endif
2245
2246 if 'CONFIG_IVSHMEM' in config_host
2247 subdir('contrib/ivshmem-client')
2248 subdir('contrib/ivshmem-server')
2249 endif
2250 endif
2251
2252 subdir('scripts')
2253 subdir('tools')
2254 subdir('pc-bios')
2255 subdir('docs')
2256 subdir('tests')
2257 if gtk.found()
2258 subdir('po')
2259 endif
2260
2261 if host_machine.system() == 'windows'
2262 nsis_cmd = [
2263 find_program('scripts/nsis.py'),
2264 '@OUTPUT@',
2265 get_option('prefix'),
2266 meson.current_source_dir(),
2267 host_machine.cpu(),
2268 '--',
2269 '-DDISPLAYVERSION=' + meson.project_version(),
2270 ]
2271 if build_docs
2272 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2273 endif
2274 if gtk.found()
2275 nsis_cmd += '-DCONFIG_GTK=y'
2276 endif
2277
2278 nsis = custom_target('nsis',
2279 output: 'qemu-setup-' + meson.project_version() + '.exe',
2280 input: files('qemu.nsi'),
2281 build_always_stale: true,
2282 command: nsis_cmd + ['@INPUT@'])
2283 alias_target('installer', nsis)
2284 endif
2285
2286 #########################
2287 # Configuration summary #
2288 #########################
2289
2290 # Directories
2291 summary_info = {}
2292 summary_info += {'Install prefix': get_option('prefix')}
2293 summary_info += {'BIOS directory': qemu_datadir}
2294 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2295 summary_info += {'binary directory': get_option('bindir')}
2296 summary_info += {'library directory': get_option('libdir')}
2297 summary_info += {'module directory': qemu_moddir}
2298 summary_info += {'libexec directory': get_option('libexecdir')}
2299 summary_info += {'include directory': get_option('includedir')}
2300 summary_info += {'config directory': get_option('sysconfdir')}
2301 if targetos != 'windows'
2302 summary_info += {'local state directory': get_option('localstatedir')}
2303 summary_info += {'Manual directory': get_option('mandir')}
2304 else
2305 summary_info += {'local state directory': 'queried at runtime'}
2306 endif
2307 summary_info += {'Doc directory': get_option('docdir')}
2308 summary_info += {'Build directory': meson.current_build_dir()}
2309 summary_info += {'Source path': meson.current_source_dir()}
2310 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2311 summary(summary_info, bool_yn: true, section: 'Directories')
2312
2313 # Host binaries
2314 summary_info = {}
2315 summary_info += {'git': config_host['GIT']}
2316 summary_info += {'make': config_host['MAKE']}
2317 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2318 summary_info += {'sphinx-build': sphinx_build.found()}
2319 if config_host.has_key('HAVE_GDB_BIN')
2320 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2321 endif
2322 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2323 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2324 summary_info += {'wixl': wixl.found() ? wixl.full_path() : false}
2325 endif
2326 if slirp_opt != 'disabled'
2327 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2328 endif
2329 summary(summary_info, bool_yn: true, section: 'Host binaries')
2330
2331 # Configurable features
2332 summary_info = {}
2333 summary_info += {'Documentation': build_docs}
2334 summary_info += {'system-mode emulation': have_system}
2335 summary_info += {'user-mode emulation': have_user}
2336 summary_info += {'Install blobs': get_option('install_blobs')}
2337 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2338 if config_host.has_key('CONFIG_MODULES')
2339 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2340 endif
2341 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2342 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2343 if have_system
2344 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2345 endif
2346 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2347 if config_host['TRACE_BACKENDS'].split().contains('simple')
2348 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2349 endif
2350 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2351 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2352 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2353 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2354 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2355 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2356 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2357 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2358 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2359 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2360 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2361 summary(summary_info, bool_yn: true, section: 'Configurable features')
2362
2363 # Compilation information
2364 summary_info = {}
2365 summary_info += {'host CPU': cpu}
2366 summary_info += {'host endianness': build_machine.endian()}
2367 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
2368 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
2369 if link_language == 'cpp'
2370 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
2371 else
2372 summary_info += {'C++ compiler': false}
2373 endif
2374 if targetos == 'darwin'
2375 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2376 endif
2377 if targetos == 'windows'
2378 if 'WIN_SDK' in config_host
2379 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2380 endif
2381 endif
2382 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2383 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2384 + ['-O' + get_option('optimization')]
2385 + (get_option('debug') ? ['-g'] : []))}
2386 if link_language == 'cpp'
2387 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2388 + ['-O' + get_option('optimization')]
2389 + (get_option('debug') ? ['-g'] : []))}
2390 endif
2391 link_args = get_option(link_language + '_link_args')
2392 if link_args.length() > 0
2393 summary_info += {'LDFLAGS': ' '.join(link_args)}
2394 endif
2395 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2396 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2397 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2398 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2399 summary_info += {'PIE': get_option('b_pie')}
2400 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2401 summary_info += {'malloc trim support': has_malloc_trim}
2402 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2403 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2404 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2405 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2406 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2407 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2408 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2409 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2410 summary_info += {'memory allocator': get_option('malloc')}
2411 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2412 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2413 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2414 summary_info += {'gcov': get_option('b_coverage')}
2415 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2416 summary_info += {'CFI support': get_option('cfi')}
2417 if get_option('cfi')
2418 summary_info += {'CFI debug support': get_option('cfi_debug')}
2419 endif
2420 summary_info += {'strip binaries': get_option('strip')}
2421 summary_info += {'sparse': sparse.found() ? sparse.full_path() : false}
2422 summary_info += {'mingw32 support': targetos == 'windows'}
2423 summary(summary_info, bool_yn: true, section: 'Compilation')
2424
2425 # Targets and accelerators
2426 summary_info = {}
2427 if have_system
2428 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2429 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2430 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2431 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2432 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2433 if config_host.has_key('CONFIG_XEN_BACKEND')
2434 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2435 endif
2436 endif
2437 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2438 if config_all.has_key('CONFIG_TCG')
2439 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2440 summary_info += {'TCG interpreter': tcg_arch == 'tci'}
2441 endif
2442 summary_info += {'target list': ' '.join(target_dirs)}
2443 if have_system
2444 summary_info += {'default devices': get_option('default_devices')}
2445 endif
2446 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2447
2448 summary_info = {}
2449 if targetos == 'darwin'
2450 summary_info += {'Cocoa support': cocoa.found()}
2451 endif
2452 # TODO: add back version
2453 summary_info += {'SDL support': sdl.found()}
2454 summary_info += {'SDL image support': sdl_image.found()}
2455 # TODO: add back version
2456 summary_info += {'GTK support': gtk.found()}
2457 summary_info += {'pixman': pixman.found()}
2458 # TODO: add back version
2459 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2460 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2461 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
2462 # TODO: add back version
2463 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
2464 if config_host.has_key('CONFIG_GCRYPT')
2465 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
2466 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2467 endif
2468 # TODO: add back version
2469 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
2470 if config_host.has_key('CONFIG_NETTLE')
2471 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2472 endif
2473 # TODO: add back version
2474 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2475 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
2476 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2477 summary_info += {'iconv support': iconv.found()}
2478 summary_info += {'curses support': curses.found()}
2479 # TODO: add back version
2480 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2481 summary_info += {'curl support': curl.found()}
2482 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2483 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2484 summary_info += {'VirtFS support': have_virtfs}
2485 summary_info += {'build virtiofs daemon': have_virtiofsd}
2486 summary_info += {'Multipath support': mpathpersist.found()}
2487 summary_info += {'VNC support': vnc.found()}
2488 if vnc.found()
2489 summary_info += {'VNC SASL support': sasl.found()}
2490 summary_info += {'VNC JPEG support': jpeg.found()}
2491 summary_info += {'VNC PNG support': png.found()}
2492 endif
2493 summary_info += {'brlapi support': brlapi.found()}
2494 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2495 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2496 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2497 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2498 summary_info += {'ATTR/XATTR support': libattr.found()}
2499 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2500 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2501 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2502 summary_info += {'libcap-ng support': libcap_ng.found()}
2503 # TODO: add back protocol and server version
2504 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2505 summary_info += {'rbd support': rbd.found()}
2506 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2507 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2508 summary_info += {'U2F support': u2f.found()}
2509 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2510 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2511 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2512 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2513 summary_info += {'libiscsi support': libiscsi.found()}
2514 summary_info += {'libnfs support': libnfs.found()}
2515 if targetos == 'windows'
2516 if config_host.has_key('CONFIG_GUEST_AGENT')
2517 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2518 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2519 endif
2520 endif
2521 summary_info += {'seccomp support': seccomp.found()}
2522 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2523 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2524 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2525 summary_info += {'GlusterFS support': glusterfs.found()}
2526 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2527 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2528 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2529 summary_info += {'lzo support': lzo.found()}
2530 summary_info += {'snappy support': snappy.found()}
2531 summary_info += {'bzip2 support': libbzip2.found()}
2532 summary_info += {'lzfse support': liblzfse.found()}
2533 summary_info += {'zstd support': zstd.found()}
2534 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2535 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2536 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2537 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2538 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2539 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2540 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2541 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2542 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2543 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2544 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2545 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
2546 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2547 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2548 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2549 summary_info += {'libudev': libudev.found()}
2550 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2551 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2552 summary_info += {'FUSE exports': fuse.found()}
2553 summary_info += {'FUSE lseek': fuse_lseek.found()}
2554 summary(summary_info, bool_yn: true)
2555
2556 if not supported_cpus.contains(cpu)
2557 message()
2558 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2559 message()
2560 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2561 message('The QEMU project intends to remove support for this host CPU in')
2562 message('a future release if nobody volunteers to maintain it and to')
2563 message('provide a build host for our continuous integration setup.')
2564 message('configure has succeeded and you can continue to build, but')
2565 message('if you care about QEMU on this platform you should contact')
2566 message('us upstream at qemu-devel@nongnu.org.')
2567 endif
2568
2569 if not supported_oses.contains(targetos)
2570 message()
2571 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2572 message()
2573 message('Host OS ' + targetos + 'support is not currently maintained.')
2574 message('The QEMU project intends to remove support for this host OS in')
2575 message('a future release if nobody volunteers to maintain it and to')
2576 message('provide a build host for our continuous integration setup.')
2577 message('configure has succeeded and you can continue to build, but')
2578 message('if you care about QEMU on this platform you should contact')
2579 message('us upstream at qemu-devel@nongnu.org.')
2580 endif