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