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