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