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