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