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