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