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