xref: /qemu/meson.build (revision f917eed3)
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/i386/kvm',
1501  'target/mips',
1502  'target/ppc',
1503  'target/riscv',
1504  'target/s390x',
1505  'target/sparc',
1506  'util',
1507]
1508
1509vhost_user = not_found
1510if 'CONFIG_VHOST_USER' in config_host
1511  libvhost_user = subproject('libvhost-user')
1512  vhost_user = libvhost_user.get_variable('vhost_user_dep')
1513endif
1514
1515subdir('qapi')
1516subdir('qobject')
1517subdir('stubs')
1518subdir('trace')
1519subdir('util')
1520subdir('qom')
1521subdir('authz')
1522subdir('crypto')
1523subdir('ui')
1524
1525
1526if enable_modules
1527  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1528  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1529endif
1530
1531stub_ss = stub_ss.apply(config_all, strict: false)
1532
1533util_ss.add_all(trace_ss)
1534util_ss = util_ss.apply(config_all, strict: false)
1535libqemuutil = static_library('qemuutil',
1536                             sources: util_ss.sources() + stub_ss.sources() + genh,
1537                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1538qemuutil = declare_dependency(link_with: libqemuutil,
1539                              sources: genh + version_res)
1540
1541decodetree = generator(find_program('scripts/decodetree.py'),
1542                       output: 'decode-@BASENAME@.c.inc',
1543                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1544
1545subdir('audio')
1546subdir('io')
1547subdir('chardev')
1548subdir('fsdev')
1549subdir('libdecnumber')
1550subdir('target')
1551subdir('dump')
1552
1553block_ss.add(files(
1554  'block.c',
1555  'blockjob.c',
1556  'job.c',
1557  'qemu-io-cmds.c',
1558))
1559block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1560
1561subdir('nbd')
1562subdir('scsi')
1563subdir('block')
1564
1565blockdev_ss.add(files(
1566  'blockdev.c',
1567  'blockdev-nbd.c',
1568  'iothread.c',
1569  'job-qmp.c',
1570))
1571
1572# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1573# os-win32.c does not
1574blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1575softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1576
1577common_ss.add(files('cpus-common.c'))
1578
1579subdir('softmmu')
1580
1581common_ss.add(capstone)
1582specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1583specific_ss.add(files('exec-vary.c'))
1584specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1585  'fpu/softfloat.c',
1586  'tcg/optimize.c',
1587  'tcg/tcg-common.c',
1588  'tcg/tcg-op-gvec.c',
1589  'tcg/tcg-op-vec.c',
1590  'tcg/tcg-op.c',
1591  'tcg/tcg.c',
1592))
1593specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1594
1595subdir('backends')
1596subdir('disas')
1597subdir('migration')
1598subdir('monitor')
1599subdir('net')
1600subdir('replay')
1601subdir('hw')
1602subdir('accel')
1603subdir('plugins')
1604subdir('bsd-user')
1605subdir('linux-user')
1606
1607bsd_user_ss.add(files('gdbstub.c'))
1608specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1609
1610linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1611specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1612
1613# needed for fuzzing binaries
1614subdir('tests/qtest/libqos')
1615subdir('tests/qtest/fuzz')
1616
1617########################
1618# Library dependencies #
1619########################
1620
1621block_mods = []
1622softmmu_mods = []
1623foreach d, list : modules
1624  foreach m, module_ss : list
1625    if enable_modules and targetos != 'windows'
1626      module_ss = module_ss.apply(config_all, strict: false)
1627      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1628                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1629      if d == 'block'
1630        block_mods += sl
1631      else
1632        softmmu_mods += sl
1633      endif
1634    else
1635      if d == 'block'
1636        block_ss.add_all(module_ss)
1637      else
1638        softmmu_ss.add_all(module_ss)
1639      endif
1640    endif
1641  endforeach
1642endforeach
1643
1644nm = find_program('nm')
1645undefsym = find_program('scripts/undefsym.py')
1646block_syms = custom_target('block.syms', output: 'block.syms',
1647                             input: [libqemuutil, block_mods],
1648                             capture: true,
1649                             command: [undefsym, nm, '@INPUT@'])
1650qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1651                             input: [libqemuutil, softmmu_mods],
1652                             capture: true,
1653                             command: [undefsym, nm, '@INPUT@'])
1654
1655qom_ss = qom_ss.apply(config_host, strict: false)
1656libqom = static_library('qom', qom_ss.sources() + genh,
1657                        dependencies: [qom_ss.dependencies()],
1658                        name_suffix: 'fa')
1659
1660qom = declare_dependency(link_whole: libqom)
1661
1662authz_ss = authz_ss.apply(config_host, strict: false)
1663libauthz = static_library('authz', authz_ss.sources() + genh,
1664                          dependencies: [authz_ss.dependencies()],
1665                          name_suffix: 'fa',
1666                          build_by_default: false)
1667
1668authz = declare_dependency(link_whole: libauthz,
1669                           dependencies: qom)
1670
1671crypto_ss = crypto_ss.apply(config_host, strict: false)
1672libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1673                           dependencies: [crypto_ss.dependencies()],
1674                           name_suffix: 'fa',
1675                           build_by_default: false)
1676
1677crypto = declare_dependency(link_whole: libcrypto,
1678                            dependencies: [authz, qom])
1679
1680io_ss = io_ss.apply(config_host, strict: false)
1681libio = static_library('io', io_ss.sources() + genh,
1682                       dependencies: [io_ss.dependencies()],
1683                       link_with: libqemuutil,
1684                       name_suffix: 'fa',
1685                       build_by_default: false)
1686
1687io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1688
1689libmigration = static_library('migration', sources: migration_files + genh,
1690                              name_suffix: 'fa',
1691                              build_by_default: false)
1692migration = declare_dependency(link_with: libmigration,
1693                               dependencies: [zlib, qom, io])
1694softmmu_ss.add(migration)
1695
1696block_ss = block_ss.apply(config_host, strict: false)
1697libblock = static_library('block', block_ss.sources() + genh,
1698                          dependencies: block_ss.dependencies(),
1699                          link_depends: block_syms,
1700                          name_suffix: 'fa',
1701                          build_by_default: false)
1702
1703block = declare_dependency(link_whole: [libblock],
1704                           link_args: '@block.syms',
1705                           dependencies: [crypto, io])
1706
1707blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1708libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1709                             dependencies: blockdev_ss.dependencies(),
1710                             name_suffix: 'fa',
1711                             build_by_default: false)
1712
1713blockdev = declare_dependency(link_whole: [libblockdev],
1714                              dependencies: [block])
1715
1716qmp_ss = qmp_ss.apply(config_host, strict: false)
1717libqmp = static_library('qmp', qmp_ss.sources() + genh,
1718                        dependencies: qmp_ss.dependencies(),
1719                        name_suffix: 'fa',
1720                        build_by_default: false)
1721
1722qmp = declare_dependency(link_whole: [libqmp])
1723
1724libchardev = static_library('chardev', chardev_ss.sources() + genh,
1725                            name_suffix: 'fa',
1726                            build_by_default: false)
1727
1728chardev = declare_dependency(link_whole: libchardev)
1729
1730libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1731                           name_suffix: 'fa',
1732                           build_by_default: false)
1733hwcore = declare_dependency(link_whole: libhwcore)
1734common_ss.add(hwcore)
1735
1736###########
1737# Targets #
1738###########
1739
1740foreach m : block_mods + softmmu_mods
1741  shared_module(m.name(),
1742                name_prefix: '',
1743                link_whole: m,
1744                install: true,
1745                install_dir: qemu_moddir)
1746endforeach
1747
1748softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1749common_ss.add(qom, qemuutil)
1750
1751common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1752common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1753
1754common_all = common_ss.apply(config_all, strict: false)
1755common_all = static_library('common',
1756                            build_by_default: false,
1757                            sources: common_all.sources() + genh,
1758                            dependencies: common_all.dependencies(),
1759                            name_suffix: 'fa')
1760
1761feature_to_c = find_program('scripts/feature_to_c.sh')
1762
1763emulators = {}
1764foreach target : target_dirs
1765  config_target = config_target_mak[target]
1766  target_name = config_target['TARGET_NAME']
1767  arch = config_target['TARGET_BASE_ARCH']
1768  arch_srcs = [config_target_h[target]]
1769  arch_deps = []
1770  c_args = ['-DNEED_CPU_H',
1771            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1772            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1773  link_args = emulator_link_args
1774
1775  config_target += config_host
1776  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1777  if targetos == 'linux'
1778    target_inc += include_directories('linux-headers', is_system: true)
1779  endif
1780  if target.endswith('-softmmu')
1781    qemu_target_name = 'qemu-system-' + target_name
1782    target_type='system'
1783    t = target_softmmu_arch[arch].apply(config_target, strict: false)
1784    arch_srcs += t.sources()
1785    arch_deps += t.dependencies()
1786
1787    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1788    hw = hw_arch[hw_dir].apply(config_target, strict: false)
1789    arch_srcs += hw.sources()
1790    arch_deps += hw.dependencies()
1791
1792    arch_srcs += config_devices_h[target]
1793    link_args += ['@block.syms', '@qemu.syms']
1794  else
1795    abi = config_target['TARGET_ABI_DIR']
1796    target_type='user'
1797    qemu_target_name = 'qemu-' + target_name
1798    if 'CONFIG_LINUX_USER' in config_target
1799      base_dir = 'linux-user'
1800      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1801    else
1802      base_dir = 'bsd-user'
1803    endif
1804    target_inc += include_directories(
1805      base_dir,
1806      base_dir / abi,
1807    )
1808    if 'CONFIG_LINUX_USER' in config_target
1809      dir = base_dir / abi
1810      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1811      if config_target.has_key('TARGET_SYSTBL_ABI')
1812        arch_srcs += \
1813          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1814                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
1815      endif
1816    endif
1817  endif
1818
1819  if 'TARGET_XML_FILES' in config_target
1820    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1821                                output: target + '-gdbstub-xml.c',
1822                                input: files(config_target['TARGET_XML_FILES'].split()),
1823                                command: [feature_to_c, '@INPUT@'],
1824                                capture: true)
1825    arch_srcs += gdbstub_xml
1826  endif
1827
1828  t = target_arch[arch].apply(config_target, strict: false)
1829  arch_srcs += t.sources()
1830  arch_deps += t.dependencies()
1831
1832  target_common = common_ss.apply(config_target, strict: false)
1833  objects = common_all.extract_objects(target_common.sources())
1834  deps = target_common.dependencies()
1835
1836  target_specific = specific_ss.apply(config_target, strict: false)
1837  arch_srcs += target_specific.sources()
1838  arch_deps += target_specific.dependencies()
1839
1840  lib = static_library('qemu-' + target,
1841                 sources: arch_srcs + genh,
1842                 dependencies: arch_deps,
1843                 objects: objects,
1844                 include_directories: target_inc,
1845                 c_args: c_args,
1846                 build_by_default: false,
1847                 name_suffix: 'fa')
1848
1849  if target.endswith('-softmmu')
1850    execs = [{
1851      'name': 'qemu-system-' + target_name,
1852      'gui': false,
1853      'sources': files('softmmu/main.c'),
1854      'dependencies': []
1855    }]
1856    if targetos == 'windows' and (sdl.found() or gtk.found())
1857      execs += [{
1858        'name': 'qemu-system-' + target_name + 'w',
1859        'gui': true,
1860        'sources': files('softmmu/main.c'),
1861        'dependencies': []
1862      }]
1863    endif
1864    if config_host.has_key('CONFIG_FUZZ')
1865      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1866      execs += [{
1867        'name': 'qemu-fuzz-' + target_name,
1868        'gui': false,
1869        'sources': specific_fuzz.sources(),
1870        'dependencies': specific_fuzz.dependencies(),
1871      }]
1872    endif
1873  else
1874    execs = [{
1875      'name': 'qemu-' + target_name,
1876      'gui': false,
1877      'sources': [],
1878      'dependencies': []
1879    }]
1880  endif
1881  foreach exe: execs
1882    emulators += {exe['name']:
1883         executable(exe['name'], exe['sources'],
1884               install: true,
1885               c_args: c_args,
1886               dependencies: arch_deps + deps + exe['dependencies'],
1887               objects: lib.extract_all_objects(recursive: true),
1888               link_language: link_language,
1889               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1890               link_args: link_args,
1891               gui_app: exe['gui'])
1892    }
1893
1894    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1895      foreach stp: [
1896        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1897        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1898        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1899        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1900      ]
1901        custom_target(exe['name'] + stp['ext'],
1902                      input: trace_events_all,
1903                      output: exe['name'] + stp['ext'],
1904                      capture: true,
1905                      install: stp['install'],
1906                      install_dir: get_option('datadir') / 'systemtap/tapset',
1907                      command: [
1908                        tracetool, '--group=all', '--format=' + stp['fmt'],
1909                        '--binary=' + stp['bin'],
1910                        '--target-name=' + target_name,
1911                        '--target-type=' + target_type,
1912                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1913                        '@INPUT@',
1914                      ])
1915      endforeach
1916    endif
1917  endforeach
1918endforeach
1919
1920# Other build targets
1921
1922if 'CONFIG_PLUGIN' in config_host
1923  install_headers('include/qemu/qemu-plugin.h')
1924endif
1925
1926if 'CONFIG_GUEST_AGENT' in config_host
1927  subdir('qga')
1928endif
1929
1930# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1931# when we don't build tools or system
1932if xkbcommon.found()
1933  # used for the update-keymaps target, so include rules even if !have_tools
1934  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1935                           dependencies: [qemuutil, xkbcommon], install: have_tools)
1936endif
1937
1938if have_tools
1939  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1940             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1941  qemu_io = executable('qemu-io', files('qemu-io.c'),
1942             dependencies: [block, qemuutil], install: true)
1943  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1944               dependencies: [blockdev, qemuutil], install: true)
1945
1946  subdir('storage-daemon')
1947  subdir('contrib/rdmacm-mux')
1948  subdir('contrib/elf2dmp')
1949
1950  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1951             dependencies: qemuutil,
1952             install: true)
1953
1954  if 'CONFIG_VHOST_USER' in config_host
1955    subdir('contrib/vhost-user-blk')
1956    subdir('contrib/vhost-user-gpu')
1957    subdir('contrib/vhost-user-input')
1958    subdir('contrib/vhost-user-scsi')
1959  endif
1960
1961  if targetos == 'linux'
1962    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1963               dependencies: [qemuutil, libcap_ng],
1964               install: true,
1965               install_dir: get_option('libexecdir'))
1966
1967    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1968               dependencies: [authz, crypto, io, qom, qemuutil,
1969                              libcap_ng, mpathpersist],
1970               install: true)
1971  endif
1972
1973  if 'CONFIG_IVSHMEM' in config_host
1974    subdir('contrib/ivshmem-client')
1975    subdir('contrib/ivshmem-server')
1976  endif
1977endif
1978
1979subdir('scripts')
1980subdir('tools')
1981subdir('pc-bios')
1982subdir('docs')
1983subdir('tests')
1984if 'CONFIG_GTK' in config_host
1985  subdir('po')
1986endif
1987
1988if host_machine.system() == 'windows'
1989  nsis_cmd = [
1990    find_program('scripts/nsis.py'),
1991    '@OUTPUT@',
1992    get_option('prefix'),
1993    meson.current_source_dir(),
1994    host_machine.cpu(),
1995    '--',
1996    '-DDISPLAYVERSION=' + meson.project_version(),
1997  ]
1998  if build_docs
1999    nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2000  endif
2001  if 'CONFIG_GTK' in config_host
2002    nsis_cmd += '-DCONFIG_GTK=y'
2003  endif
2004
2005  nsis = custom_target('nsis',
2006                       output: 'qemu-setup-' + meson.project_version() + '.exe',
2007                       input: files('qemu.nsi'),
2008                       build_always_stale: true,
2009                       command: nsis_cmd + ['@INPUT@'])
2010  alias_target('installer', nsis)
2011endif
2012
2013#########################
2014# Configuration summary #
2015#########################
2016
2017summary_info = {}
2018summary_info += {'Install prefix':    get_option('prefix')}
2019summary_info += {'BIOS directory':    qemu_datadir}
2020summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2021summary_info += {'binary directory':  get_option('bindir')}
2022summary_info += {'library directory': get_option('libdir')}
2023summary_info += {'module directory':  qemu_moddir}
2024summary_info += {'libexec directory': get_option('libexecdir')}
2025summary_info += {'include directory': get_option('includedir')}
2026summary_info += {'config directory':  get_option('sysconfdir')}
2027if targetos != 'windows'
2028  summary_info += {'local state directory': get_option('localstatedir')}
2029  summary_info += {'Manual directory':      get_option('mandir')}
2030else
2031  summary_info += {'local state directory': 'queried at runtime'}
2032endif
2033summary_info += {'Doc directory':     get_option('docdir')}
2034summary_info += {'Build directory':   meson.current_build_dir()}
2035summary_info += {'Source path':       meson.current_source_dir()}
2036summary_info += {'GIT binary':        config_host['GIT']}
2037summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2038summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2039summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2040if link_language == 'cpp'
2041  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2042else
2043  summary_info += {'C++ compiler':      false}
2044endif
2045if targetos == 'darwin'
2046  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2047endif
2048summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2049summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2050                                               + ['-O' + get_option('optimization')]
2051                                               + (get_option('debug') ? ['-g'] : []))}
2052if link_language == 'cpp'
2053  summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2054                                               + ['-O' + get_option('optimization')]
2055                                               + (get_option('debug') ? ['-g'] : []))}
2056endif
2057link_args = get_option(link_language + '_link_args')
2058if link_args.length() > 0
2059  summary_info += {'LDFLAGS':         ' '.join(link_args)}
2060endif
2061summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2062summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2063summary_info += {'make':              config_host['MAKE']}
2064summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2065summary_info += {'sphinx-build':      sphinx_build.found()}
2066summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2067# TODO: add back version
2068summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2069if slirp_opt != 'disabled'
2070  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2071endif
2072summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2073if config_host.has_key('CONFIG_MODULES')
2074  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2075endif
2076summary_info += {'host CPU':          cpu}
2077summary_info += {'host endianness':   build_machine.endian()}
2078summary_info += {'target list':       ' '.join(target_dirs)}
2079summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2080summary_info += {'sparse enabled':    sparse.found()}
2081summary_info += {'strip binaries':    get_option('strip')}
2082summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2083summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2084if targetos == 'darwin'
2085  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2086endif
2087# TODO: add back version
2088summary_info += {'SDL support':       sdl.found()}
2089summary_info += {'SDL image support': sdl_image.found()}
2090# TODO: add back version
2091summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
2092summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
2093summary_info += {'pixman':            pixman.found()}
2094# TODO: add back version
2095summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2096summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2097summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2098# TODO: add back version
2099summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2100if config_host.has_key('CONFIG_GCRYPT')
2101   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2102   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2103endif
2104# TODO: add back version
2105summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2106if config_host.has_key('CONFIG_NETTLE')
2107   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2108endif
2109summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2110summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2111summary_info += {'iconv support':     iconv.found()}
2112summary_info += {'curses support':    curses.found()}
2113# TODO: add back version
2114summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2115summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
2116summary_info += {'mingw32 support':   targetos == 'windows'}
2117summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2118summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2119summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2120summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
2121summary_info += {'build virtiofs daemon': have_virtiofsd}
2122summary_info += {'Multipath support': mpathpersist.found()}
2123summary_info += {'VNC support':       vnc.found()}
2124if vnc.found()
2125  summary_info += {'VNC SASL support':  sasl.found()}
2126  summary_info += {'VNC JPEG support':  jpeg.found()}
2127  summary_info += {'VNC PNG support':   png.found()}
2128endif
2129summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2130if config_host.has_key('CONFIG_XEN_BACKEND')
2131  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2132endif
2133summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
2134summary_info += {'Documentation':     build_docs}
2135summary_info += {'PIE':               get_option('b_pie')}
2136summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2137summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2138summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2139summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2140summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2141summary_info += {'Install blobs':     get_option('install_blobs')}
2142summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2143summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2144summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2145summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2146summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2147if config_all.has_key('CONFIG_TCG')
2148  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2149  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
2150endif
2151summary_info += {'malloc trim support': has_malloc_trim}
2152summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2153summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2154summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2155summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2156summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2157summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2158summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2159summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2160summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2161summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2162summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2163summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2164summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2165summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2166summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2167summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2168summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2169summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2170summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2171summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2172if config_host['TRACE_BACKENDS'].split().contains('simple')
2173  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2174endif
2175# TODO: add back protocol and server version
2176summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2177summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
2178summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2179summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2180summary_info += {'U2F support':       u2f.found()}
2181summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2182summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2183summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2184summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2185summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
2186summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
2187summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2188if targetos == 'windows'
2189  if 'WIN_SDK' in config_host
2190    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
2191  endif
2192  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2193  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2194  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
2195endif
2196summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
2197summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2198summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2199summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2200summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2201summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2202summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
2203summary_info += {'gcov':              get_option('b_coverage')}
2204summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2205summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2206summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2207summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2208summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
2209summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
2210summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
2211summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
2212summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
2213summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2214summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2215summary_info += {'memory allocator':  get_option('malloc')}
2216summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2217summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2218summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2219summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2220summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2221summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2222summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2223summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2224summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2225summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2226summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2227summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2228summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2229summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2230summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2231summary_info += {'libudev':           libudev.found()}
2232summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2233summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2234summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2235if config_host.has_key('HAVE_GDB_BIN')
2236  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2237endif
2238summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2239summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2240summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2241summary_info += {'FUSE exports':      fuse.found()}
2242summary_info += {'FUSE lseek':        fuse_lseek.found()}
2243summary(summary_info, bool_yn: true)
2244
2245if not supported_cpus.contains(cpu)
2246  message()
2247  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2248  message()
2249  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2250  message('The QEMU project intends to remove support for this host CPU in')
2251  message('a future release if nobody volunteers to maintain it and to')
2252  message('provide a build host for our continuous integration setup.')
2253  message('configure has succeeded and you can continue to build, but')
2254  message('if you care about QEMU on this platform you should contact')
2255  message('us upstream at qemu-devel@nongnu.org.')
2256endif
2257
2258if not supported_oses.contains(targetos)
2259  message()
2260  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2261  message()
2262  message('Host OS ' + targetos + 'support is not currently maintained.')
2263  message('The QEMU project intends to remove support for this host OS in')
2264  message('a future release if nobody volunteers to maintain it and to')
2265  message('provide a build host for our continuous integration setup.')
2266  message('configure has succeeded and you can continue to build, but')
2267  message('if you care about QEMU on this platform you should contact')
2268  message('us upstream at qemu-devel@nongnu.org.')
2269endif
2270