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