project('qemu', ['c'], meson_version: '>=0.55.0',
- default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11',
- 'b_colorout=auto'],
+ default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_colorout=auto'] +
+ (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
not_found = dependency('', required: false)
error('qemu_suffix cannot start with a /')
endif
+qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
+qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
+
+qemu_desktopdir = get_option('datadir') / 'applications'
+qemu_icondir = get_option('datadir') / 'icons'
+
config_host_data = configuration_data()
genh = []
endif
accelerator_targets = { 'CONFIG_KVM': kvm_targets }
+if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
+ # i368 emulator provides xenpv machine type for multiple architectures
+ accelerator_targets += {
+ 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
+ }
+endif
if cpu in ['x86', 'x86_64']
accelerator_targets += {
'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
- 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
'CONFIG_HVF': ['x86_64-softmmu'],
'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
}
have_xen_pci_passthrough = false
endif
if not get_option('whpx').disabled() and targetos == 'windows'
- if get_option('whpx').enabled() and cpu != 'x86_64'
+ if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
error('WHPX requires 64-bit host')
elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
iconv = not_found
curses = not_found
if have_system and not get_option('curses').disabled()
- if not get_option('iconv').disabled()
- libiconv = cc.find_library('iconv',
- required: false,
- static: enable_static)
- if cc.links('''
- #include <iconv.h>
- int main(void) {
- iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
- return conv != (iconv_t) -1;
- }''', dependencies: [libiconv])
- iconv = declare_dependency(dependencies: [libiconv])
+ curses_test = '''
+ #include <locale.h>
+ #include <curses.h>
+ #include <wchar.h>
+ int main(void) {
+ wchar_t wch = L'w';
+ setlocale(LC_ALL, "");
+ resize_term(0, 0);
+ addwstr(L"wide chars\n");
+ addnwstr(&wch, 1);
+ add_wch(WACS_DEGREE);
+ return 0;
+ }'''
+
+ curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
+ foreach curses_dep : curses_dep_list
+ if not curses.found()
+ curses = dependency(curses_dep,
+ required: false,
+ method: 'pkg-config',
+ static: enable_static)
+ endif
+ endforeach
+ msg = get_option('curses').enabled() ? 'curses library not found' : ''
+ if curses.found()
+ if cc.links(curses_test, dependencies: [curses])
+ curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR', dependencies: [curses])
+ else
+ msg = 'curses package not usable'
+ curses = not_found
endif
endif
- if get_option('iconv').enabled() and not iconv.found()
- error('Cannot detect iconv API')
- endif
- if iconv.found()
- curses_libname_list = ['ncursesw', 'ncurses', 'cursesw', 'pdcurses']
- curses_test = '''
- #include <locale.h>
- #include <curses.h>
- #include <wchar.h>
- int main(void) {
- wchar_t wch = L'w';
- setlocale(LC_ALL, "");
- resize_term(0, 0);
- addwstr(L"wide chars\n");
- addnwstr(&wch, 1);
- add_wch(WACS_DEGREE);
- return 0;
- }'''
- foreach curses_libname : curses_libname_list
- libcurses = dependency(curses_libname,
- required: false,
- method: 'pkg-config',
- static: enable_static)
-
- if not libcurses.found()
- dirs = ['/usr/include/ncursesw']
- if targetos == 'windows'
- dirs = []
- endif
+ if not curses.found()
+ curses_compile_args = ['-DNCURSES_WIDECHAR']
+ has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
+ if targetos != 'windows' and not has_curses_h
+ message('Trying with /usr/include/ncursesw')
+ curses_compile_args += ['-I/usr/include/ncursesw']
+ has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
+ endif
+ if has_curses_h
+ curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
+ foreach curses_libname : curses_libname_list
libcurses = cc.find_library(curses_libname,
required: false,
- dirs: dirs,
static: enable_static)
- endif
- if libcurses.found()
- if cc.links(curses_test, dependencies: [libcurses])
- curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR', dependencies: [libcurses])
- break
+ if libcurses.found()
+ if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
+ curses = declare_dependency(compile_args: curses_compile_args,
+ dependencies: [libcurses])
+ break
+ else
+ msg = 'curses library not usable'
+ endif
endif
+ endforeach
+ endif
+ endif
+ if not get_option('iconv').disabled()
+ foreach link_args : [ ['-liconv'], [] ]
+ # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
+ # We need to use libiconv if available because mixing libiconv's headers with
+ # the system libc does not work.
+ # However, without adding glib to the dependencies -L/usr/local/lib will not be
+ # included in the command line and libiconv will not be found.
+ if cc.links('''
+ #include <iconv.h>
+ int main(void) {
+ iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
+ return conv != (iconv_t) -1;
+ }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
+ iconv = declare_dependency(link_args: link_args, dependencies: glib)
+ break
endif
endforeach
endif
- if not curses.found()
- if iconv.found()
- if get_option('curses').enabled()
- error('Cannot find curses')
- endif
- elif get_option('curses').enabled()
- error('iconv required for curses UI but not available')
+ if curses.found() and not iconv.found()
+ if get_option('iconv').enabled()
+ error('iconv not available')
+ endif
+ msg = 'iconv required for curses UI but not available'
+ curses = not_found
+ endif
+ if not curses.found() and msg != ''
+ if get_option('curses').enabled()
+ error(msg)
else
- warning('iconv required for curses UI but not available, disabling')
+ warning(msg + ', disabling')
endif
endif
endif
vnc = declare_dependency() # dummy dependency
png = dependency('libpng', required: get_option('vnc_png'),
method: 'pkg-config', static: enable_static)
- jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
- required: get_option('vnc_jpeg'),
- static: enable_static)
+ jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
+ method: 'pkg-config', static: enable_static)
sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
required: get_option('vnc_sasl'),
static: enable_static)
endif
endif
+# Check whether the glibc provides statx()
+
+statx_test = '''
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #include <sys/stat.h>
+ int main(void) {
+ struct statx statxbuf;
+ statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
+ return 0;
+ }'''
+
+has_statx = cc.links(statx_test)
+
+have_vhost_user_blk_server = (targetos == 'linux' and
+ 'CONFIG_VHOST_USER' in config_host)
+
+if get_option('vhost_user_blk_server').enabled()
+ if targetos != 'linux'
+ error('vhost_user_blk_server requires linux')
+ elif 'CONFIG_VHOST_USER' not in config_host
+ error('vhost_user_blk_server requires vhost-user support')
+ endif
+elif get_option('vhost_user_blk_server').disabled() or not have_system
+ have_vhost_user_blk_server = false
+endif
+
+if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
+ error('Cannot enable fuse-lseek while fuse is disabled')
+endif
+
+fuse = dependency('fuse3', required: get_option('fuse'),
+ version: '>=3.1', method: 'pkg-config',
+ static: enable_static)
+
+fuse_lseek = not_found
+if not get_option('fuse_lseek').disabled()
+ if fuse.version().version_compare('>=3.8')
+ # Dummy dependency
+ fuse_lseek = declare_dependency()
+ elif get_option('fuse_lseek').enabled()
+ if fuse.found()
+ error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
+ else
+ error('fuse-lseek requires libfuse, which was not found')
+ endif
+ endif
+endif
+
#################
# config-host.h #
#################
+config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
+config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
+config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
+config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
+config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
+config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
+config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
+config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
+config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
+config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
+config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
+config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
+
config_host_data.set('CONFIG_COCOA', cocoa.found())
config_host_data.set('CONFIG_LIBUDEV', libudev.found())
config_host_data.set('CONFIG_MPATH', mpathpersist.found())
config_host_data.set('CONFIG_CURSES', curses.found())
config_host_data.set('CONFIG_SDL', sdl.found())
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
+config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
config_host_data.set('CONFIG_VNC', vnc.found())
config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
config_host_data.set('CONFIG_VNC_PNG', png.found())
config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
config_host_data.set('CONFIG_GETTID', has_gettid)
config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
+config_host_data.set('CONFIG_STATX', has_statx)
+config_host_data.set('CONFIG_FUSE', fuse.found())
+config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
+config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
+
ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
-strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'bindir', 'prefix', 'qemu_confdir', 'qemu_datadir',
- 'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
- 'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath', 'sysconfdir']
+strings = ['HOST_DSOSUF', 'CONFIG_IASL']
foreach k, v: config_host
if ignored.contains(k)
# do nothing
'hw/misc',
'hw/misc/macio',
'hw/net',
+ 'hw/net/can',
'hw/nvram',
'hw/pci',
'hw/pci-host',
vhost_user = not_found
if 'CONFIG_VHOST_USER' in config_host
- subdir('contrib/libvhost-user')
+ libvhost_user = subproject('libvhost-user')
+ vhost_user = libvhost_user.get_variable('vhost_user_dep')
endif
subdir('qapi')
name_prefix: '',
link_whole: m,
install: true,
- install_dir: config_host['qemu_moddir'])
+ install_dir: qemu_moddir)
endforeach
softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
output: exe['name'] + stp['ext'],
capture: true,
install: stp['install'],
- install_dir: qemu_datadir / '../systemtap/tapset',
+ install_dir: get_option('datadir') / 'systemtap/tapset',
command: [
tracetool, '--group=all', '--format=' + stp['fmt'],
'--binary=' + stp['bin'],
'@OUTPUT@',
get_option('prefix'),
meson.current_source_dir(),
- host_machine.cpu_family(),
+ host_machine.cpu(),
'--',
'-DDISPLAYVERSION=' + meson.project_version(),
]
#########################
summary_info = {}
-summary_info += {'Install prefix': config_host['prefix']}
-summary_info += {'BIOS directory': config_host['qemu_datadir']}
-summary_info += {'firmware path': config_host['qemu_firmwarepath']}
-summary_info += {'binary directory': config_host['bindir']}
-summary_info += {'library directory': config_host['libdir']}
-summary_info += {'module directory': config_host['qemu_moddir']}
-summary_info += {'libexec directory': config_host['libexecdir']}
-summary_info += {'include directory': config_host['includedir']}
-summary_info += {'config directory': config_host['sysconfdir']}
+summary_info += {'Install prefix': get_option('prefix')}
+summary_info += {'BIOS directory': qemu_datadir}
+summary_info += {'firmware path': get_option('qemu_firmwarepath')}
+summary_info += {'binary directory': get_option('bindir')}
+summary_info += {'library directory': get_option('libdir')}
+summary_info += {'module directory': qemu_moddir}
+summary_info += {'libexec directory': get_option('libexecdir')}
+summary_info += {'include directory': get_option('includedir')}
+summary_info += {'config directory': get_option('sysconfdir')}
if targetos != 'windows'
- summary_info += {'local state directory': config_host['qemu_localstatedir']}
+ summary_info += {'local state directory': get_option('localstatedir')}
summary_info += {'Manual directory': get_option('mandir')}
else
summary_info += {'local state directory': 'queried at runtime'}
summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
+summary_info += {'build virtiofs daemon': have_virtiofsd}
summary_info += {'Multipath support': mpathpersist.found()}
summary_info += {'VNC support': vnc.found()}
if vnc.found()
summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
-summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')}
+summary_info += {'Install blobs': get_option('install_blobs')}
summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
+summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
-summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
+summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
+summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
+summary_info += {'FUSE exports': fuse.found()}
+summary_info += {'FUSE lseek': fuse_lseek.found()}
summary(summary_info, bool_yn: true)
if not supported_cpus.contains(cpu)