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 cc = meson.get_compiler('c')
10 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
12 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
13 native: false, language: ['c', 'objc'])
14 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
15 native: false, language: 'cpp')
16 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
17 native: false, language: ['c', 'cpp', 'objc'])
18 add_project_arguments(config_host['QEMU_INCLUDES'].split(),
19 language: ['c', 'cpp', 'objc'])
21 python = import('python').find_installation()
23 link_language = meson.get_external_property('link_language', 'cpp')
24 if link_language == 'cpp'
25 add_languages('cpp', required: true, native: false)
27 if host_machine.system() == 'darwin'
28 add_languages('objc', required: false, native: false)
31 if 'SPARSE_CFLAGS' in config_host
33 command: [find_program('scripts/check_sparse.py'),
34 config_host['SPARSE_CFLAGS'].split(),
35 'compile_commands.json'])
38 configure_file(input: files('scripts/ninjatool.py'),
40 configuration: config_host)
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 m = cc.find_library('m', required: false)
50 util = cc.find_library('util', required: false)
53 if targetos == 'windows'
54 socket = cc.find_library('ws2_32')
56 win = import('windows')
57 version_res = win.compile_resources('version.rc',
58 depend_files: files('pc-bios/qemu-nsis.ico'),
59 include_directories: include_directories('.'))
61 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
62 link_args: config_host['GLIB_LIBS'].split())
64 if 'CONFIG_GIO' in config_host
65 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
66 link_args: config_host['GIO_LIBS'].split())
69 if 'CONFIG_TRACE_UST' in config_host
70 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
73 if 'CONFIG_TRACE_UST' in config_host
74 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
77 if 'CONFIG_NETTLE' in config_host
78 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
79 link_args: config_host['NETTLE_LIBS'].split())
82 if 'CONFIG_GNUTLS' in config_host
83 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
84 link_args: config_host['GNUTLS_LIBS'].split())
87 target_dirs = config_host['TARGET_DIRS'].split()
90 foreach target : target_dirs
91 have_user = have_user or target.endswith('-user')
92 have_system = have_system or target.endswith('-softmmu')
94 have_tools = 'CONFIG_TOOLS' in config_host
95 have_block = have_system or have_tools
99 qapi_gen = find_program('scripts/qapi-gen.py')
100 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
101 meson.source_root() / 'scripts/qapi/commands.py',
102 meson.source_root() / 'scripts/qapi/common.py',
103 meson.source_root() / 'scripts/qapi/doc.py',
104 meson.source_root() / 'scripts/qapi/error.py',
105 meson.source_root() / 'scripts/qapi/events.py',
106 meson.source_root() / 'scripts/qapi/expr.py',
107 meson.source_root() / 'scripts/qapi/gen.py',
108 meson.source_root() / 'scripts/qapi/introspect.py',
109 meson.source_root() / 'scripts/qapi/parser.py',
110 meson.source_root() / 'scripts/qapi/schema.py',
111 meson.source_root() / 'scripts/qapi/source.py',
112 meson.source_root() / 'scripts/qapi/types.py',
113 meson.source_root() / 'scripts/qapi/visit.py',
114 meson.source_root() / 'scripts/qapi/common.py',
115 meson.source_root() / 'scripts/qapi/doc.py',
116 meson.source_root() / 'scripts/qapi-gen.py'
120 python, files('scripts/tracetool.py'),
121 '--backend=' + config_host['TRACE_BACKENDS']
124 # Collect sourcesets.
126 util_ss = ss.source_set()
127 stub_ss = ss.source_set()
128 trace_ss = ss.source_set()
134 trace_events_subdirs = [
141 trace_events_subdirs += [ 'linux-user' ]
144 trace_events_subdirs += [
153 trace_events_subdirs += [
164 'hw/block/dataplane',
209 trace_events_subdirs += [
232 subdir('storage-daemon')
234 # Build targets from sourcesets
236 stub_ss = stub_ss.apply(config_host, strict: false)
238 util_ss.add_all(trace_ss)
239 util_ss = util_ss.apply(config_host, strict: false)
240 libqemuutil = static_library('qemuutil',
241 sources: util_ss.sources() + stub_ss.sources() + genh,
242 dependencies: [util_ss.dependencies(), m, glib, socket])
243 qemuutil = declare_dependency(link_with: libqemuutil,
244 sources: genh + version_res)
246 # Other build targets
249 if 'CONFIG_VHOST_USER' in config_host
250 subdir('contrib/libvhost-user')
255 summary_info += {'Install prefix': config_host['prefix']}
256 summary_info += {'BIOS directory': config_host['qemu_datadir']}
257 summary_info += {'firmware path': config_host['qemu_firmwarepath']}
258 summary_info += {'binary directory': config_host['bindir']}
259 summary_info += {'library directory': config_host['libdir']}
260 summary_info += {'module directory': config_host['qemu_moddir']}
261 summary_info += {'libexec directory': config_host['libexecdir']}
262 summary_info += {'include directory': config_host['includedir']}
263 summary_info += {'config directory': config_host['sysconfdir']}
264 if targetos != 'windows'
265 summary_info += {'local state directory': config_host['qemu_localstatedir']}
266 summary_info += {'Manual directory': config_host['mandir']}
268 summary_info += {'local state directory': 'queried at runtime'}
270 summary_info += {'Build directory': meson.current_build_dir()}
271 summary_info += {'Source path': meson.current_source_dir()}
272 summary_info += {'GIT binary': config_host['GIT']}
273 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
274 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
275 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
276 if link_language == 'cpp'
277 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
279 summary_info += {'C++ compiler': false}
281 if targetos == 'darwin'
282 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
284 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
285 summary_info += {'CFLAGS': config_host['CFLAGS']}
286 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
287 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
288 summary_info += {'make': config_host['MAKE']}
289 summary_info += {'install': config_host['INSTALL']}
290 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
291 summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
292 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
293 # TODO: add back version
294 summary_info += {'slirp support': config_host.has_key('CONFIG_SLIRP')}
295 if config_host.has_key('CONFIG_SLIRP')
296 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
298 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
299 if config_host.has_key('CONFIG_MODULES')
300 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
302 summary_info += {'host CPU': cpu}
303 summary_info += {'host endianness': build_machine.endian()}
304 summary_info += {'target list': config_host['TARGET_DIRS']}
305 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
306 summary_info += {'sparse enabled': meson.get_compiler('c').cmd_array().contains('cgcc')}
307 summary_info += {'strip binaries': get_option('strip')}
308 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
309 summary_info += {'static build': config_host.has_key('CONFIG_TOOLS')}
310 if targetos == 'darwin'
311 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
313 # TODO: add back version
314 summary_info += {'SDL support': config_host.has_key('CONFIG_SDL')}
315 summary_info += {'SDL image support': config_host.has_key('CONFIG_SDL_IMAGE')}
316 # TODO: add back version
317 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
318 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
319 # TODO: add back version
320 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
321 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
322 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
323 # TODO: add back version
324 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
325 if config_host.has_key('CONFIG_GCRYPT')
326 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
327 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
329 # TODO: add back version
330 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
331 if config_host.has_key('CONFIG_NETTLE')
332 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
334 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
335 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
336 summary_info += {'iconv support': config_host.has_key('CONFIG_ICONV')}
337 summary_info += {'curses support': config_host.has_key('CONFIG_CURSES')}
338 # TODO: add back version
339 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
340 summary_info += {'curl support': config_host.has_key('CONFIG_CURL')}
341 summary_info += {'mingw32 support': targetos == 'windows'}
342 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
343 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
344 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
345 summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
346 summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
347 summary_info += {'VNC support': config_host.has_key('CONFIG_VNC')}
348 if config_host.has_key('CONFIG_VNC')
349 summary_info += {'VNC SASL support': config_host.has_key('CONFIG_VNC_SASL')}
350 summary_info += {'VNC JPEG support': config_host.has_key('CONFIG_VNC_JPEG')}
351 summary_info += {'VNC PNG support': config_host.has_key('CONFIG_VNC_PNG')}
353 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
354 if config_host.has_key('CONFIG_XEN_BACKEND')
355 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
357 summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')}
358 summary_info += {'Documentation': config_host.has_key('BUILD_DOCS')}
359 summary_info += {'PIE': get_option('b_pie')}
360 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
361 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
362 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
363 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
364 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
365 summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')}
366 # TODO: add back KVM/HAX/HVF/WHPX/TCG
367 #summary_info += {'KVM support': have_kvm'}
368 #summary_info += {'HAX support': have_hax'}
369 #summary_info += {'HVF support': have_hvf'}
370 #summary_info += {'WHPX support': have_whpx'}
371 #summary_info += {'TCG support': have_tcg'}
372 #if get_option('tcg')
373 # summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
374 # summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
376 summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
377 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
378 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
379 summary_info += {'fdt support': config_host.has_key('CONFIG_FDT')}
380 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
381 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
382 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
383 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
384 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
385 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
386 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
387 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
388 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
389 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
390 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
391 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
392 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
393 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
394 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
395 if config_host['TRACE_BACKENDS'].split().contains('simple')
396 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
398 # TODO: add back protocol and server version
399 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
400 summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')}
401 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
402 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
403 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
404 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
405 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
406 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
407 summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')}
408 summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')}
409 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
410 if targetos == 'windows'
411 if 'WIN_SDK' in config_host
412 summary_info += {'Windows SDK': config_host['WIN_SDK']}
414 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
415 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
416 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
418 summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
419 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
420 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
421 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
422 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
423 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
424 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
425 summary_info += {'gcov': get_option('b_coverage')}
426 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
427 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
428 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
429 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
430 summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')}
431 summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')}
432 summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')}
433 summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
434 summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
435 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
436 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
437 summary_info += {'tcmalloc support': config_host.has_key('CONFIG_TCMALLOC')}
438 summary_info += {'jemalloc support': config_host.has_key('CONFIG_JEMALLOC')}
439 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
440 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
441 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
442 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
443 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
444 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
445 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
446 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
447 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
448 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
449 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
450 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
451 summary_info += {'capstone': config_host.has_key('CONFIG_CAPSTONE')}
452 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
453 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
454 summary_info += {'libudev': config_host.has_key('CONFIG_LIBUDEV')}
455 summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
456 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
457 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
458 if config_host.has_key('HAVE_GDB_BIN')
459 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
461 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
462 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
463 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
464 summary(summary_info, bool_yn: true)
466 if not supported_cpus.contains(cpu)
468 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
470 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
471 message('The QEMU project intends to remove support for this host CPU in')
472 message('a future release if nobody volunteers to maintain it and to')
473 message('provide a build host for our continuous integration setup.')
474 message('configure has succeeded and you can continue to build, but')
475 message('if you care about QEMU on this platform you should contact')
476 message('us upstream at qemu-devel@nongnu.org.')
479 if not supported_oses.contains(targetos)
481 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
483 message('Host OS ' + targetos + 'support is not currently maintained.')
484 message('The QEMU project intends to remove support for this host OS in')
485 message('a future release if nobody volunteers to maintain it and to')
486 message('provide a build host for our continuous integration setup.')
487 message('configure has succeeded and you can continue to build, but')
488 message('if you care about QEMU on this platform you should contact')
489 message('us upstream at qemu-devel@nongnu.org.')