1 project('qemu', ['c'], meson_version: '>=0.55.0',
2 default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_lundef=false'],
3 version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
5 not_found = dependency('', required: false)
6 keyval = import('unstable-keyval')
7 ss = import('sourceset')
9 sh = find_program('sh')
10 cc = meson.get_compiler('c')
11 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
12 config_all_disas = keyval.load(meson.current_build_dir() / 'config-all-disas.mak')
13 enable_modules = 'CONFIG_MODULES' in config_host
15 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
16 native: false, language: ['c', 'objc'])
17 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
18 native: false, language: 'cpp')
19 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
20 native: false, language: ['c', 'cpp', 'objc'])
21 add_project_arguments(config_host['QEMU_INCLUDES'].split(),
22 language: ['c', 'cpp', 'objc'])
24 python = import('python').find_installation()
26 link_language = meson.get_external_property('link_language', 'cpp')
27 if link_language == 'cpp'
28 add_languages('cpp', required: true, native: false)
30 if host_machine.system() == 'darwin'
31 add_languages('objc', required: false, native: false)
34 if 'SPARSE_CFLAGS' in config_host
36 command: [find_program('scripts/check_sparse.py'),
37 config_host['SPARSE_CFLAGS'].split(),
38 'compile_commands.json'])
41 configure_file(input: files('scripts/ninjatool.py'),
43 configuration: config_host)
45 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
46 supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
47 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
49 cpu = host_machine.cpu_family()
50 targetos = host_machine.system()
52 m = cc.find_library('m', required: false)
53 util = cc.find_library('util', required: false)
61 if targetos == 'windows'
62 socket = cc.find_library('ws2_32')
63 winmm = cc.find_library('winmm')
65 win = import('windows')
66 version_res = win.compile_resources('version.rc',
67 depend_files: files('pc-bios/qemu-nsis.ico'),
68 include_directories: include_directories('.'))
69 elif targetos == 'darwin'
70 coref = dependency('appleframeworks', modules: 'CoreFoundation')
71 iokit = dependency('appleframeworks', modules: 'IOKit')
72 cocoa = dependency('appleframeworks', modules: 'Cocoa')
73 hvf = dependency('appleframeworks', modules: 'Hypervisor')
74 elif targetos == 'sunos'
75 socket = [cc.find_library('socket'),
76 cc.find_library('nsl'),
77 cc.find_library('resolv')]
78 elif targetos == 'haiku'
79 socket = [cc.find_library('posix_error_mapper'),
80 cc.find_library('network'),
81 cc.find_library('bsd')]
83 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
84 link_args: config_host['GLIB_LIBS'].split())
86 if 'CONFIG_GIO' in config_host
87 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
88 link_args: config_host['GIO_LIBS'].split())
91 if 'CONFIG_TRACE_UST' in config_host
92 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
95 if 'CONFIG_TRACE_UST' in config_host
96 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
99 if 'CONFIG_NETTLE' in config_host
100 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
101 link_args: config_host['NETTLE_LIBS'].split())
104 if 'CONFIG_GNUTLS' in config_host
105 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
106 link_args: config_host['GNUTLS_LIBS'].split())
108 pixman = declare_dependency(compile_args: config_host['PIXMAN_CFLAGS'].split(),
109 link_args: config_host['PIXMAN_LIBS'].split())
111 if 'CONFIG_AUTH_PAM' in config_host
112 pam = cc.find_library('pam')
114 libaio = cc.find_library('aio', required: false)
116 if 'CONFIG_ZLIB' in config_host
117 zlib = declare_dependency(compile_args: config_host['ZLIB_CFLAGS'].split(),
118 link_args: config_host['ZLIB_LIBS'].split())
120 linux_io_uring = not_found
121 if 'CONFIG_LINUX_IO_URING' in config_host
122 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
123 link_args: config_host['LINUX_IO_URING_LIBS'].split())
126 if 'CONFIG_LIBXML2' in config_host
127 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
128 link_args: config_host['LIBXML2_LIBS'].split())
131 if 'CONFIG_LIBNFS' in config_host
132 libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
135 if 'CONFIG_ATTR' in config_host
136 libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
139 if 'CONFIG_SECCOMP' in config_host
140 seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
141 link_args: config_host['SECCOMP_LIBS'].split())
143 libcap_ng = not_found
144 if 'CONFIG_LIBCAP_NG' in config_host
145 libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
147 xkbcommon = not_found
148 if 'CONFIG_XKBCOMMON' in config_host
149 xkbcommon = declare_dependency(compile_args: config_host['XKBCOMMON_CFLAGS'].split(),
150 link_args: config_host['XKBCOMMON_LIBS'].split())
153 if 'CONFIG_LIBPULSE' in config_host
154 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
155 link_args: config_host['PULSE_LIBS'].split())
158 if 'CONFIG_ALSA' in config_host
159 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
160 link_args: config_host['ALSA_LIBS'].split())
163 if 'CONFIG_LIBJACK' in config_host
164 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
167 if 'CONFIG_SPICE' in config_host
168 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
169 link_args: config_host['SPICE_LIBS'].split())
171 rt = cc.find_library('rt', required: false)
172 libmpathpersist = not_found
173 if config_host.has_key('CONFIG_MPATH')
174 libmpathpersist = cc.find_library('mpathpersist')
177 if 'CONFIG_LIBISCSI' in config_host
178 libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
179 link_args: config_host['LIBISCSI_LIBS'].split())
182 if 'CONFIG_ZSTD' in config_host
183 zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
184 link_args: config_host['ZSTD_LIBS'].split())
187 if 'CONFIG_GBM' in config_host
188 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
189 link_args: config_host['GBM_LIBS'].split())
192 if 'CONFIG_VIRGL' in config_host
193 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
194 link_args: config_host['VIRGL_LIBS'].split())
197 if 'CONFIG_CURL' in config_host
198 curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
199 link_args: config_host['CURL_LIBS'].split())
202 if 'CONFIG_LIBUDEV' in config_host
203 libudev = declare_dependency(link_args: config_host['LIBUDEV_LIBS'].split())
206 if 'CONFIG_BRLAPI' in config_host
207 brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
210 if 'CONFIG_SDL' in config_host
211 sdl = declare_dependency(compile_args: config_host['SDL_CFLAGS'].split(),
212 link_args: config_host['SDL_LIBS'].split())
215 if 'CONFIG_RBD' in config_host
216 rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
218 glusterfs = not_found
219 if 'CONFIG_GLUSTERFS' in config_host
220 glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
221 link_args: config_host['GLUSTERFS_LIBS'].split())
224 if 'CONFIG_LIBSSH' in config_host
225 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
226 link_args: config_host['LIBSSH_LIBS'].split())
229 if 'CONFIG_BZIP2' in config_host
230 libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
233 if 'CONFIG_LZFSE' in config_host
234 liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
237 if 'CONFIG_AUDIO_OSS' in config_host
238 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
241 if 'CONFIG_AUDIO_DSOUND' in config_host
242 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
244 coreaudio = not_found
245 if 'CONFIG_AUDIO_COREAUDIO' in config_host
246 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
249 if 'CONFIG_OPENGL' in config_host
250 opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
254 if 'CONFIG_GTK' in config_host
255 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
256 link_args: config_host['GTK_LIBS'].split())
259 if 'CONFIG_VTE' in config_host
260 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
261 link_args: config_host['VTE_LIBS'].split())
264 if 'CONFIG_X11' in config_host
265 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
266 link_args: config_host['X11_LIBS'].split())
269 if 'CONFIG_CURSES' in config_host
270 curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
271 link_args: config_host['CURSES_LIBS'].split())
274 if 'CONFIG_ICONV' in config_host
275 iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
276 link_args: config_host['ICONV_LIBS'].split())
279 if 'CONFIG_GIO' in config_host
280 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
281 link_args: config_host['GIO_LIBS'].split())
284 if 'CONFIG_VNC_PNG' in config_host
285 png = declare_dependency(compile_args: config_host['PNG_CFLAGS'].split(),
286 link_args: config_host['PNG_LIBS'].split())
289 if 'CONFIG_VNC_JPEG' in config_host
290 jpeg = declare_dependency(compile_args: config_host['JPEG_CFLAGS'].split(),
291 link_args: config_host['JPEG_LIBS'].split())
294 if 'CONFIG_VNC_SASL' in config_host
295 sasl = declare_dependency(compile_args: config_host['SASL_CFLAGS'].split(),
296 link_args: config_host['SASL_LIBS'].split())
299 if 'CONFIG_FDT' in config_host
300 fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
301 link_args: config_host['FDT_LIBS'].split())
304 if 'CONFIG_SNAPPY' in config_host
305 snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
308 if 'CONFIG_LZO' in config_host
309 lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
312 create_config = find_program('scripts/create_config')
313 minikconf = find_program('scripts/minikconf.py')
314 target_dirs = config_host['TARGET_DIRS'].split()
317 config_devices_mak_list = []
318 config_devices_h = {}
319 config_target_mak = {}
320 kconfig_external_symbols = [
329 'CONFIG_VHOST_KERNEL',
334 foreach target : target_dirs
335 have_user = have_user or target.endswith('-user')
336 config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak') + config_host
338 if target.endswith('-softmmu')
342 foreach sym : kconfig_external_symbols
343 if sym in config_target
344 base_kconfig += '@0@=y'.format(sym)
348 config_devices_mak = target + '-config-devices.mak'
349 config_devices_mak = configure_file(
350 input: ['default-configs' / target + '.mak', 'Kconfig'],
351 output: config_devices_mak,
352 depfile: config_devices_mak + '.d',
354 command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
355 config_devices_mak, '@DEPFILE@', '@INPUT@',
357 config_devices_h += {target: custom_target(
358 target + '-config-devices.h',
359 input: config_devices_mak,
360 output: target + '-config-devices.h',
362 command: [create_config, '@INPUT@'])}
363 config_devices_mak_list += config_devices_mak
364 config_target += keyval.load(config_devices_mak)
366 config_target_mak += {target: config_target}
368 have_tools = 'CONFIG_TOOLS' in config_host
369 have_block = have_system or have_tools
371 grepy = find_program('scripts/grepy.sh')
372 # This configuration is used to build files that are shared by
373 # multiple binaries, and then extracted out of the "common"
374 # static_library target.
376 # We do not use all_sources()/all_dependencies(), because it would
377 # build literally all source files, including devices only used by
378 # targets that are not built for this compilation. The CONFIG_ALL
379 # pseudo symbol replaces it.
382 config_all_devices_mak = configure_file(
383 output: 'config-all-devices.mak',
384 input: config_devices_mak_list,
386 command: [grepy, '@INPUT@'],
388 config_all_devices = keyval.load(config_all_devices_mak)
390 config_all_devices = {}
392 config_all = config_all_devices
393 config_all += config_host
394 config_all += config_all_disas
396 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
397 'CONFIG_SOFTMMU': have_system,
398 'CONFIG_USER_ONLY': have_user,
405 hxtool = find_program('scripts/hxtool')
406 shaderinclude = find_program('scripts/shaderinclude.pl')
407 qapi_gen = find_program('scripts/qapi-gen.py')
408 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
409 meson.source_root() / 'scripts/qapi/commands.py',
410 meson.source_root() / 'scripts/qapi/common.py',
411 meson.source_root() / 'scripts/qapi/doc.py',
412 meson.source_root() / 'scripts/qapi/error.py',
413 meson.source_root() / 'scripts/qapi/events.py',
414 meson.source_root() / 'scripts/qapi/expr.py',
415 meson.source_root() / 'scripts/qapi/gen.py',
416 meson.source_root() / 'scripts/qapi/introspect.py',
417 meson.source_root() / 'scripts/qapi/parser.py',
418 meson.source_root() / 'scripts/qapi/schema.py',
419 meson.source_root() / 'scripts/qapi/source.py',
420 meson.source_root() / 'scripts/qapi/types.py',
421 meson.source_root() / 'scripts/qapi/visit.py',
422 meson.source_root() / 'scripts/qapi/common.py',
423 meson.source_root() / 'scripts/qapi/doc.py',
424 meson.source_root() / 'scripts/qapi-gen.py'
428 python, files('scripts/tracetool.py'),
429 '--backend=' + config_host['TRACE_BACKENDS']
432 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
433 meson.current_source_dir(),
434 config_host['PKGVERSION'], config_host['VERSION']]
435 qemu_version = custom_target('qemu-version.h',
436 output: 'qemu-version.h',
437 command: qemu_version_cmd,
439 build_by_default: true,
440 build_always_stale: true)
443 config_host_h = custom_target('config-host.h',
444 input: meson.current_build_dir() / 'config-host.mak',
445 output: 'config-host.h',
447 command: [create_config, '@INPUT@'])
448 genh += config_host_h
452 ['qemu-options.hx', 'qemu-options.def'],
453 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
457 ['hmp-commands.hx', 'hmp-commands.h'],
458 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
461 foreach d : hx_headers
462 hxdep += custom_target(d[1],
466 build_by_default: true, # to be removed when added to a target
467 command: [hxtool, '-h', '@INPUT0@'])
471 # Collect sourcesets.
473 util_ss = ss.source_set()
474 stub_ss = ss.source_set()
475 trace_ss = ss.source_set()
476 block_ss = ss.source_set()
477 blockdev_ss = ss.source_set()
478 qmp_ss = ss.source_set()
479 common_ss = ss.source_set()
480 softmmu_ss = ss.source_set()
481 user_ss = ss.source_set()
482 bsd_user_ss = ss.source_set()
483 linux_user_ss = ss.source_set()
484 specific_ss = ss.source_set()
489 target_softmmu_arch = {}
495 trace_events_subdirs = [
502 trace_events_subdirs += [ 'linux-user' ]
505 trace_events_subdirs += [
514 trace_events_subdirs += [
525 'hw/block/dataplane',
570 trace_events_subdirs += [
597 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
598 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
601 # Build targets from sourcesets
603 stub_ss = stub_ss.apply(config_all, strict: false)
605 util_ss.add_all(trace_ss)
606 util_ss = util_ss.apply(config_all, strict: false)
607 libqemuutil = static_library('qemuutil',
608 sources: util_ss.sources() + stub_ss.sources() + genh,
609 dependencies: [util_ss.dependencies(), m, glib, socket])
610 qemuutil = declare_dependency(link_with: libqemuutil,
611 sources: genh + version_res)
626 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
632 blockdev_ss.add(files(
639 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
640 # os-win32.c does not
641 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
642 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
644 softmmu_ss.add_all(blockdev_ss)
645 softmmu_ss.add(files(
651 softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
652 softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
653 softmmu_ss.add(when: ['CONFIG_FDT', fdt], if_true: [files('device_tree.c')])
655 common_ss.add(files('cpus-common.c'))
660 # needed for fuzzing binaries
661 subdir('tests/qtest/libqos')
665 foreach d, list : modules
666 foreach m, module_ss : list
667 if enable_modules and targetos != 'windows'
668 module_ss = module_ss.apply(config_host, strict: false)
669 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
670 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
678 block_ss.add_all(module_ss)
680 softmmu_ss.add_all(module_ss)
686 nm = find_program('nm')
687 undefsym = find_program('scripts/undefsym.sh')
688 block_syms = custom_target('block.syms', output: 'block.syms',
689 input: [libqemuutil, block_mods],
691 command: [undefsym, nm, '@INPUT@'])
692 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
693 input: [libqemuutil, softmmu_mods],
695 command: [undefsym, nm, '@INPUT@'])
697 block_ss = block_ss.apply(config_host, strict: false)
698 libblock = static_library('block', block_ss.sources() + genh,
699 dependencies: block_ss.dependencies(),
700 link_depends: block_syms,
702 build_by_default: false)
704 block = declare_dependency(link_whole: [libblock],
705 link_args: '@block.syms',
706 dependencies: [crypto, io])
708 qmp_ss = qmp_ss.apply(config_host, strict: false)
709 libqmp = static_library('qmp', qmp_ss.sources() + genh,
710 dependencies: qmp_ss.dependencies(),
712 build_by_default: false)
714 qmp = declare_dependency(link_whole: [libqmp])
716 foreach m : block_mods + softmmu_mods
717 shared_module(m.name(),
721 install_dir: config_host['qemu_moddir'])
724 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: softmmu_ss)
725 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
727 common_all = common_ss.apply(config_all, strict: false)
728 common_all = static_library('common',
729 build_by_default: false,
730 sources: common_all.sources() + genh,
731 dependencies: common_all.dependencies(),
734 foreach target : target_dirs
735 config_target = config_target_mak[target]
736 target_name = config_target['TARGET_NAME']
737 arch = config_target['TARGET_BASE_ARCH']
740 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
741 if targetos == 'linux'
742 target_inc += include_directories('linux-headers', is_system: true)
744 if target.endswith('-softmmu')
745 qemu_target_name = 'qemu-system-' + target_name
747 arch_srcs += config_devices_h[target]
750 qemu_target_name = 'qemu-' + target_name
751 if 'CONFIG_LINUX_USER' in config_target
752 base_dir = 'linux-user'
753 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
755 base_dir = 'bsd-user'
757 target_inc += include_directories(
759 base_dir / config_target['TARGET_ABI_DIR'],
763 target_common = common_ss.apply(config_target, strict: false)
764 objects = common_all.extract_objects(target_common.sources())
766 # TODO: Change to generator once obj-y goes away
767 config_target_h = custom_target(target + '-config-target.h',
768 input: meson.current_build_dir() / target / 'config-target.mak',
769 output: target + '-config-target.h',
771 command: [create_config, '@INPUT@'])
773 target_specific = specific_ss.apply(config_target, strict: false)
774 arch_srcs += target_specific.sources()
776 static_library('qemu-' + target,
777 sources: arch_srcs + [config_target_h] + genh,
779 include_directories: target_inc,
780 c_args: ['-DNEED_CPU_H',
781 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
782 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)],
786 # Other build targets
788 if 'CONFIG_GUEST_AGENT' in config_host
793 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
794 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
795 qemu_io = executable('qemu-io', files('qemu-io.c'),
796 dependencies: [block, qemuutil], install: true)
797 if targetos == 'linux' or targetos == 'sunos' or targetos.endswith('bsd')
798 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
799 dependencies: [block, qemuutil], install: true)
802 subdir('storage-daemon')
803 subdir('contrib/rdmacm-mux')
804 subdir('contrib/elf2dmp')
806 if 'CONFIG_XKBCOMMON' in config_host
807 executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c'),
808 dependencies: [qemuutil, xkbcommon], install: true)
811 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
812 dependencies: qemuutil,
815 if 'CONFIG_VHOST_USER' in config_host
816 subdir('contrib/libvhost-user')
817 subdir('contrib/vhost-user-blk')
818 if 'CONFIG_LINUX' in config_host
819 subdir('contrib/vhost-user-gpu')
821 subdir('contrib/vhost-user-input')
822 subdir('contrib/vhost-user-scsi')
825 if targetos == 'linux'
826 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
827 dependencies: [qemuutil, libcap_ng],
829 install_dir: get_option('libexecdir'))
831 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
832 dependencies: [authz, crypto, io, qom, qemuutil,
833 libcap_ng, libudev, libmpathpersist],
837 if 'CONFIG_IVSHMEM' in config_host
838 subdir('contrib/ivshmem-client')
839 subdir('contrib/ivshmem-server')
848 summary_info += {'Install prefix': config_host['prefix']}
849 summary_info += {'BIOS directory': config_host['qemu_datadir']}
850 summary_info += {'firmware path': config_host['qemu_firmwarepath']}
851 summary_info += {'binary directory': config_host['bindir']}
852 summary_info += {'library directory': config_host['libdir']}
853 summary_info += {'module directory': config_host['qemu_moddir']}
854 summary_info += {'libexec directory': config_host['libexecdir']}
855 summary_info += {'include directory': config_host['includedir']}
856 summary_info += {'config directory': config_host['sysconfdir']}
857 if targetos != 'windows'
858 summary_info += {'local state directory': config_host['qemu_localstatedir']}
859 summary_info += {'Manual directory': config_host['mandir']}
861 summary_info += {'local state directory': 'queried at runtime'}
863 summary_info += {'Build directory': meson.current_build_dir()}
864 summary_info += {'Source path': meson.current_source_dir()}
865 summary_info += {'GIT binary': config_host['GIT']}
866 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
867 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
868 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
869 if link_language == 'cpp'
870 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
872 summary_info += {'C++ compiler': false}
874 if targetos == 'darwin'
875 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
877 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
878 summary_info += {'CFLAGS': config_host['CFLAGS']}
879 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
880 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
881 summary_info += {'make': config_host['MAKE']}
882 summary_info += {'install': config_host['INSTALL']}
883 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
884 summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
885 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
886 # TODO: add back version
887 summary_info += {'slirp support': config_host.has_key('CONFIG_SLIRP')}
888 if config_host.has_key('CONFIG_SLIRP')
889 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
891 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
892 if config_host.has_key('CONFIG_MODULES')
893 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
895 summary_info += {'host CPU': cpu}
896 summary_info += {'host endianness': build_machine.endian()}
897 summary_info += {'target list': config_host['TARGET_DIRS']}
898 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
899 summary_info += {'sparse enabled': meson.get_compiler('c').cmd_array().contains('cgcc')}
900 summary_info += {'strip binaries': get_option('strip')}
901 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
902 summary_info += {'static build': config_host.has_key('CONFIG_TOOLS')}
903 if targetos == 'darwin'
904 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
906 # TODO: add back version
907 summary_info += {'SDL support': config_host.has_key('CONFIG_SDL')}
908 summary_info += {'SDL image support': config_host.has_key('CONFIG_SDL_IMAGE')}
909 # TODO: add back version
910 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
911 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
912 # TODO: add back version
913 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
914 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
915 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
916 # TODO: add back version
917 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
918 if config_host.has_key('CONFIG_GCRYPT')
919 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
920 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
922 # TODO: add back version
923 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
924 if config_host.has_key('CONFIG_NETTLE')
925 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
927 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
928 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
929 summary_info += {'iconv support': config_host.has_key('CONFIG_ICONV')}
930 summary_info += {'curses support': config_host.has_key('CONFIG_CURSES')}
931 # TODO: add back version
932 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
933 summary_info += {'curl support': config_host.has_key('CONFIG_CURL')}
934 summary_info += {'mingw32 support': targetos == 'windows'}
935 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
936 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
937 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
938 summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
939 summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
940 summary_info += {'VNC support': config_host.has_key('CONFIG_VNC')}
941 if config_host.has_key('CONFIG_VNC')
942 summary_info += {'VNC SASL support': config_host.has_key('CONFIG_VNC_SASL')}
943 summary_info += {'VNC JPEG support': config_host.has_key('CONFIG_VNC_JPEG')}
944 summary_info += {'VNC PNG support': config_host.has_key('CONFIG_VNC_PNG')}
946 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
947 if config_host.has_key('CONFIG_XEN_BACKEND')
948 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
950 summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')}
951 summary_info += {'Documentation': config_host.has_key('BUILD_DOCS')}
952 summary_info += {'PIE': get_option('b_pie')}
953 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
954 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
955 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
956 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
957 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
958 summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')}
959 # TODO: add back KVM/HAX/HVF/WHPX/TCG
960 #summary_info += {'KVM support': have_kvm'}
961 #summary_info += {'HAX support': have_hax'}
962 #summary_info += {'HVF support': have_hvf'}
963 #summary_info += {'WHPX support': have_whpx'}
964 #summary_info += {'TCG support': have_tcg'}
965 #if get_option('tcg')
966 # summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
967 # summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
969 summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
970 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
971 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
972 summary_info += {'fdt support': config_host.has_key('CONFIG_FDT')}
973 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
974 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
975 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
976 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
977 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
978 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
979 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
980 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
981 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
982 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
983 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
984 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
985 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
986 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
987 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
988 if config_host['TRACE_BACKENDS'].split().contains('simple')
989 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
991 # TODO: add back protocol and server version
992 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
993 summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')}
994 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
995 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
996 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
997 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
998 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
999 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
1000 summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')}
1001 summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')}
1002 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1003 if targetos == 'windows'
1004 if 'WIN_SDK' in config_host
1005 summary_info += {'Windows SDK': config_host['WIN_SDK']}
1007 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
1008 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1009 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1011 summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
1012 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1013 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
1014 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1015 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
1016 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
1017 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1018 summary_info += {'gcov': get_option('b_coverage')}
1019 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
1020 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
1021 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1022 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1023 summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')}
1024 summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')}
1025 summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')}
1026 summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
1027 summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
1028 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1029 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
1030 summary_info += {'tcmalloc support': config_host.has_key('CONFIG_TCMALLOC')}
1031 summary_info += {'jemalloc support': config_host.has_key('CONFIG_JEMALLOC')}
1032 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1033 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1034 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1035 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
1036 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
1037 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
1038 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
1039 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
1040 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
1041 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
1042 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1043 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
1044 summary_info += {'capstone': config_host.has_key('CONFIG_CAPSTONE')}
1045 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
1046 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1047 summary_info += {'libudev': config_host.has_key('CONFIG_LIBUDEV')}
1048 summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1049 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
1050 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
1051 if config_host.has_key('HAVE_GDB_BIN')
1052 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
1054 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
1055 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
1056 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
1057 summary(summary_info, bool_yn: true)
1059 if not supported_cpus.contains(cpu)
1061 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1063 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1064 message('The QEMU project intends to remove support for this host CPU in')
1065 message('a future release if nobody volunteers to maintain it and to')
1066 message('provide a build host for our continuous integration setup.')
1067 message('configure has succeeded and you can continue to build, but')
1068 message('if you care about QEMU on this platform you should contact')
1069 message('us upstream at qemu-devel@nongnu.org.')
1072 if not supported_oses.contains(targetos)
1074 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1076 message('Host OS ' + targetos + 'support is not currently maintained.')
1077 message('The QEMU project intends to remove support for this host OS in')
1078 message('a future release if nobody volunteers to maintain it and to')
1079 message('provide a build host for our continuous integration setup.')
1080 message('configure has succeeded and you can continue to build, but')
1081 message('if you care about QEMU on this platform you should contact')
1082 message('us upstream at qemu-devel@nongnu.org.')