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