xref: /openbmc/qemu/meson.build (revision 7cc25f6c)
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_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
840
841ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
842arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
843strings = ['HOST_DSOSUF', 'CONFIG_IASL']
844foreach k, v: config_host
845  if ignored.contains(k)
846    # do nothing
847  elif arrays.contains(k)
848    if v != ''
849      v = '"' + '", "'.join(v.split()) + '", '
850    endif
851    config_host_data.set(k, v)
852  elif k == 'ARCH'
853    config_host_data.set('HOST_' + v.to_upper(), 1)
854  elif strings.contains(k)
855    if not k.startswith('CONFIG_')
856      k = 'CONFIG_' + k.to_upper()
857    endif
858    config_host_data.set_quoted(k, v)
859  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
860    config_host_data.set(k, v == 'y' ? 1 : v)
861  endif
862endforeach
863
864########################
865# Target configuration #
866########################
867
868minikconf = find_program('scripts/minikconf.py')
869config_all = {}
870config_all_devices = {}
871config_all_disas = {}
872config_devices_mak_list = []
873config_devices_h = {}
874config_target_h = {}
875config_target_mak = {}
876
877disassemblers = {
878  'alpha' : ['CONFIG_ALPHA_DIS'],
879  'arm' : ['CONFIG_ARM_DIS'],
880  'avr' : ['CONFIG_AVR_DIS'],
881  'cris' : ['CONFIG_CRIS_DIS'],
882  'hppa' : ['CONFIG_HPPA_DIS'],
883  'i386' : ['CONFIG_I386_DIS'],
884  'x86_64' : ['CONFIG_I386_DIS'],
885  'x32' : ['CONFIG_I386_DIS'],
886  'lm32' : ['CONFIG_LM32_DIS'],
887  'm68k' : ['CONFIG_M68K_DIS'],
888  'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
889  'mips' : ['CONFIG_MIPS_DIS'],
890  'moxie' : ['CONFIG_MOXIE_DIS'],
891  'nios2' : ['CONFIG_NIOS2_DIS'],
892  'or1k' : ['CONFIG_OPENRISC_DIS'],
893  'ppc' : ['CONFIG_PPC_DIS'],
894  'riscv' : ['CONFIG_RISCV_DIS'],
895  'rx' : ['CONFIG_RX_DIS'],
896  's390' : ['CONFIG_S390_DIS'],
897  'sh4' : ['CONFIG_SH4_DIS'],
898  'sparc' : ['CONFIG_SPARC_DIS'],
899  'xtensa' : ['CONFIG_XTENSA_DIS'],
900}
901if link_language == 'cpp'
902  disassemblers += {
903    'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
904    'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
905    'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
906  }
907endif
908
909kconfig_external_symbols = [
910  'CONFIG_KVM',
911  'CONFIG_XEN',
912  'CONFIG_TPM',
913  'CONFIG_SPICE',
914  'CONFIG_IVSHMEM',
915  'CONFIG_OPENGL',
916  'CONFIG_X11',
917  'CONFIG_VHOST_USER',
918  'CONFIG_VHOST_VDPA',
919  'CONFIG_VHOST_KERNEL',
920  'CONFIG_VIRTFS',
921  'CONFIG_LINUX',
922  'CONFIG_PVRDMA',
923]
924ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
925
926default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
927actual_target_dirs = []
928fdt_required = []
929foreach target : target_dirs
930  config_target = { 'TARGET_NAME': target.split('-')[0] }
931  if target.endswith('linux-user')
932    if targetos != 'linux'
933      if default_targets
934        continue
935      endif
936      error('Target @0@ is only available on a Linux host'.format(target))
937    endif
938    config_target += { 'CONFIG_LINUX_USER': 'y' }
939  elif target.endswith('bsd-user')
940    if 'CONFIG_BSD' not in config_host
941      if default_targets
942        continue
943      endif
944      error('Target @0@ is only available on a BSD host'.format(target))
945    endif
946    config_target += { 'CONFIG_BSD_USER': 'y' }
947  elif target.endswith('softmmu')
948    config_target += { 'CONFIG_SOFTMMU': 'y' }
949  endif
950  if target.endswith('-user')
951    config_target += {
952      'CONFIG_USER_ONLY': 'y',
953      'CONFIG_QEMU_INTERP_PREFIX':
954        config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
955    }
956  endif
957
958  have_accel = false
959  foreach sym: accelerators
960    if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
961      config_target += { sym: 'y' }
962      config_all += { sym: 'y' }
963      if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
964        config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
965      endif
966      have_accel = true
967    endif
968  endforeach
969  if not have_accel
970    if default_targets
971      continue
972    endif
973    error('No accelerator available for target @0@'.format(target))
974  endif
975
976  actual_target_dirs += target
977  config_target += keyval.load('default-configs/targets' / target + '.mak')
978  config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
979
980  if 'TARGET_NEED_FDT' in config_target
981    fdt_required += target
982  endif
983
984  # Add default keys
985  if 'TARGET_BASE_ARCH' not in config_target
986    config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
987  endif
988  if 'TARGET_ABI_DIR' not in config_target
989    config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
990  endif
991
992  foreach k, v: disassemblers
993    if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
994      foreach sym: v
995        config_target += { sym: 'y' }
996        config_all_disas += { sym: 'y' }
997      endforeach
998    endif
999  endforeach
1000
1001  config_target_data = configuration_data()
1002  foreach k, v: config_target
1003    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1004      # do nothing
1005    elif ignored.contains(k)
1006      # do nothing
1007    elif k == 'TARGET_BASE_ARCH'
1008      # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1009      # not used to select files from sourcesets.
1010      config_target_data.set('TARGET_' + v.to_upper(), 1)
1011    elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1012      config_target_data.set_quoted(k, v)
1013    elif v == 'y'
1014      config_target_data.set(k, 1)
1015    else
1016      config_target_data.set(k, v)
1017    endif
1018  endforeach
1019  config_target_h += {target: configure_file(output: target + '-config-target.h',
1020                                               configuration: config_target_data)}
1021
1022  if target.endswith('-softmmu')
1023    base_kconfig = []
1024    foreach sym : kconfig_external_symbols
1025      if sym in config_target or sym in config_host
1026        base_kconfig += '@0@=y'.format(sym)
1027      endif
1028    endforeach
1029
1030    config_devices_mak = target + '-config-devices.mak'
1031    config_devices_mak = configure_file(
1032      input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1033      output: config_devices_mak,
1034      depfile: config_devices_mak + '.d',
1035      capture: true,
1036      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
1037                config_devices_mak, '@DEPFILE@', '@INPUT@',
1038                base_kconfig])
1039
1040    config_devices_data = configuration_data()
1041    config_devices = keyval.load(config_devices_mak)
1042    foreach k, v: config_devices
1043      config_devices_data.set(k, 1)
1044    endforeach
1045    config_devices_mak_list += config_devices_mak
1046    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1047                                                configuration: config_devices_data)}
1048    config_target += config_devices
1049    config_all_devices += config_devices
1050  endif
1051  config_target_mak += {target: config_target}
1052endforeach
1053target_dirs = actual_target_dirs
1054
1055# This configuration is used to build files that are shared by
1056# multiple binaries, and then extracted out of the "common"
1057# static_library target.
1058#
1059# We do not use all_sources()/all_dependencies(), because it would
1060# build literally all source files, including devices only used by
1061# targets that are not built for this compilation.  The CONFIG_ALL
1062# pseudo symbol replaces it.
1063
1064config_all += config_all_devices
1065config_all += config_host
1066config_all += config_all_disas
1067config_all += {
1068  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1069  'CONFIG_SOFTMMU': have_system,
1070  'CONFIG_USER_ONLY': have_user,
1071  'CONFIG_ALL': true,
1072}
1073
1074##############
1075# Submodules #
1076##############
1077
1078capstone = not_found
1079capstone_opt = get_option('capstone')
1080if capstone_opt in ['enabled', 'auto', 'system']
1081  have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1082  capstone = dependency('capstone', version: '>=4.0',
1083                        static: enable_static, method: 'pkg-config',
1084                        required: capstone_opt == 'system' or
1085                                  capstone_opt == 'enabled' and not have_internal)
1086  if capstone.found()
1087    capstone_opt = 'system'
1088  elif have_internal
1089    capstone_opt = 'internal'
1090  else
1091    capstone_opt = 'disabled'
1092  endif
1093endif
1094if capstone_opt == 'internal'
1095  capstone_data = configuration_data()
1096  capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1097
1098  capstone_files = files(
1099    'capstone/cs.c',
1100    'capstone/MCInst.c',
1101    'capstone/MCInstrDesc.c',
1102    'capstone/MCRegisterInfo.c',
1103    'capstone/SStream.c',
1104    'capstone/utils.c'
1105  )
1106
1107  if 'CONFIG_ARM_DIS' in config_all_disas
1108    capstone_data.set('CAPSTONE_HAS_ARM', '1')
1109    capstone_files += files(
1110      'capstone/arch/ARM/ARMDisassembler.c',
1111      'capstone/arch/ARM/ARMInstPrinter.c',
1112      'capstone/arch/ARM/ARMMapping.c',
1113      'capstone/arch/ARM/ARMModule.c'
1114    )
1115  endif
1116
1117  # FIXME: This config entry currently depends on a c++ compiler.
1118  # Which is needed for building libvixl, but not for capstone.
1119  if 'CONFIG_ARM_A64_DIS' in config_all_disas
1120    capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1121    capstone_files += files(
1122      'capstone/arch/AArch64/AArch64BaseInfo.c',
1123      'capstone/arch/AArch64/AArch64Disassembler.c',
1124      'capstone/arch/AArch64/AArch64InstPrinter.c',
1125      'capstone/arch/AArch64/AArch64Mapping.c',
1126      'capstone/arch/AArch64/AArch64Module.c'
1127    )
1128  endif
1129
1130  if 'CONFIG_PPC_DIS' in config_all_disas
1131    capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1132    capstone_files += files(
1133      'capstone/arch/PowerPC/PPCDisassembler.c',
1134      'capstone/arch/PowerPC/PPCInstPrinter.c',
1135      'capstone/arch/PowerPC/PPCMapping.c',
1136      'capstone/arch/PowerPC/PPCModule.c'
1137    )
1138  endif
1139
1140  if 'CONFIG_S390_DIS' in config_all_disas
1141    capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1142    capstone_files += files(
1143      'capstone/arch/SystemZ/SystemZDisassembler.c',
1144      'capstone/arch/SystemZ/SystemZInstPrinter.c',
1145      'capstone/arch/SystemZ/SystemZMapping.c',
1146      'capstone/arch/SystemZ/SystemZModule.c',
1147      'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1148    )
1149  endif
1150
1151  if 'CONFIG_I386_DIS' in config_all_disas
1152    capstone_data.set('CAPSTONE_HAS_X86', 1)
1153    capstone_files += files(
1154      'capstone/arch/X86/X86Disassembler.c',
1155      'capstone/arch/X86/X86DisassemblerDecoder.c',
1156      'capstone/arch/X86/X86ATTInstPrinter.c',
1157      'capstone/arch/X86/X86IntelInstPrinter.c',
1158      'capstone/arch/X86/X86InstPrinterCommon.c',
1159      'capstone/arch/X86/X86Mapping.c',
1160      'capstone/arch/X86/X86Module.c'
1161    )
1162  endif
1163
1164  configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1165
1166  capstone_cargs = [
1167    # FIXME: There does not seem to be a way to completely replace the c_args
1168    # that come from add_project_arguments() -- we can only add to them.
1169    # So: disable all warnings with a big hammer.
1170    '-Wno-error', '-w',
1171
1172    # Include all configuration defines via a header file, which will wind up
1173    # as a dependency on the object file, and thus changes here will result
1174    # in a rebuild.
1175    '-include', 'capstone-defs.h'
1176  ]
1177
1178  libcapstone = static_library('capstone',
1179                               sources: capstone_files,
1180                               c_args: capstone_cargs,
1181                               include_directories: 'capstone/include')
1182  capstone = declare_dependency(link_with: libcapstone,
1183                                include_directories: 'capstone/include/capstone')
1184endif
1185
1186slirp = not_found
1187slirp_opt = 'disabled'
1188if have_system
1189  slirp_opt = get_option('slirp')
1190  if slirp_opt in ['enabled', 'auto', 'system']
1191    have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1192    slirp = dependency('slirp', static: enable_static,
1193                       method: 'pkg-config',
1194                       required: slirp_opt == 'system' or
1195                                 slirp_opt == 'enabled' and not have_internal)
1196    if slirp.found()
1197      slirp_opt = 'system'
1198    elif have_internal
1199      slirp_opt = 'internal'
1200    else
1201      slirp_opt = 'disabled'
1202    endif
1203  endif
1204  if slirp_opt == 'internal'
1205    slirp_deps = []
1206    if targetos == 'windows'
1207      slirp_deps = cc.find_library('iphlpapi')
1208    endif
1209    slirp_conf = configuration_data()
1210    slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1211    slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1212    slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1213    slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1214    slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1215    slirp_files = [
1216      'slirp/src/arp_table.c',
1217      'slirp/src/bootp.c',
1218      'slirp/src/cksum.c',
1219      'slirp/src/dhcpv6.c',
1220      'slirp/src/dnssearch.c',
1221      'slirp/src/if.c',
1222      'slirp/src/ip6_icmp.c',
1223      'slirp/src/ip6_input.c',
1224      'slirp/src/ip6_output.c',
1225      'slirp/src/ip_icmp.c',
1226      'slirp/src/ip_input.c',
1227      'slirp/src/ip_output.c',
1228      'slirp/src/mbuf.c',
1229      'slirp/src/misc.c',
1230      'slirp/src/ncsi.c',
1231      'slirp/src/ndp_table.c',
1232      'slirp/src/sbuf.c',
1233      'slirp/src/slirp.c',
1234      'slirp/src/socket.c',
1235      'slirp/src/state.c',
1236      'slirp/src/stream.c',
1237      'slirp/src/tcp_input.c',
1238      'slirp/src/tcp_output.c',
1239      'slirp/src/tcp_subr.c',
1240      'slirp/src/tcp_timer.c',
1241      'slirp/src/tftp.c',
1242      'slirp/src/udp.c',
1243      'slirp/src/udp6.c',
1244      'slirp/src/util.c',
1245      'slirp/src/version.c',
1246      'slirp/src/vmstate.c',
1247    ]
1248
1249    configure_file(
1250      input : 'slirp/src/libslirp-version.h.in',
1251      output : 'libslirp-version.h',
1252      configuration: slirp_conf)
1253
1254    slirp_inc = include_directories('slirp', 'slirp/src')
1255    libslirp = static_library('slirp',
1256                              sources: slirp_files,
1257                              c_args: slirp_cargs,
1258                              include_directories: slirp_inc)
1259    slirp = declare_dependency(link_with: libslirp,
1260                               dependencies: slirp_deps,
1261                               include_directories: slirp_inc)
1262  endif
1263endif
1264
1265fdt = not_found
1266fdt_opt = get_option('fdt')
1267if have_system
1268  if fdt_opt in ['enabled', 'auto', 'system']
1269    have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1270    fdt = cc.find_library('fdt', static: enable_static,
1271                          required: fdt_opt == 'system' or
1272                                    fdt_opt == 'enabled' and not have_internal)
1273    if fdt.found() and cc.links('''
1274       #include <libfdt.h>
1275       #include <libfdt_env.h>
1276       int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1277         dependencies: fdt)
1278      fdt_opt = 'system'
1279    elif have_internal
1280      fdt_opt = 'internal'
1281    else
1282      fdt_opt = 'disabled'
1283    endif
1284  endif
1285  if fdt_opt == 'internal'
1286    fdt_files = files(
1287      'dtc/libfdt/fdt.c',
1288      'dtc/libfdt/fdt_ro.c',
1289      'dtc/libfdt/fdt_wip.c',
1290      'dtc/libfdt/fdt_sw.c',
1291      'dtc/libfdt/fdt_rw.c',
1292      'dtc/libfdt/fdt_strerror.c',
1293      'dtc/libfdt/fdt_empty_tree.c',
1294      'dtc/libfdt/fdt_addresses.c',
1295      'dtc/libfdt/fdt_overlay.c',
1296      'dtc/libfdt/fdt_check.c',
1297    )
1298
1299    fdt_inc = include_directories('dtc/libfdt')
1300    libfdt = static_library('fdt',
1301                            sources: fdt_files,
1302                            include_directories: fdt_inc)
1303    fdt = declare_dependency(link_with: libfdt,
1304                             include_directories: fdt_inc)
1305  endif
1306endif
1307if not fdt.found() and fdt_required.length() > 0
1308  error('fdt not available but required by targets ' + ', '.join(fdt_required))
1309endif
1310
1311config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1312config_host_data.set('CONFIG_FDT', fdt.found())
1313config_host_data.set('CONFIG_SLIRP', slirp.found())
1314
1315#####################
1316# Generated sources #
1317#####################
1318
1319genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1320
1321hxtool = find_program('scripts/hxtool')
1322shaderinclude = find_program('scripts/shaderinclude.pl')
1323qapi_gen = find_program('scripts/qapi-gen.py')
1324qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1325                     meson.source_root() / 'scripts/qapi/commands.py',
1326                     meson.source_root() / 'scripts/qapi/common.py',
1327                     meson.source_root() / 'scripts/qapi/error.py',
1328                     meson.source_root() / 'scripts/qapi/events.py',
1329                     meson.source_root() / 'scripts/qapi/expr.py',
1330                     meson.source_root() / 'scripts/qapi/gen.py',
1331                     meson.source_root() / 'scripts/qapi/introspect.py',
1332                     meson.source_root() / 'scripts/qapi/parser.py',
1333                     meson.source_root() / 'scripts/qapi/schema.py',
1334                     meson.source_root() / 'scripts/qapi/source.py',
1335                     meson.source_root() / 'scripts/qapi/types.py',
1336                     meson.source_root() / 'scripts/qapi/visit.py',
1337                     meson.source_root() / 'scripts/qapi/common.py',
1338                     meson.source_root() / 'scripts/qapi-gen.py'
1339]
1340
1341tracetool = [
1342  python, files('scripts/tracetool.py'),
1343   '--backend=' + config_host['TRACE_BACKENDS']
1344]
1345
1346qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1347                    meson.current_source_dir(),
1348                    config_host['PKGVERSION'], meson.project_version()]
1349qemu_version = custom_target('qemu-version.h',
1350                             output: 'qemu-version.h',
1351                             command: qemu_version_cmd,
1352                             capture: true,
1353                             build_by_default: true,
1354                             build_always_stale: true)
1355genh += qemu_version
1356
1357hxdep = []
1358hx_headers = [
1359  ['qemu-options.hx', 'qemu-options.def'],
1360  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1361]
1362if have_system
1363  hx_headers += [
1364    ['hmp-commands.hx', 'hmp-commands.h'],
1365    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1366  ]
1367endif
1368foreach d : hx_headers
1369  hxdep += custom_target(d[1],
1370                input: files(d[0]),
1371                output: d[1],
1372                capture: true,
1373                build_by_default: true, # to be removed when added to a target
1374                command: [hxtool, '-h', '@INPUT0@'])
1375endforeach
1376genh += hxdep
1377
1378###################
1379# Collect sources #
1380###################
1381
1382authz_ss = ss.source_set()
1383blockdev_ss = ss.source_set()
1384block_ss = ss.source_set()
1385bsd_user_ss = ss.source_set()
1386chardev_ss = ss.source_set()
1387common_ss = ss.source_set()
1388crypto_ss = ss.source_set()
1389io_ss = ss.source_set()
1390linux_user_ss = ss.source_set()
1391qmp_ss = ss.source_set()
1392qom_ss = ss.source_set()
1393softmmu_ss = ss.source_set()
1394specific_fuzz_ss = ss.source_set()
1395specific_ss = ss.source_set()
1396stub_ss = ss.source_set()
1397trace_ss = ss.source_set()
1398user_ss = ss.source_set()
1399util_ss = ss.source_set()
1400
1401modules = {}
1402hw_arch = {}
1403target_arch = {}
1404target_softmmu_arch = {}
1405
1406###############
1407# Trace files #
1408###############
1409
1410# TODO: add each directory to the subdirs from its own meson.build, once
1411# we have those
1412trace_events_subdirs = [
1413  'accel/kvm',
1414  'accel/tcg',
1415  'crypto',
1416  'monitor',
1417]
1418if have_user
1419  trace_events_subdirs += [ 'linux-user' ]
1420endif
1421if have_block
1422  trace_events_subdirs += [
1423    'authz',
1424    'block',
1425    'io',
1426    'nbd',
1427    'scsi',
1428  ]
1429endif
1430if have_system
1431  trace_events_subdirs += [
1432    'audio',
1433    'backends',
1434    'backends/tpm',
1435    'chardev',
1436    'hw/9pfs',
1437    'hw/acpi',
1438    'hw/alpha',
1439    'hw/arm',
1440    'hw/audio',
1441    'hw/block',
1442    'hw/block/dataplane',
1443    'hw/char',
1444    'hw/display',
1445    'hw/dma',
1446    'hw/hppa',
1447    'hw/hyperv',
1448    'hw/i2c',
1449    'hw/i386',
1450    'hw/i386/xen',
1451    'hw/ide',
1452    'hw/input',
1453    'hw/intc',
1454    'hw/isa',
1455    'hw/mem',
1456    'hw/mips',
1457    'hw/misc',
1458    'hw/misc/macio',
1459    'hw/net',
1460    'hw/net/can',
1461    'hw/nvram',
1462    'hw/pci',
1463    'hw/pci-host',
1464    'hw/ppc',
1465    'hw/rdma',
1466    'hw/rdma/vmw',
1467    'hw/rtc',
1468    'hw/s390x',
1469    'hw/scsi',
1470    'hw/sd',
1471    'hw/sparc',
1472    'hw/sparc64',
1473    'hw/ssi',
1474    'hw/timer',
1475    'hw/tpm',
1476    'hw/usb',
1477    'hw/vfio',
1478    'hw/virtio',
1479    'hw/watchdog',
1480    'hw/xen',
1481    'hw/gpio',
1482    'migration',
1483    'net',
1484    'softmmu',
1485    'ui',
1486  ]
1487endif
1488trace_events_subdirs += [
1489  'hw/core',
1490  'qapi',
1491  'qom',
1492  'target/arm',
1493  'target/hppa',
1494  'target/i386',
1495  'target/mips',
1496  'target/ppc',
1497  'target/riscv',
1498  'target/s390x',
1499  'target/sparc',
1500  'util',
1501]
1502
1503vhost_user = not_found
1504if 'CONFIG_VHOST_USER' in config_host
1505  libvhost_user = subproject('libvhost-user')
1506  vhost_user = libvhost_user.get_variable('vhost_user_dep')
1507endif
1508
1509subdir('qapi')
1510subdir('qobject')
1511subdir('stubs')
1512subdir('trace')
1513subdir('util')
1514subdir('qom')
1515subdir('authz')
1516subdir('crypto')
1517subdir('ui')
1518
1519
1520if enable_modules
1521  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1522  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1523endif
1524
1525stub_ss = stub_ss.apply(config_all, strict: false)
1526
1527util_ss.add_all(trace_ss)
1528util_ss = util_ss.apply(config_all, strict: false)
1529libqemuutil = static_library('qemuutil',
1530                             sources: util_ss.sources() + stub_ss.sources() + genh,
1531                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1532qemuutil = declare_dependency(link_with: libqemuutil,
1533                              sources: genh + version_res)
1534
1535decodetree = generator(find_program('scripts/decodetree.py'),
1536                       output: 'decode-@BASENAME@.c.inc',
1537                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1538
1539subdir('audio')
1540subdir('io')
1541subdir('chardev')
1542subdir('fsdev')
1543subdir('libdecnumber')
1544subdir('target')
1545subdir('dump')
1546
1547block_ss.add(files(
1548  'block.c',
1549  'blockjob.c',
1550  'job.c',
1551  'qemu-io-cmds.c',
1552))
1553block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1554
1555subdir('nbd')
1556subdir('scsi')
1557subdir('block')
1558
1559blockdev_ss.add(files(
1560  'blockdev.c',
1561  'blockdev-nbd.c',
1562  'iothread.c',
1563  'job-qmp.c',
1564))
1565
1566# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1567# os-win32.c does not
1568blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1569softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1570
1571common_ss.add(files('cpus-common.c'))
1572
1573subdir('softmmu')
1574
1575common_ss.add(capstone)
1576specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1577specific_ss.add(files('exec-vary.c'))
1578specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1579  'fpu/softfloat.c',
1580  'tcg/optimize.c',
1581  'tcg/tcg-common.c',
1582  'tcg/tcg-op-gvec.c',
1583  'tcg/tcg-op-vec.c',
1584  'tcg/tcg-op.c',
1585  'tcg/tcg.c',
1586))
1587specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1588
1589subdir('backends')
1590subdir('disas')
1591subdir('migration')
1592subdir('monitor')
1593subdir('net')
1594subdir('replay')
1595subdir('hw')
1596subdir('accel')
1597subdir('plugins')
1598subdir('bsd-user')
1599subdir('linux-user')
1600
1601bsd_user_ss.add(files('gdbstub.c'))
1602specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1603
1604linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1605specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1606
1607# needed for fuzzing binaries
1608subdir('tests/qtest/libqos')
1609subdir('tests/qtest/fuzz')
1610
1611########################
1612# Library dependencies #
1613########################
1614
1615block_mods = []
1616softmmu_mods = []
1617foreach d, list : modules
1618  foreach m, module_ss : list
1619    if enable_modules and targetos != 'windows'
1620      module_ss = module_ss.apply(config_all, strict: false)
1621      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1622                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1623      if d == 'block'
1624        block_mods += sl
1625      else
1626        softmmu_mods += sl
1627      endif
1628    else
1629      if d == 'block'
1630        block_ss.add_all(module_ss)
1631      else
1632        softmmu_ss.add_all(module_ss)
1633      endif
1634    endif
1635  endforeach
1636endforeach
1637
1638nm = find_program('nm')
1639undefsym = find_program('scripts/undefsym.py')
1640block_syms = custom_target('block.syms', output: 'block.syms',
1641                             input: [libqemuutil, block_mods],
1642                             capture: true,
1643                             command: [undefsym, nm, '@INPUT@'])
1644qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1645                             input: [libqemuutil, softmmu_mods],
1646                             capture: true,
1647                             command: [undefsym, nm, '@INPUT@'])
1648
1649qom_ss = qom_ss.apply(config_host, strict: false)
1650libqom = static_library('qom', qom_ss.sources() + genh,
1651                        dependencies: [qom_ss.dependencies()],
1652                        name_suffix: 'fa')
1653
1654qom = declare_dependency(link_whole: libqom)
1655
1656authz_ss = authz_ss.apply(config_host, strict: false)
1657libauthz = static_library('authz', authz_ss.sources() + genh,
1658                          dependencies: [authz_ss.dependencies()],
1659                          name_suffix: 'fa',
1660                          build_by_default: false)
1661
1662authz = declare_dependency(link_whole: libauthz,
1663                           dependencies: qom)
1664
1665crypto_ss = crypto_ss.apply(config_host, strict: false)
1666libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1667                           dependencies: [crypto_ss.dependencies()],
1668                           name_suffix: 'fa',
1669                           build_by_default: false)
1670
1671crypto = declare_dependency(link_whole: libcrypto,
1672                            dependencies: [authz, qom])
1673
1674io_ss = io_ss.apply(config_host, strict: false)
1675libio = static_library('io', io_ss.sources() + genh,
1676                       dependencies: [io_ss.dependencies()],
1677                       link_with: libqemuutil,
1678                       name_suffix: 'fa',
1679                       build_by_default: false)
1680
1681io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1682
1683libmigration = static_library('migration', sources: migration_files + genh,
1684                              name_suffix: 'fa',
1685                              build_by_default: false)
1686migration = declare_dependency(link_with: libmigration,
1687                               dependencies: [zlib, qom, io])
1688softmmu_ss.add(migration)
1689
1690block_ss = block_ss.apply(config_host, strict: false)
1691libblock = static_library('block', block_ss.sources() + genh,
1692                          dependencies: block_ss.dependencies(),
1693                          link_depends: block_syms,
1694                          name_suffix: 'fa',
1695                          build_by_default: false)
1696
1697block = declare_dependency(link_whole: [libblock],
1698                           link_args: '@block.syms',
1699                           dependencies: [crypto, io])
1700
1701blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1702libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1703                             dependencies: blockdev_ss.dependencies(),
1704                             name_suffix: 'fa',
1705                             build_by_default: false)
1706
1707blockdev = declare_dependency(link_whole: [libblockdev],
1708                              dependencies: [block])
1709
1710qmp_ss = qmp_ss.apply(config_host, strict: false)
1711libqmp = static_library('qmp', qmp_ss.sources() + genh,
1712                        dependencies: qmp_ss.dependencies(),
1713                        name_suffix: 'fa',
1714                        build_by_default: false)
1715
1716qmp = declare_dependency(link_whole: [libqmp])
1717
1718libchardev = static_library('chardev', chardev_ss.sources() + genh,
1719                            name_suffix: 'fa',
1720                            build_by_default: false)
1721
1722chardev = declare_dependency(link_whole: libchardev)
1723
1724libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1725                           name_suffix: 'fa',
1726                           build_by_default: false)
1727hwcore = declare_dependency(link_whole: libhwcore)
1728common_ss.add(hwcore)
1729
1730###########
1731# Targets #
1732###########
1733
1734foreach m : block_mods + softmmu_mods
1735  shared_module(m.name(),
1736                name_prefix: '',
1737                link_whole: m,
1738                install: true,
1739                install_dir: qemu_moddir)
1740endforeach
1741
1742softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1743common_ss.add(qom, qemuutil)
1744
1745common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1746common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1747
1748common_all = common_ss.apply(config_all, strict: false)
1749common_all = static_library('common',
1750                            build_by_default: false,
1751                            sources: common_all.sources() + genh,
1752                            dependencies: common_all.dependencies(),
1753                            name_suffix: 'fa')
1754
1755feature_to_c = find_program('scripts/feature_to_c.sh')
1756
1757emulators = {}
1758foreach target : target_dirs
1759  config_target = config_target_mak[target]
1760  target_name = config_target['TARGET_NAME']
1761  arch = config_target['TARGET_BASE_ARCH']
1762  arch_srcs = [config_target_h[target]]
1763  arch_deps = []
1764  c_args = ['-DNEED_CPU_H',
1765            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1766            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1767  link_args = emulator_link_args
1768
1769  config_target += config_host
1770  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1771  if targetos == 'linux'
1772    target_inc += include_directories('linux-headers', is_system: true)
1773  endif
1774  if target.endswith('-softmmu')
1775    qemu_target_name = 'qemu-system-' + target_name
1776    target_type='system'
1777    t = target_softmmu_arch[arch].apply(config_target, strict: false)
1778    arch_srcs += t.sources()
1779    arch_deps += t.dependencies()
1780
1781    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1782    hw = hw_arch[hw_dir].apply(config_target, strict: false)
1783    arch_srcs += hw.sources()
1784    arch_deps += hw.dependencies()
1785
1786    arch_srcs += config_devices_h[target]
1787    link_args += ['@block.syms', '@qemu.syms']
1788  else
1789    abi = config_target['TARGET_ABI_DIR']
1790    target_type='user'
1791    qemu_target_name = 'qemu-' + target_name
1792    if 'CONFIG_LINUX_USER' in config_target
1793      base_dir = 'linux-user'
1794      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1795    else
1796      base_dir = 'bsd-user'
1797    endif
1798    target_inc += include_directories(
1799      base_dir,
1800      base_dir / abi,
1801    )
1802    if 'CONFIG_LINUX_USER' in config_target
1803      dir = base_dir / abi
1804      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1805      if config_target.has_key('TARGET_SYSTBL_ABI')
1806        arch_srcs += \
1807          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1808                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
1809      endif
1810    endif
1811  endif
1812
1813  if 'TARGET_XML_FILES' in config_target
1814    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1815                                output: target + '-gdbstub-xml.c',
1816                                input: files(config_target['TARGET_XML_FILES'].split()),
1817                                command: [feature_to_c, '@INPUT@'],
1818                                capture: true)
1819    arch_srcs += gdbstub_xml
1820  endif
1821
1822  t = target_arch[arch].apply(config_target, strict: false)
1823  arch_srcs += t.sources()
1824  arch_deps += t.dependencies()
1825
1826  target_common = common_ss.apply(config_target, strict: false)
1827  objects = common_all.extract_objects(target_common.sources())
1828  deps = target_common.dependencies()
1829
1830  target_specific = specific_ss.apply(config_target, strict: false)
1831  arch_srcs += target_specific.sources()
1832  arch_deps += target_specific.dependencies()
1833
1834  lib = static_library('qemu-' + target,
1835                 sources: arch_srcs + genh,
1836                 dependencies: arch_deps,
1837                 objects: objects,
1838                 include_directories: target_inc,
1839                 c_args: c_args,
1840                 build_by_default: false,
1841                 name_suffix: 'fa')
1842
1843  if target.endswith('-softmmu')
1844    execs = [{
1845      'name': 'qemu-system-' + target_name,
1846      'gui': false,
1847      'sources': files('softmmu/main.c'),
1848      'dependencies': []
1849    }]
1850    if targetos == 'windows' and (sdl.found() or gtk.found())
1851      execs += [{
1852        'name': 'qemu-system-' + target_name + 'w',
1853        'gui': true,
1854        'sources': files('softmmu/main.c'),
1855        'dependencies': []
1856      }]
1857    endif
1858    if config_host.has_key('CONFIG_FUZZ')
1859      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1860      execs += [{
1861        'name': 'qemu-fuzz-' + target_name,
1862        'gui': false,
1863        'sources': specific_fuzz.sources(),
1864        'dependencies': specific_fuzz.dependencies(),
1865      }]
1866    endif
1867  else
1868    execs = [{
1869      'name': 'qemu-' + target_name,
1870      'gui': false,
1871      'sources': [],
1872      'dependencies': []
1873    }]
1874  endif
1875  foreach exe: execs
1876    emulators += {exe['name']:
1877         executable(exe['name'], exe['sources'],
1878               install: true,
1879               c_args: c_args,
1880               dependencies: arch_deps + deps + exe['dependencies'],
1881               objects: lib.extract_all_objects(recursive: true),
1882               link_language: link_language,
1883               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1884               link_args: link_args,
1885               gui_app: exe['gui'])
1886    }
1887
1888    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1889      foreach stp: [
1890        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1891        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1892        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1893        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1894      ]
1895        custom_target(exe['name'] + stp['ext'],
1896                      input: trace_events_all,
1897                      output: exe['name'] + stp['ext'],
1898                      capture: true,
1899                      install: stp['install'],
1900                      install_dir: get_option('datadir') / 'systemtap/tapset',
1901                      command: [
1902                        tracetool, '--group=all', '--format=' + stp['fmt'],
1903                        '--binary=' + stp['bin'],
1904                        '--target-name=' + target_name,
1905                        '--target-type=' + target_type,
1906                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1907                        '@INPUT@',
1908                      ])
1909      endforeach
1910    endif
1911  endforeach
1912endforeach
1913
1914# Other build targets
1915
1916if 'CONFIG_PLUGIN' in config_host
1917  install_headers('include/qemu/qemu-plugin.h')
1918endif
1919
1920if 'CONFIG_GUEST_AGENT' in config_host
1921  subdir('qga')
1922endif
1923
1924# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1925# when we don't build tools or system
1926if xkbcommon.found()
1927  # used for the update-keymaps target, so include rules even if !have_tools
1928  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1929                           dependencies: [qemuutil, xkbcommon], install: have_tools)
1930endif
1931
1932if have_tools
1933  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1934             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1935  qemu_io = executable('qemu-io', files('qemu-io.c'),
1936             dependencies: [block, qemuutil], install: true)
1937  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1938               dependencies: [blockdev, qemuutil], install: true)
1939
1940  subdir('storage-daemon')
1941  subdir('contrib/rdmacm-mux')
1942  subdir('contrib/elf2dmp')
1943
1944  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1945             dependencies: qemuutil,
1946             install: true)
1947
1948  if 'CONFIG_VHOST_USER' in config_host
1949    subdir('contrib/vhost-user-blk')
1950    subdir('contrib/vhost-user-gpu')
1951    subdir('contrib/vhost-user-input')
1952    subdir('contrib/vhost-user-scsi')
1953  endif
1954
1955  if targetos == 'linux'
1956    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1957               dependencies: [qemuutil, libcap_ng],
1958               install: true,
1959               install_dir: get_option('libexecdir'))
1960
1961    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1962               dependencies: [authz, crypto, io, qom, qemuutil,
1963                              libcap_ng, mpathpersist],
1964               install: true)
1965  endif
1966
1967  if 'CONFIG_IVSHMEM' in config_host
1968    subdir('contrib/ivshmem-client')
1969    subdir('contrib/ivshmem-server')
1970  endif
1971endif
1972
1973subdir('scripts')
1974subdir('tools')
1975subdir('pc-bios')
1976subdir('docs')
1977subdir('tests')
1978if 'CONFIG_GTK' in config_host
1979  subdir('po')
1980endif
1981
1982if host_machine.system() == 'windows'
1983  nsis_cmd = [
1984    find_program('scripts/nsis.py'),
1985    '@OUTPUT@',
1986    get_option('prefix'),
1987    meson.current_source_dir(),
1988    host_machine.cpu(),
1989    '--',
1990    '-DDISPLAYVERSION=' + meson.project_version(),
1991  ]
1992  if build_docs
1993    nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1994  endif
1995  if 'CONFIG_GTK' in config_host
1996    nsis_cmd += '-DCONFIG_GTK=y'
1997  endif
1998
1999  nsis = custom_target('nsis',
2000                       output: 'qemu-setup-' + meson.project_version() + '.exe',
2001                       input: files('qemu.nsi'),
2002                       build_always_stale: true,
2003                       command: nsis_cmd + ['@INPUT@'])
2004  alias_target('installer', nsis)
2005endif
2006
2007#########################
2008# Configuration summary #
2009#########################
2010
2011summary_info = {}
2012summary_info += {'Install prefix':    get_option('prefix')}
2013summary_info += {'BIOS directory':    qemu_datadir}
2014summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2015summary_info += {'binary directory':  get_option('bindir')}
2016summary_info += {'library directory': get_option('libdir')}
2017summary_info += {'module directory':  qemu_moddir}
2018summary_info += {'libexec directory': get_option('libexecdir')}
2019summary_info += {'include directory': get_option('includedir')}
2020summary_info += {'config directory':  get_option('sysconfdir')}
2021if targetos != 'windows'
2022  summary_info += {'local state directory': get_option('localstatedir')}
2023  summary_info += {'Manual directory':      get_option('mandir')}
2024else
2025  summary_info += {'local state directory': 'queried at runtime'}
2026endif
2027summary_info += {'Doc directory':     get_option('docdir')}
2028summary_info += {'Build directory':   meson.current_build_dir()}
2029summary_info += {'Source path':       meson.current_source_dir()}
2030summary_info += {'GIT binary':        config_host['GIT']}
2031summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2032summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2033summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2034if link_language == 'cpp'
2035  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2036else
2037  summary_info += {'C++ compiler':      false}
2038endif
2039if targetos == 'darwin'
2040  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2041endif
2042summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2043summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2044                                               + ['-O' + get_option('optimization')]
2045                                               + (get_option('debug') ? ['-g'] : []))}
2046if link_language == 'cpp'
2047  summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2048                                               + ['-O' + get_option('optimization')]
2049                                               + (get_option('debug') ? ['-g'] : []))}
2050endif
2051link_args = get_option(link_language + '_link_args')
2052if link_args.length() > 0
2053  summary_info += {'LDFLAGS':         ' '.join(link_args)}
2054endif
2055summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2056summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2057summary_info += {'make':              config_host['MAKE']}
2058summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2059summary_info += {'sphinx-build':      sphinx_build.found()}
2060summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2061# TODO: add back version
2062summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2063if slirp_opt != 'disabled'
2064  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2065endif
2066summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2067if config_host.has_key('CONFIG_MODULES')
2068  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2069endif
2070summary_info += {'host CPU':          cpu}
2071summary_info += {'host endianness':   build_machine.endian()}
2072summary_info += {'target list':       ' '.join(target_dirs)}
2073summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2074summary_info += {'sparse enabled':    sparse.found()}
2075summary_info += {'strip binaries':    get_option('strip')}
2076summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2077summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2078if targetos == 'darwin'
2079  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2080endif
2081# TODO: add back version
2082summary_info += {'SDL support':       sdl.found()}
2083summary_info += {'SDL image support': sdl_image.found()}
2084# TODO: add back version
2085summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
2086summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
2087summary_info += {'pixman':            pixman.found()}
2088# TODO: add back version
2089summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2090summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2091summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2092# TODO: add back version
2093summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2094if config_host.has_key('CONFIG_GCRYPT')
2095   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2096   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2097endif
2098# TODO: add back version
2099summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2100if config_host.has_key('CONFIG_NETTLE')
2101   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2102endif
2103summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2104summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2105summary_info += {'iconv support':     iconv.found()}
2106summary_info += {'curses support':    curses.found()}
2107# TODO: add back version
2108summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2109summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
2110summary_info += {'mingw32 support':   targetos == 'windows'}
2111summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2112summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2113summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2114summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
2115summary_info += {'build virtiofs daemon': have_virtiofsd}
2116summary_info += {'Multipath support': mpathpersist.found()}
2117summary_info += {'VNC support':       vnc.found()}
2118if vnc.found()
2119  summary_info += {'VNC SASL support':  sasl.found()}
2120  summary_info += {'VNC JPEG support':  jpeg.found()}
2121  summary_info += {'VNC PNG support':   png.found()}
2122endif
2123summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2124if config_host.has_key('CONFIG_XEN_BACKEND')
2125  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2126endif
2127summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
2128summary_info += {'Documentation':     build_docs}
2129summary_info += {'PIE':               get_option('b_pie')}
2130summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2131summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2132summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2133summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2134summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2135summary_info += {'Install blobs':     get_option('install_blobs')}
2136summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2137summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2138summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2139summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2140summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2141if config_all.has_key('CONFIG_TCG')
2142  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2143  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
2144endif
2145summary_info += {'malloc trim support': has_malloc_trim}
2146summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2147summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2148summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2149summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2150summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2151summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2152summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2153summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2154summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2155summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2156summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2157summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2158summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2159summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2160summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2161summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2162summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2163summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2164summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2165summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2166if config_host['TRACE_BACKENDS'].split().contains('simple')
2167  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2168endif
2169# TODO: add back protocol and server version
2170summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2171summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
2172summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2173summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2174summary_info += {'U2F support':       u2f.found()}
2175summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2176summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2177summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2178summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2179summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
2180summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
2181summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2182if targetos == 'windows'
2183  if 'WIN_SDK' in config_host
2184    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
2185  endif
2186  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2187  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2188  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
2189endif
2190summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
2191summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2192summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2193summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2194summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2195summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2196summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
2197summary_info += {'gcov':              get_option('b_coverage')}
2198summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2199summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2200summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2201summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2202summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
2203summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
2204summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
2205summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
2206summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
2207summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2208summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2209summary_info += {'memory allocator':  get_option('malloc')}
2210summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2211summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2212summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2213summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2214summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2215summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2216summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2217summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2218summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2219summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2220summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2221summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2222summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2223summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2224summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2225summary_info += {'libudev':           libudev.found()}
2226summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2227summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2228summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2229if config_host.has_key('HAVE_GDB_BIN')
2230  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2231endif
2232summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2233summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2234summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2235summary_info += {'FUSE exports':      fuse.found()}
2236summary_info += {'FUSE lseek':        fuse_lseek.found()}
2237summary(summary_info, bool_yn: true)
2238
2239if not supported_cpus.contains(cpu)
2240  message()
2241  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2242  message()
2243  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2244  message('The QEMU project intends to remove support for this host CPU in')
2245  message('a future release if nobody volunteers to maintain it and to')
2246  message('provide a build host for our continuous integration setup.')
2247  message('configure has succeeded and you can continue to build, but')
2248  message('if you care about QEMU on this platform you should contact')
2249  message('us upstream at qemu-devel@nongnu.org.')
2250endif
2251
2252if not supported_oses.contains(targetos)
2253  message()
2254  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2255  message()
2256  message('Host OS ' + targetos + 'support is not currently maintained.')
2257  message('The QEMU project intends to remove support for this host OS in')
2258  message('a future release if nobody volunteers to maintain it and to')
2259  message('provide a build host for our continuous integration setup.')
2260  message('configure has succeeded and you can continue to build, but')
2261  message('if you care about QEMU on this platform you should contact')
2262  message('us upstream at qemu-devel@nongnu.org.')
2263endif
2264