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