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