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