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