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