xref: /openbmc/qemu/meson.build (revision 70122d62302c97bcd205956a544b8e79f2a4a50f)
1project('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())
5
6not_found = dependency('', required: false)
7if meson.version().version_compare('>=0.56.0')
8  keyval = import('keyval')
9else
10  keyval = import('unstable-keyval')
11endif
12ss = import('sourceset')
13fs = import('fs')
14
15sh = find_program('sh')
16cc = meson.get_compiler('c')
17config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18enable_modules = 'CONFIG_MODULES' in config_host
19enable_static = 'CONFIG_STATIC' in config_host
20build_docs = 'BUILD_DOCS' in config_host
21
22if get_option('qemu_suffix').startswith('/')
23  error('qemu_suffix cannot start with a /')
24endif
25
26qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
27qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
28config_host_data = configuration_data()
29genh = []
30
31target_dirs = config_host['TARGET_DIRS'].split()
32have_user = false
33have_system = false
34foreach target : target_dirs
35  have_user = have_user or target.endswith('-user')
36  have_system = have_system or target.endswith('-softmmu')
37endforeach
38have_tools = 'CONFIG_TOOLS' in config_host
39have_block = have_system or have_tools
40
41python = import('python').find_installation()
42
43supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
44supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
45  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
46
47cpu = host_machine.cpu_family()
48targetos = host_machine.system()
49
50configure_file(input: files('scripts/ninjatool.py'),
51               output: 'ninjatool',
52               configuration: config_host)
53
54if cpu in ['x86', 'x86_64']
55  kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
56elif cpu == 'aarch64'
57  kvm_targets = ['aarch64-softmmu']
58elif cpu == 's390x'
59  kvm_targets = ['s390x-softmmu']
60elif cpu in ['ppc', 'ppc64']
61  kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
62elif cpu in ['mips', 'mips64']
63  kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
64else
65  kvm_targets = []
66endif
67
68accelerator_targets = { 'CONFIG_KVM': kvm_targets }
69if 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  }
76endif
77
78##################
79# Compiler flags #
80##################
81
82# Specify linker-script with add_project_link_arguments so that it is not placed
83# within a linker --start-group/--end-group pair
84if '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'])
88endif
89
90add_project_arguments(config_host['QEMU_CFLAGS'].split(),
91                      native: false, language: ['c', 'objc'])
92add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
93                      native: false, language: 'cpp')
94add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
95                           native: false, language: ['c', 'cpp', 'objc'])
96add_project_arguments(config_host['QEMU_INCLUDES'].split(),
97                      language: ['c', 'cpp', 'objc'])
98
99
100link_language = meson.get_external_property('link_language', 'cpp')
101if link_language == 'cpp'
102  add_languages('cpp', required: true, native: false)
103endif
104if host_machine.system() == 'darwin'
105  add_languages('objc', required: false, native: false)
106endif
107
108sparse = find_program('cgcc', required: get_option('sparse'))
109if 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'])
115endif
116
117###########################################
118# Target-specific checks and dependencies #
119###########################################
120
121if targetos != 'linux' and get_option('mpath').enabled()
122  error('Multipath is supported only on Linux')
123endif
124
125m = cc.find_library('m', required: false)
126util = cc.find_library('util', required: false)
127winmm = []
128socket = []
129version_res = []
130coref = []
131iokit = []
132emulator_link_args = []
133cocoa = not_found
134hvf = not_found
135if targetos == 'windows'
136  socket = cc.find_library('ws2_32')
137  winmm = cc.find_library('winmm')
138
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('.'))
143elif targetos == 'darwin'
144  coref = dependency('appleframeworks', modules: 'CoreFoundation')
145  iokit = dependency('appleframeworks', modules: 'IOKit')
146  cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
147elif targetos == 'sunos'
148  socket = [cc.find_library('socket'),
149            cc.find_library('nsl'),
150            cc.find_library('resolv')]
151elif targetos == 'haiku'
152  socket = [cc.find_library('posix_error_mapper'),
153            cc.find_library('network'),
154            cc.find_library('bsd')]
155elif 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
160endif
161
162accelerators = []
163if not get_option('kvm').disabled() and targetos == 'linux'
164  accelerators += 'CONFIG_KVM'
165endif
166if 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'
169else
170  have_xen_pci_passthrough = false
171endif
172if 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
179endif
180if 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
186endif
187if not get_option('hax').disabled()
188  if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
189    accelerators += 'CONFIG_HAX'
190  endif
191endif
192if 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' }
202endif
203
204if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
205  error('KVM not available on this platform')
206endif
207if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
208  error('HVF not available on this platform')
209endif
210if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
211  error('WHPX not available on this platform')
212endif
213if 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
219endif
220if not cocoa.found() and get_option('cocoa').enabled()
221  error('Cocoa not available on this platform')
222endif
223
224################
225# Dependencies #
226################
227
228# The path to glib.h is added to all compilation commands.  This was
229# grandfathered in from the QEMU Makefiles.
230add_project_arguments(config_host['GLIB_CFLAGS'].split(),
231                      native: false, language: ['c', 'cpp', 'objc'])
232glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
233gio = not_found
234if 'CONFIG_GIO' in config_host
235  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
236                           link_args: config_host['GIO_LIBS'].split())
237endif
238lttng = not_found
239if 'CONFIG_TRACE_UST' in config_host
240  lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
241endif
242urcubp = not_found
243if 'CONFIG_TRACE_UST' in config_host
244  urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
245endif
246gcrypt = not_found
247if 'CONFIG_GCRYPT' in config_host
248  gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
249                              link_args: config_host['GCRYPT_LIBS'].split())
250endif
251nettle = not_found
252if 'CONFIG_NETTLE' in config_host
253  nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
254                              link_args: config_host['NETTLE_LIBS'].split())
255endif
256gnutls = not_found
257if 'CONFIG_GNUTLS' in config_host
258  gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
259                              link_args: config_host['GNUTLS_LIBS'].split())
260endif
261pixman = not_found
262if have_system or have_tools
263  pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
264                      method: 'pkg-config', static: enable_static)
265endif
266pam = not_found
267if 'CONFIG_AUTH_PAM' in config_host
268  pam = cc.find_library('pam')
269endif
270libaio = cc.find_library('aio', required: false)
271zlib = dependency('zlib', required: true, static: enable_static)
272linux_io_uring = not_found
273if '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())
276endif
277libxml2 = not_found
278if 'CONFIG_LIBXML2' in config_host
279  libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
280                               link_args: config_host['LIBXML2_LIBS'].split())
281endif
282libnfs = not_found
283if 'CONFIG_LIBNFS' in config_host
284  libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
285endif
286libattr = not_found
287if 'CONFIG_ATTR' in config_host
288  libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
289endif
290seccomp = not_found
291if 'CONFIG_SECCOMP' in config_host
292  seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
293                               link_args: config_host['SECCOMP_LIBS'].split())
294endif
295libcap_ng = not_found
296if 'CONFIG_LIBCAP_NG' in config_host
297  libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
298endif
299if get_option('xkbcommon').auto() and not have_system and not have_tools
300  xkbcommon = not_found
301else
302  xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
303                         method: 'pkg-config', static: enable_static)
304endif
305vde = not_found
306if config_host.has_key('CONFIG_VDE')
307  vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
308endif
309pulse = not_found
310if 'CONFIG_LIBPULSE' in config_host
311  pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
312                             link_args: config_host['PULSE_LIBS'].split())
313endif
314alsa = not_found
315if 'CONFIG_ALSA' in config_host
316  alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
317                            link_args: config_host['ALSA_LIBS'].split())
318endif
319jack = not_found
320if 'CONFIG_LIBJACK' in config_host
321  jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
322endif
323spice = not_found
324if 'CONFIG_SPICE' in config_host
325  spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
326                             link_args: config_host['SPICE_LIBS'].split())
327endif
328rt = cc.find_library('rt', required: false)
329libdl = not_found
330if 'CONFIG_PLUGIN' in config_host
331  libdl = cc.find_library('dl', required: true)
332endif
333libiscsi = not_found
334if 'CONFIG_LIBISCSI' in config_host
335  libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
336                                link_args: config_host['LIBISCSI_LIBS'].split())
337endif
338zstd = not_found
339if 'CONFIG_ZSTD' in config_host
340  zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
341                            link_args: config_host['ZSTD_LIBS'].split())
342endif
343gbm = not_found
344if 'CONFIG_GBM' in config_host
345  gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
346                           link_args: config_host['GBM_LIBS'].split())
347endif
348virgl = not_found
349if 'CONFIG_VIRGL' in config_host
350  virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
351                             link_args: config_host['VIRGL_LIBS'].split())
352endif
353curl = not_found
354if 'CONFIG_CURL' in config_host
355  curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
356                            link_args: config_host['CURL_LIBS'].split())
357endif
358libudev = not_found
359if targetos == 'linux' and (have_system or have_tools)
360  libudev = dependency('libudev',
361                       required: get_option('mpath').enabled(),
362                       static: enable_static)
363endif
364
365mpathpersist = not_found
366mpathpersist_new_api = false
367if 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
427endif
428
429iconv = not_found
430if 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
444endif
445if get_option('iconv').enabled() and not iconv.found()
446  error('Cannot detect iconv API')
447endif
448
449curses = not_found
450if 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)
470
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
488endif
489if 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
495endif
496
497brlapi = not_found
498if 'CONFIG_BRLAPI' in config_host
499  brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
500endif
501
502sdl = not_found
503if have_system
504  sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
505  sdl_image = not_found
506endif
507if 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)
513else
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
519endif
520
521rbd = not_found
522if 'CONFIG_RBD' in config_host
523  rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
524endif
525glusterfs = not_found
526if 'CONFIG_GLUSTERFS' in config_host
527  glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
528                                 link_args: config_host['GLUSTERFS_LIBS'].split())
529endif
530libssh = not_found
531if 'CONFIG_LIBSSH' in config_host
532  libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
533                              link_args: config_host['LIBSSH_LIBS'].split())
534endif
535libbzip2 = not_found
536if 'CONFIG_BZIP2' in config_host
537  libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
538endif
539liblzfse = not_found
540if 'CONFIG_LZFSE' in config_host
541  liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
542endif
543oss = not_found
544if 'CONFIG_AUDIO_OSS' in config_host
545  oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
546endif
547dsound = not_found
548if 'CONFIG_AUDIO_DSOUND' in config_host
549  dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
550endif
551coreaudio = not_found
552if 'CONFIG_AUDIO_COREAUDIO' in config_host
553  coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
554endif
555opengl = not_found
556if 'CONFIG_OPENGL' in config_host
557  opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
558                              link_args: config_host['OPENGL_LIBS'].split())
559endif
560gtk = not_found
561if 'CONFIG_GTK' in config_host
562  gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
563                              link_args: config_host['GTK_LIBS'].split())
564endif
565vte = not_found
566if 'CONFIG_VTE' in config_host
567  vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
568                           link_args: config_host['VTE_LIBS'].split())
569endif
570x11 = not_found
571if 'CONFIG_X11' in config_host
572  x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
573                           link_args: config_host['X11_LIBS'].split())
574endif
575vnc = not_found
576png = not_found
577jpeg = not_found
578sasl = not_found
579if 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
593endif
594snappy = not_found
595if 'CONFIG_SNAPPY' in config_host
596  snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
597endif
598lzo = not_found
599if 'CONFIG_LZO' in config_host
600  lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
601endif
602rdma = not_found
603if 'CONFIG_RDMA' in config_host
604  rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
605endif
606numa = not_found
607if 'CONFIG_NUMA' in config_host
608  numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
609endif
610xen = not_found
611if '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())
614endif
615cacard = not_found
616if 'CONFIG_SMARTCARD' in config_host
617  cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
618                              link_args: config_host['SMARTCARD_LIBS'].split())
619endif
620u2f = not_found
621if have_system
622  u2f = dependency('u2f-emu', required: get_option('u2f'),
623                   method: 'pkg-config',
624                   static: enable_static)
625endif
626usbredir = not_found
627if '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())
630endif
631libusb = not_found
632if '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())
635endif
636libpmem = not_found
637if 'CONFIG_LIBPMEM' in config_host
638  libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
639                               link_args: config_host['LIBPMEM_LIBS'].split())
640endif
641libdaxctl = not_found
642if 'CONFIG_LIBDAXCTL' in config_host
643  libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
644endif
645tasn1 = not_found
646if 'CONFIG_TASN1' in config_host
647  tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
648                             link_args: config_host['TASN1_LIBS'].split())
649endif
650keyutils = dependency('libkeyutils', required: false,
651                      method: 'pkg-config', static: enable_static)
652
653has_gettid = cc.has_function('gettid')
654
655# Malloc tests
656
657malloc = []
658if 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; }''')
663else
664  has_malloc_trim = false
665  malloc = cc.find_library(get_option('malloc'), required: true)
666endif
667if 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
673endif
674
675#################
676# config-host.h #
677#################
678
679config_host_data.set('CONFIG_COCOA', cocoa.found())
680config_host_data.set('CONFIG_LIBUDEV', libudev.found())
681config_host_data.set('CONFIG_MPATH', mpathpersist.found())
682config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
683config_host_data.set('CONFIG_CURSES', curses.found())
684config_host_data.set('CONFIG_SDL', sdl.found())
685config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
686config_host_data.set('CONFIG_VNC', vnc.found())
687config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
688config_host_data.set('CONFIG_VNC_PNG', png.found())
689config_host_data.set('CONFIG_VNC_SASL', sasl.found())
690config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
691config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
692config_host_data.set('CONFIG_GETTID', has_gettid)
693config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
694config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
695config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
696config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
697config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
698
699ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
700arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
701strings = ['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']
704foreach 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
722endforeach
723
724########################
725# Target configuration #
726########################
727
728minikconf = find_program('scripts/minikconf.py')
729config_all = {}
730config_all_devices = {}
731config_all_disas = {}
732config_devices_mak_list = []
733config_devices_h = {}
734config_target_h = {}
735config_target_mak = {}
736
737disassemblers = {
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'],
760}
761if 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  }
767endif
768
769kconfig_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',
783]
784ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
785
786default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
787actual_target_dirs = []
788fdt_required = []
789foreach 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
817
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
835
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' }
839
840  if 'TARGET_NEED_FDT' in config_target
841    fdt_required += target
842  endif
843
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
851
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
860
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)}
881
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
889
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])
899
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}
912endforeach
913target_dirs = actual_target_dirs
914
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.
918#
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.
923
924config_all += config_all_devices
925config_all += config_host
926config_all += config_all_disas
927config_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,
932}
933
934##############
935# Submodules #
936##############
937
938capstone = not_found
939capstone_opt = get_option('capstone')
940if 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
953endif
954if capstone_opt == 'internal'
955  capstone_data = configuration_data()
956  capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
957
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  )
966
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
976
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
989
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
999
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
1010
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
1023
1024  configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1025
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',
1031
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  ]
1037
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')
1044endif
1045
1046slirp = not_found
1047slirp_opt = 'disabled'
1048if 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    ]
1108
1109    configure_file(
1110      input : 'slirp/src/libslirp-version.h.in',
1111      output : 'libslirp-version.h',
1112      configuration: slirp_conf)
1113
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
1123endif
1124
1125fdt = not_found
1126fdt_opt = get_option('fdt')
1127if 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    )
1158
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
1166endif
1167if not fdt.found() and fdt_required.length() > 0
1168  error('fdt not available but required by targets ' + ', '.join(fdt_required))
1169endif
1170
1171config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1172config_host_data.set('CONFIG_FDT', fdt.found())
1173config_host_data.set('CONFIG_SLIRP', slirp.found())
1174
1175#####################
1176# Generated sources #
1177#####################
1178
1179genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1180
1181hxtool = find_program('scripts/hxtool')
1182shaderinclude = find_program('scripts/shaderinclude.pl')
1183qapi_gen = find_program('scripts/qapi-gen.py')
1184qapi_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'
1199]
1200
1201tracetool = [
1202  python, files('scripts/tracetool.py'),
1203   '--backend=' + config_host['TRACE_BACKENDS']
1204]
1205
1206qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1207                    meson.current_source_dir(),
1208                    config_host['PKGVERSION'], meson.project_version()]
1209qemu_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)
1215genh += qemu_version
1216
1217hxdep = []
1218hx_headers = [
1219  ['qemu-options.hx', 'qemu-options.def'],
1220  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1221]
1222if have_system
1223  hx_headers += [
1224    ['hmp-commands.hx', 'hmp-commands.h'],
1225    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1226  ]
1227endif
1228foreach 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@'])
1235endforeach
1236genh += hxdep
1237
1238SPHINX_ARGS = [config_host['SPHINX_BUILD'],
1239               '-Dversion=' + meson.project_version(),
1240               '-Drelease=' + config_host['PKGVERSION']]
1241
1242if get_option('werror')
1243  SPHINX_ARGS += [ '-W' ]
1244endif
1245
1246sphinx_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 ]
1253
1254###################
1255# Collect sources #
1256###################
1257
1258authz_ss = ss.source_set()
1259blockdev_ss = ss.source_set()
1260block_ss = ss.source_set()
1261bsd_user_ss = ss.source_set()
1262chardev_ss = ss.source_set()
1263common_ss = ss.source_set()
1264crypto_ss = ss.source_set()
1265io_ss = ss.source_set()
1266linux_user_ss = ss.source_set()
1267qmp_ss = ss.source_set()
1268qom_ss = ss.source_set()
1269softmmu_ss = ss.source_set()
1270specific_fuzz_ss = ss.source_set()
1271specific_ss = ss.source_set()
1272stub_ss = ss.source_set()
1273trace_ss = ss.source_set()
1274user_ss = ss.source_set()
1275util_ss = ss.source_set()
1276
1277modules = {}
1278hw_arch = {}
1279target_arch = {}
1280target_softmmu_arch = {}
1281
1282###############
1283# Trace files #
1284###############
1285
1286# TODO: add each directory to the subdirs from its own meson.build, once
1287# we have those
1288trace_events_subdirs = [
1289  'accel/kvm',
1290  'accel/tcg',
1291  'crypto',
1292  'monitor',
1293]
1294if have_user
1295  trace_events_subdirs += [ 'linux-user' ]
1296endif
1297if have_block
1298  trace_events_subdirs += [
1299    'authz',
1300    'block',
1301    'io',
1302    'nbd',
1303    'scsi',
1304  ]
1305endif
1306if 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  ]
1362endif
1363trace_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',
1376]
1377
1378subdir('qapi')
1379subdir('qobject')
1380subdir('stubs')
1381subdir('trace')
1382subdir('util')
1383subdir('qom')
1384subdir('authz')
1385subdir('crypto')
1386subdir('ui')
1387
1388
1389if 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')
1392endif
1393
1394stub_ss = stub_ss.apply(config_all, strict: false)
1395
1396util_ss.add_all(trace_ss)
1397util_ss = util_ss.apply(config_all, strict: false)
1398libqemuutil = static_library('qemuutil',
1399                             sources: util_ss.sources() + stub_ss.sources() + genh,
1400                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1401qemuutil = declare_dependency(link_with: libqemuutil,
1402                              sources: genh + version_res)
1403
1404decodetree = generator(find_program('scripts/decodetree.py'),
1405                       output: 'decode-@BASENAME@.c.inc',
1406                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1407
1408subdir('audio')
1409subdir('io')
1410subdir('chardev')
1411subdir('fsdev')
1412subdir('libdecnumber')
1413subdir('target')
1414subdir('dump')
1415
1416block_ss.add(files(
1417  'block.c',
1418  'blockdev-nbd.c',
1419  'blockjob.c',
1420  'job.c',
1421  'qemu-io-cmds.c',
1422))
1423block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1424
1425subdir('nbd')
1426subdir('scsi')
1427subdir('block')
1428
1429blockdev_ss.add(files(
1430  'blockdev.c',
1431  'iothread.c',
1432  'job-qmp.c',
1433))
1434
1435# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1436# os-win32.c does not
1437blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1438softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1439softmmu_ss.add_all(blockdev_ss)
1440
1441common_ss.add(files('cpus-common.c'))
1442
1443subdir('softmmu')
1444
1445common_ss.add(capstone)
1446specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1447specific_ss.add(files('exec-vary.c'))
1448specific_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',
1456))
1457specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1458
1459subdir('backends')
1460subdir('disas')
1461subdir('migration')
1462subdir('monitor')
1463subdir('net')
1464subdir('replay')
1465subdir('hw')
1466subdir('accel')
1467subdir('plugins')
1468subdir('bsd-user')
1469subdir('linux-user')
1470
1471bsd_user_ss.add(files('gdbstub.c'))
1472specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1473
1474linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1475specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1476
1477# needed for fuzzing binaries
1478subdir('tests/qtest/libqos')
1479subdir('tests/qtest/fuzz')
1480
1481########################
1482# Library dependencies #
1483########################
1484
1485block_mods = []
1486softmmu_mods = []
1487foreach 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
1506endforeach
1507
1508nm = find_program('nm')
1509undefsym = find_program('scripts/undefsym.py')
1510block_syms = custom_target('block.syms', output: 'block.syms',
1511                             input: [libqemuutil, block_mods],
1512                             capture: true,
1513                             command: [undefsym, nm, '@INPUT@'])
1514qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1515                             input: [libqemuutil, softmmu_mods],
1516                             capture: true,
1517                             command: [undefsym, nm, '@INPUT@'])
1518
1519qom_ss = qom_ss.apply(config_host, strict: false)
1520libqom = static_library('qom', qom_ss.sources() + genh,
1521                        dependencies: [qom_ss.dependencies()],
1522                        name_suffix: 'fa')
1523
1524qom = declare_dependency(link_whole: libqom)
1525
1526authz_ss = authz_ss.apply(config_host, strict: false)
1527libauthz = static_library('authz', authz_ss.sources() + genh,
1528                          dependencies: [authz_ss.dependencies()],
1529                          name_suffix: 'fa',
1530                          build_by_default: false)
1531
1532authz = declare_dependency(link_whole: libauthz,
1533                           dependencies: qom)
1534
1535crypto_ss = crypto_ss.apply(config_host, strict: false)
1536libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1537                           dependencies: [crypto_ss.dependencies()],
1538                           name_suffix: 'fa',
1539                           build_by_default: false)
1540
1541crypto = declare_dependency(link_whole: libcrypto,
1542                            dependencies: [authz, qom])
1543
1544io_ss = io_ss.apply(config_host, strict: false)
1545libio = 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)
1550
1551io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1552
1553libmigration = static_library('migration', sources: migration_files + genh,
1554                              name_suffix: 'fa',
1555                              build_by_default: false)
1556migration = declare_dependency(link_with: libmigration,
1557                               dependencies: [zlib, qom, io])
1558softmmu_ss.add(migration)
1559
1560block_ss = block_ss.apply(config_host, strict: false)
1561libblock = 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)
1566
1567block = declare_dependency(link_whole: [libblock],
1568                           link_args: '@block.syms',
1569                           dependencies: [crypto, io])
1570
1571qmp_ss = qmp_ss.apply(config_host, strict: false)
1572libqmp = static_library('qmp', qmp_ss.sources() + genh,
1573                        dependencies: qmp_ss.dependencies(),
1574                        name_suffix: 'fa',
1575                        build_by_default: false)
1576
1577qmp = declare_dependency(link_whole: [libqmp])
1578
1579libchardev = static_library('chardev', chardev_ss.sources() + genh,
1580                            name_suffix: 'fa',
1581                            build_by_default: false)
1582
1583chardev = declare_dependency(link_whole: libchardev)
1584
1585libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1586                           name_suffix: 'fa',
1587                           build_by_default: false)
1588hwcore = declare_dependency(link_whole: libhwcore)
1589common_ss.add(hwcore)
1590
1591###########
1592# Targets #
1593###########
1594
1595foreach 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'])
1601endforeach
1602
1603softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
1604common_ss.add(qom, qemuutil)
1605
1606common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1607common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1608
1609common_all = common_ss.apply(config_all, strict: false)
1610common_all = static_library('common',
1611                            build_by_default: false,
1612                            sources: common_all.sources() + genh,
1613                            dependencies: common_all.dependencies(),
1614                            name_suffix: 'fa')
1615
1616feature_to_c = find_program('scripts/feature_to_c.sh')
1617
1618emulators = {}
1619foreach 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
1629
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()
1641
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()
1646
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
1673
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
1682
1683  t = target_arch[arch].apply(config_target, strict: false)
1684  arch_srcs += t.sources()
1685  arch_deps += t.dependencies()
1686
1687  target_common = common_ss.apply(config_target, strict: false)
1688  objects = common_all.extract_objects(target_common.sources())
1689  deps = target_common.dependencies()
1690
1691  target_specific = specific_ss.apply(config_target, strict: false)
1692  arch_srcs += target_specific.sources()
1693  arch_deps += target_specific.dependencies()
1694
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')
1703
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    }
1748
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
1773endforeach
1774
1775# Other build targets
1776
1777if 'CONFIG_PLUGIN' in config_host
1778  install_headers('include/qemu/qemu-plugin.h')
1779endif
1780
1781if 'CONFIG_GUEST_AGENT' in config_host
1782  subdir('qga')
1783endif
1784
1785# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1786# when we don't build tools or system
1787if 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)
1791endif
1792
1793if 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)
1800
1801  subdir('storage-daemon')
1802  subdir('contrib/rdmacm-mux')
1803  subdir('contrib/elf2dmp')
1804
1805  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1806             dependencies: qemuutil,
1807             install: true)
1808
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
1816
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'))
1822
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
1828
1829  if 'CONFIG_IVSHMEM' in config_host
1830    subdir('contrib/ivshmem-client')
1831    subdir('contrib/ivshmem-server')
1832  endif
1833endif
1834
1835subdir('scripts')
1836subdir('tools')
1837subdir('pc-bios')
1838subdir('tests')
1839subdir('docs')
1840if 'CONFIG_GTK' in config_host
1841  subdir('po')
1842endif
1843
1844if 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
1860
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)
1867endif
1868
1869#########################
1870# Configuration summary #
1871#########################
1872
1873summary_info = {}
1874summary_info += {'Install prefix':    config_host['prefix']}
1875summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1876summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1877summary_info += {'binary directory':  config_host['bindir']}
1878summary_info += {'library directory': config_host['libdir']}
1879summary_info += {'module directory':  config_host['qemu_moddir']}
1880summary_info += {'libexec directory': config_host['libexecdir']}
1881summary_info += {'include directory': config_host['includedir']}
1882summary_info += {'config directory':  config_host['sysconfdir']}
1883if targetos != 'windows'
1884  summary_info += {'local state directory': config_host['qemu_localstatedir']}
1885  summary_info += {'Manual directory':      get_option('mandir')}
1886else
1887  summary_info += {'local state directory': 'queried at runtime'}
1888endif
1889summary_info += {'Doc directory':     get_option('docdir')}
1890summary_info += {'Build directory':   meson.current_build_dir()}
1891summary_info += {'Source path':       meson.current_source_dir()}
1892summary_info += {'GIT binary':        config_host['GIT']}
1893summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1894summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1895summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1896if link_language == 'cpp'
1897  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1898else
1899  summary_info += {'C++ compiler':      false}
1900endif
1901if targetos == 'darwin'
1902  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1903endif
1904summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1905summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
1906                                               + ['-O' + get_option('optimization')]
1907                                               + (get_option('debug') ? ['-g'] : []))}
1908if link_language == 'cpp'
1909  summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
1910                                               + ['-O' + get_option('optimization')]
1911                                               + (get_option('debug') ? ['-g'] : []))}
1912endif
1913link_args = get_option(link_language + '_link_args')
1914if link_args.length() > 0
1915  summary_info += {'LDFLAGS':         ' '.join(link_args)}
1916endif
1917summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1918summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1919summary_info += {'make':              config_host['MAKE']}
1920summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1921summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1922summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1923# TODO: add back version
1924summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
1925if slirp_opt != 'disabled'
1926  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1927endif
1928summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1929if config_host.has_key('CONFIG_MODULES')
1930  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1931endif
1932summary_info += {'host CPU':          cpu}
1933summary_info += {'host endianness':   build_machine.endian()}
1934summary_info += {'target list':       ' '.join(target_dirs)}
1935summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1936summary_info += {'sparse enabled':    sparse.found()}
1937summary_info += {'strip binaries':    get_option('strip')}
1938summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1939summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
1940if targetos == 'darwin'
1941  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1942endif
1943# TODO: add back version
1944summary_info += {'SDL support':       sdl.found()}
1945summary_info += {'SDL image support': sdl_image.found()}
1946# TODO: add back version
1947summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1948summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1949summary_info += {'pixman':            pixman.found()}
1950# TODO: add back version
1951summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1952summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1953summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1954# TODO: add back version
1955summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1956if 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')}
1959endif
1960# TODO: add back version
1961summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1962if config_host.has_key('CONFIG_NETTLE')
1963   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1964endif
1965summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1966summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1967summary_info += {'iconv support':     iconv.found()}
1968summary_info += {'curses support':    curses.found()}
1969# TODO: add back version
1970summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1971summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1972summary_info += {'mingw32 support':   targetos == 'windows'}
1973summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1974summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1975summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1976summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1977summary_info += {'Multipath support': mpathpersist.found()}
1978summary_info += {'VNC support':       vnc.found()}
1979if 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()}
1983endif
1984summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1985if config_host.has_key('CONFIG_XEN_BACKEND')
1986  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1987endif
1988summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1989summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1990summary_info += {'PIE':               get_option('b_pie')}
1991summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1992summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1993summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1994summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1995summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1996summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1997summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
1998summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
1999summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2000summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2001summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2002if 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')}
2005endif
2006summary_info += {'malloc trim support': has_malloc_trim}
2007summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2008summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2009summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2010summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2011summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2012summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2013summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2014summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2015summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2016summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2017summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2018summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2019summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2020summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2021summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2022summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2023summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2024summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2025if config_host['TRACE_BACKENDS'].split().contains('simple')
2026  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2027endif
2028# TODO: add back protocol and server version
2029summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2030summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
2031summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2032summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2033summary_info += {'U2F support':       u2f.found()}
2034summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2035summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2036summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2037summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2038summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
2039summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
2040summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2041if 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')}
2048endif
2049summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
2050summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2051summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2052summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2053summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2054summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2055summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
2056summary_info += {'gcov':              get_option('b_coverage')}
2057summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2058summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2059summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2060summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2061summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
2062summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
2063summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
2064summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
2065summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
2066summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2067summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2068summary_info += {'memory allocator':  get_option('malloc')}
2069summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2070summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2071summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2072summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2073summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2074summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2075summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2076summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2077summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2078summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2079summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2080summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2081summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2082summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2083summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2084summary_info += {'libudev':           libudev.found()}
2085summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2086summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2087summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2088if config_host.has_key('HAVE_GDB_BIN')
2089  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2090endif
2091summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2092summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2093summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2094summary(summary_info, bool_yn: true)
2095
2096if 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.')
2107endif
2108
2109if 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.')
2120endif
2121