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