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