47b30835e4
Environment variables like CFLAGS are easy to accidentally change. Meson warns if that happens, but in a project with a lot of configuration that is easy to lose. It is also surprising behavior since meson caches -D options and remembers those on reconfiguration (which we rely on, since configure options become -D options). By placing the user-provided CFLAGS, CXXFLAGS and LDFLAGS in the cross file, we at least get consistent behavior. These environment variables are still ugly and not really recommended, but there are distros that rely on them. For the gory details, refer to https://github.com/mesonbuild/meson/issues/4664. Tested-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20200923092617.1593722-5-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1990 lines
72 KiB
Meson
1990 lines
72 KiB
Meson
project('qemu', ['c'], meson_version: '>=0.55.0',
|
|
default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11',
|
|
'b_colorout=auto'],
|
|
version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
|
|
|
|
not_found = dependency('', required: false)
|
|
if meson.version().version_compare('>=0.56.0')
|
|
keyval = import('keyval')
|
|
else
|
|
keyval = import('unstable-keyval')
|
|
endif
|
|
ss = import('sourceset')
|
|
fs = import('fs')
|
|
|
|
sh = find_program('sh')
|
|
cc = meson.get_compiler('c')
|
|
config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
|
|
enable_modules = 'CONFIG_MODULES' in config_host
|
|
enable_static = 'CONFIG_STATIC' in config_host
|
|
build_docs = 'BUILD_DOCS' in config_host
|
|
|
|
if get_option('qemu_suffix').startswith('/')
|
|
error('qemu_suffix cannot start with a /')
|
|
endif
|
|
|
|
qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
|
|
qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
|
|
config_host_data = configuration_data()
|
|
genh = []
|
|
|
|
target_dirs = config_host['TARGET_DIRS'].split()
|
|
have_user = false
|
|
have_system = false
|
|
foreach target : target_dirs
|
|
have_user = have_user or target.endswith('-user')
|
|
have_system = have_system or target.endswith('-softmmu')
|
|
endforeach
|
|
have_tools = 'CONFIG_TOOLS' in config_host
|
|
have_block = have_system or have_tools
|
|
|
|
python = import('python').find_installation()
|
|
|
|
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
|
|
supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
|
|
'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
|
|
|
|
cpu = host_machine.cpu_family()
|
|
targetos = host_machine.system()
|
|
|
|
configure_file(input: files('scripts/ninjatool.py'),
|
|
output: 'ninjatool',
|
|
configuration: config_host)
|
|
|
|
if cpu in ['x86', 'x86_64']
|
|
kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
|
|
elif cpu == 'aarch64'
|
|
kvm_targets = ['aarch64-softmmu']
|
|
elif cpu == 's390x'
|
|
kvm_targets = ['s390x-softmmu']
|
|
elif cpu in ['ppc', 'ppc64']
|
|
kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
|
|
else
|
|
kvm_targets = []
|
|
endif
|
|
|
|
accelerator_targets = { 'CONFIG_KVM': kvm_targets }
|
|
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'],
|
|
}
|
|
endif
|
|
|
|
##################
|
|
# Compiler flags #
|
|
##################
|
|
|
|
# Specify linker-script with add_project_link_arguments so that it is not placed
|
|
# within a linker --start-group/--end-group pair
|
|
if 'CONFIG_FUZZ' in config_host
|
|
add_project_link_arguments(['-Wl,-T,',
|
|
(meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
|
|
native: false, language: ['c', 'cpp', 'objc'])
|
|
endif
|
|
|
|
add_project_arguments(config_host['QEMU_CFLAGS'].split(),
|
|
native: false, language: ['c', 'objc'])
|
|
add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
|
|
native: false, language: 'cpp')
|
|
add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
|
|
native: false, language: ['c', 'cpp', 'objc'])
|
|
add_project_arguments(config_host['QEMU_INCLUDES'].split(),
|
|
language: ['c', 'cpp', 'objc'])
|
|
|
|
|
|
link_language = meson.get_external_property('link_language', 'cpp')
|
|
if link_language == 'cpp'
|
|
add_languages('cpp', required: true, native: false)
|
|
endif
|
|
if host_machine.system() == 'darwin'
|
|
add_languages('objc', required: false, native: false)
|
|
endif
|
|
|
|
sparse = find_program('cgcc', required: get_option('sparse'))
|
|
if sparse.found()
|
|
run_target('sparse',
|
|
command: [find_program('scripts/check_sparse.py'),
|
|
'compile_commands.json', sparse.full_path(), '-Wbitwise',
|
|
'-Wno-transparent-union', '-Wno-old-initializer',
|
|
'-Wno-non-pointer-null'])
|
|
endif
|
|
|
|
###########################################
|
|
# Target-specific checks and dependencies #
|
|
###########################################
|
|
|
|
if targetos != 'linux' and get_option('mpath').enabled()
|
|
error('Multipath is supported only on Linux')
|
|
endif
|
|
|
|
m = cc.find_library('m', required: false)
|
|
util = cc.find_library('util', required: false)
|
|
winmm = []
|
|
socket = []
|
|
version_res = []
|
|
coref = []
|
|
iokit = []
|
|
emulator_link_args = []
|
|
cocoa = not_found
|
|
hvf = not_found
|
|
if targetos == 'windows'
|
|
socket = cc.find_library('ws2_32')
|
|
winmm = cc.find_library('winmm')
|
|
|
|
win = import('windows')
|
|
version_res = win.compile_resources('version.rc',
|
|
depend_files: files('pc-bios/qemu-nsis.ico'),
|
|
include_directories: include_directories('.'))
|
|
elif targetos == 'darwin'
|
|
coref = dependency('appleframeworks', modules: 'CoreFoundation')
|
|
iokit = dependency('appleframeworks', modules: 'IOKit')
|
|
cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
|
|
elif targetos == 'sunos'
|
|
socket = [cc.find_library('socket'),
|
|
cc.find_library('nsl'),
|
|
cc.find_library('resolv')]
|
|
elif targetos == 'haiku'
|
|
socket = [cc.find_library('posix_error_mapper'),
|
|
cc.find_library('network'),
|
|
cc.find_library('bsd')]
|
|
elif targetos == 'openbsd'
|
|
if not get_option('tcg').disabled() and target_dirs.length() > 0
|
|
# Disable OpenBSD W^X if available
|
|
emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
|
|
endif
|
|
endif
|
|
|
|
accelerators = []
|
|
if not get_option('kvm').disabled() and targetos == 'linux'
|
|
accelerators += 'CONFIG_KVM'
|
|
endif
|
|
if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
|
|
accelerators += 'CONFIG_XEN'
|
|
have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
|
|
else
|
|
have_xen_pci_passthrough = false
|
|
endif
|
|
if not get_option('whpx').disabled() and targetos == 'windows'
|
|
if get_option('whpx').enabled() and 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'))
|
|
accelerators += 'CONFIG_WHPX'
|
|
endif
|
|
endif
|
|
if not get_option('hvf').disabled()
|
|
hvf = dependency('appleframeworks', modules: 'Hypervisor',
|
|
required: get_option('hvf'))
|
|
if hvf.found()
|
|
accelerators += 'CONFIG_HVF'
|
|
endif
|
|
endif
|
|
if not get_option('hax').disabled()
|
|
if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
|
|
accelerators += 'CONFIG_HAX'
|
|
endif
|
|
endif
|
|
if not get_option('tcg').disabled()
|
|
if cpu not in supported_cpus
|
|
if 'CONFIG_TCG_INTERPRETER' in config_host
|
|
warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
|
|
else
|
|
error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
|
|
endif
|
|
endif
|
|
accelerators += 'CONFIG_TCG'
|
|
config_host += { 'CONFIG_TCG': 'y' }
|
|
endif
|
|
|
|
if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
|
|
error('KVM not available on this platform')
|
|
endif
|
|
if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
|
|
error('HVF not available on this platform')
|
|
endif
|
|
if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
|
|
error('WHPX not available on this platform')
|
|
endif
|
|
if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
|
|
if 'CONFIG_XEN' in accelerators
|
|
error('Xen PCI passthrough not available on this platform')
|
|
else
|
|
error('Xen PCI passthrough requested but Xen not enabled')
|
|
endif
|
|
endif
|
|
if not cocoa.found() and get_option('cocoa').enabled()
|
|
error('Cocoa not available on this platform')
|
|
endif
|
|
|
|
################
|
|
# Dependencies #
|
|
################
|
|
|
|
# The path to glib.h is added to all compilation commands. This was
|
|
# grandfathered in from the QEMU Makefiles.
|
|
add_project_arguments(config_host['GLIB_CFLAGS'].split(),
|
|
native: false, language: ['c', 'cpp', 'objc'])
|
|
glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
|
|
gio = not_found
|
|
if 'CONFIG_GIO' in config_host
|
|
gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
|
|
link_args: config_host['GIO_LIBS'].split())
|
|
endif
|
|
lttng = not_found
|
|
if 'CONFIG_TRACE_UST' in config_host
|
|
lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
|
|
endif
|
|
urcubp = not_found
|
|
if 'CONFIG_TRACE_UST' in config_host
|
|
urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
|
|
endif
|
|
gcrypt = not_found
|
|
if 'CONFIG_GCRYPT' in config_host
|
|
gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
|
|
link_args: config_host['GCRYPT_LIBS'].split())
|
|
endif
|
|
nettle = not_found
|
|
if 'CONFIG_NETTLE' in config_host
|
|
nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
|
|
link_args: config_host['NETTLE_LIBS'].split())
|
|
endif
|
|
gnutls = not_found
|
|
if 'CONFIG_GNUTLS' in config_host
|
|
gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
|
|
link_args: config_host['GNUTLS_LIBS'].split())
|
|
endif
|
|
pixman = not_found
|
|
if have_system or have_tools
|
|
pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
|
|
method: 'pkg-config', static: enable_static)
|
|
endif
|
|
pam = not_found
|
|
if 'CONFIG_AUTH_PAM' in config_host
|
|
pam = cc.find_library('pam')
|
|
endif
|
|
libaio = cc.find_library('aio', required: false)
|
|
zlib = dependency('zlib', required: true, static: enable_static)
|
|
linux_io_uring = not_found
|
|
if 'CONFIG_LINUX_IO_URING' in config_host
|
|
linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
|
|
link_args: config_host['LINUX_IO_URING_LIBS'].split())
|
|
endif
|
|
libxml2 = not_found
|
|
if 'CONFIG_LIBXML2' in config_host
|
|
libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
|
|
link_args: config_host['LIBXML2_LIBS'].split())
|
|
endif
|
|
libnfs = not_found
|
|
if 'CONFIG_LIBNFS' in config_host
|
|
libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
|
|
endif
|
|
libattr = not_found
|
|
if 'CONFIG_ATTR' in config_host
|
|
libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
|
|
endif
|
|
seccomp = not_found
|
|
if 'CONFIG_SECCOMP' in config_host
|
|
seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
|
|
link_args: config_host['SECCOMP_LIBS'].split())
|
|
endif
|
|
libcap_ng = not_found
|
|
if 'CONFIG_LIBCAP_NG' in config_host
|
|
libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
|
|
endif
|
|
if get_option('xkbcommon').auto() and not have_system and not have_tools
|
|
xkbcommon = not_found
|
|
else
|
|
xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
|
|
method: 'pkg-config', static: enable_static)
|
|
endif
|
|
vde = not_found
|
|
if config_host.has_key('CONFIG_VDE')
|
|
vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
|
|
endif
|
|
pulse = not_found
|
|
if 'CONFIG_LIBPULSE' in config_host
|
|
pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
|
|
link_args: config_host['PULSE_LIBS'].split())
|
|
endif
|
|
alsa = not_found
|
|
if 'CONFIG_ALSA' in config_host
|
|
alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
|
|
link_args: config_host['ALSA_LIBS'].split())
|
|
endif
|
|
jack = not_found
|
|
if 'CONFIG_LIBJACK' in config_host
|
|
jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
|
|
endif
|
|
spice = not_found
|
|
if 'CONFIG_SPICE' in config_host
|
|
spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
|
|
link_args: config_host['SPICE_LIBS'].split())
|
|
endif
|
|
rt = cc.find_library('rt', required: false)
|
|
libdl = not_found
|
|
if 'CONFIG_PLUGIN' in config_host
|
|
libdl = cc.find_library('dl', required: true)
|
|
endif
|
|
libiscsi = not_found
|
|
if 'CONFIG_LIBISCSI' in config_host
|
|
libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
|
|
link_args: config_host['LIBISCSI_LIBS'].split())
|
|
endif
|
|
zstd = not_found
|
|
if 'CONFIG_ZSTD' in config_host
|
|
zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
|
|
link_args: config_host['ZSTD_LIBS'].split())
|
|
endif
|
|
gbm = not_found
|
|
if 'CONFIG_GBM' in config_host
|
|
gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
|
|
link_args: config_host['GBM_LIBS'].split())
|
|
endif
|
|
virgl = not_found
|
|
if 'CONFIG_VIRGL' in config_host
|
|
virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
|
|
link_args: config_host['VIRGL_LIBS'].split())
|
|
endif
|
|
curl = not_found
|
|
if 'CONFIG_CURL' in config_host
|
|
curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
|
|
link_args: config_host['CURL_LIBS'].split())
|
|
endif
|
|
libudev = not_found
|
|
if targetos == 'linux' and (have_system or have_tools)
|
|
libudev = dependency('libudev',
|
|
required: get_option('mpath').enabled(),
|
|
static: enable_static)
|
|
endif
|
|
|
|
mpathpersist = not_found
|
|
mpathpersist_new_api = false
|
|
if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
|
|
mpath_test_source_new = '''
|
|
#include <libudev.h>
|
|
#include <mpath_persist.h>
|
|
unsigned mpath_mx_alloc_len = 1024;
|
|
int logsink;
|
|
static struct config *multipath_conf;
|
|
extern struct udev *udev;
|
|
extern struct config *get_multipath_config(void);
|
|
extern void put_multipath_config(struct config *conf);
|
|
struct udev *udev;
|
|
struct config *get_multipath_config(void) { return multipath_conf; }
|
|
void put_multipath_config(struct config *conf) { }
|
|
int main(void) {
|
|
udev = udev_new();
|
|
multipath_conf = mpath_lib_init();
|
|
return 0;
|
|
}'''
|
|
mpath_test_source_old = '''
|
|
#include <libudev.h>
|
|
#include <mpath_persist.h>
|
|
unsigned mpath_mx_alloc_len = 1024;
|
|
int logsink;
|
|
int main(void) {
|
|
struct udev *udev = udev_new();
|
|
mpath_lib_init(udev);
|
|
return 0;
|
|
}'''
|
|
mpathlibs = [libudev]
|
|
if enable_static
|
|
mpathlibs += cc.find_library('devmapper',
|
|
required: get_option('mpath'),
|
|
static: enable_static)
|
|
endif
|
|
mpathlibs += cc.find_library('multipath',
|
|
required: get_option('mpath'),
|
|
static: enable_static)
|
|
mpathlibs += cc.find_library('mpathpersist',
|
|
required: get_option('mpath'),
|
|
static: enable_static)
|
|
foreach lib: mpathlibs
|
|
if not lib.found()
|
|
mpathlibs = []
|
|
break
|
|
endif
|
|
endforeach
|
|
if mpathlibs.length() > 0
|
|
if cc.links(mpath_test_source_new, dependencies: mpathlibs)
|
|
mpathpersist = declare_dependency(dependencies: mpathlibs)
|
|
mpathpersist_new_api = true
|
|
elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
|
|
mpathpersist = declare_dependency(dependencies: mpathlibs)
|
|
else
|
|
if get_option('mpath').enabled()
|
|
error('Cannot detect libmpathpersist API')
|
|
else
|
|
warning('Cannot detect libmpathpersist API, disabling')
|
|
endif
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
brlapi = not_found
|
|
if 'CONFIG_BRLAPI' in config_host
|
|
brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
|
|
endif
|
|
|
|
sdl = not_found
|
|
if have_system
|
|
sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
|
|
sdl_image = not_found
|
|
endif
|
|
if sdl.found()
|
|
# work around 2.0.8 bug
|
|
sdl = declare_dependency(compile_args: '-Wno-undef',
|
|
dependencies: sdl)
|
|
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
|
|
method: 'pkg-config', static: enable_static)
|
|
else
|
|
if get_option('sdl_image').enabled()
|
|
error('sdl-image required, but SDL was @0@'.format(
|
|
get_option('sdl').disabled() ? 'disabled' : 'not found'))
|
|
endif
|
|
sdl_image = not_found
|
|
endif
|
|
|
|
rbd = not_found
|
|
if 'CONFIG_RBD' in config_host
|
|
rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
|
|
endif
|
|
glusterfs = not_found
|
|
if 'CONFIG_GLUSTERFS' in config_host
|
|
glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
|
|
link_args: config_host['GLUSTERFS_LIBS'].split())
|
|
endif
|
|
libssh = not_found
|
|
if 'CONFIG_LIBSSH' in config_host
|
|
libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
|
|
link_args: config_host['LIBSSH_LIBS'].split())
|
|
endif
|
|
libbzip2 = not_found
|
|
if 'CONFIG_BZIP2' in config_host
|
|
libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
|
|
endif
|
|
liblzfse = not_found
|
|
if 'CONFIG_LZFSE' in config_host
|
|
liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
|
|
endif
|
|
oss = not_found
|
|
if 'CONFIG_AUDIO_OSS' in config_host
|
|
oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
|
|
endif
|
|
dsound = not_found
|
|
if 'CONFIG_AUDIO_DSOUND' in config_host
|
|
dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
|
|
endif
|
|
coreaudio = not_found
|
|
if 'CONFIG_AUDIO_COREAUDIO' in config_host
|
|
coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
|
|
endif
|
|
opengl = not_found
|
|
if 'CONFIG_OPENGL' in config_host
|
|
opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
|
|
link_args: config_host['OPENGL_LIBS'].split())
|
|
endif
|
|
gtk = not_found
|
|
if 'CONFIG_GTK' in config_host
|
|
gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
|
|
link_args: config_host['GTK_LIBS'].split())
|
|
endif
|
|
vte = not_found
|
|
if 'CONFIG_VTE' in config_host
|
|
vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
|
|
link_args: config_host['VTE_LIBS'].split())
|
|
endif
|
|
x11 = not_found
|
|
if 'CONFIG_X11' in config_host
|
|
x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
|
|
link_args: config_host['X11_LIBS'].split())
|
|
endif
|
|
curses = not_found
|
|
if 'CONFIG_CURSES' in config_host
|
|
curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
|
|
link_args: config_host['CURSES_LIBS'].split())
|
|
endif
|
|
iconv = not_found
|
|
if 'CONFIG_ICONV' in config_host
|
|
iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
|
|
link_args: config_host['ICONV_LIBS'].split())
|
|
endif
|
|
vnc = not_found
|
|
png = not_found
|
|
jpeg = not_found
|
|
sasl = not_found
|
|
if get_option('vnc').enabled()
|
|
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)
|
|
sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
|
|
required: get_option('vnc_sasl'),
|
|
static: enable_static)
|
|
if sasl.found()
|
|
sasl = declare_dependency(dependencies: sasl,
|
|
compile_args: '-DSTRUCT_IOVEC_DEFINED')
|
|
endif
|
|
endif
|
|
snappy = not_found
|
|
if 'CONFIG_SNAPPY' in config_host
|
|
snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
|
|
endif
|
|
lzo = not_found
|
|
if 'CONFIG_LZO' in config_host
|
|
lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
|
|
endif
|
|
rdma = not_found
|
|
if 'CONFIG_RDMA' in config_host
|
|
rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
|
|
endif
|
|
numa = not_found
|
|
if 'CONFIG_NUMA' in config_host
|
|
numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
|
|
endif
|
|
xen = not_found
|
|
if 'CONFIG_XEN_BACKEND' in config_host
|
|
xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
|
|
link_args: config_host['XEN_LIBS'].split())
|
|
endif
|
|
cacard = not_found
|
|
if 'CONFIG_SMARTCARD' in config_host
|
|
cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
|
|
link_args: config_host['SMARTCARD_LIBS'].split())
|
|
endif
|
|
u2f = not_found
|
|
if have_system
|
|
u2f = dependency('u2f-emu', required: get_option('u2f'),
|
|
method: 'pkg-config',
|
|
static: enable_static)
|
|
endif
|
|
usbredir = not_found
|
|
if 'CONFIG_USB_REDIR' in config_host
|
|
usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
|
|
link_args: config_host['USB_REDIR_LIBS'].split())
|
|
endif
|
|
libusb = not_found
|
|
if 'CONFIG_USB_LIBUSB' in config_host
|
|
libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
|
|
link_args: config_host['LIBUSB_LIBS'].split())
|
|
endif
|
|
libpmem = not_found
|
|
if 'CONFIG_LIBPMEM' in config_host
|
|
libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
|
|
link_args: config_host['LIBPMEM_LIBS'].split())
|
|
endif
|
|
libdaxctl = not_found
|
|
if 'CONFIG_LIBDAXCTL' in config_host
|
|
libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
|
|
endif
|
|
tasn1 = not_found
|
|
if 'CONFIG_TASN1' in config_host
|
|
tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
|
|
link_args: config_host['TASN1_LIBS'].split())
|
|
endif
|
|
keyutils = dependency('libkeyutils', required: false,
|
|
method: 'pkg-config', static: enable_static)
|
|
|
|
has_gettid = cc.has_function('gettid')
|
|
|
|
# Malloc tests
|
|
|
|
malloc = []
|
|
if get_option('malloc') == 'system'
|
|
has_malloc_trim = \
|
|
not get_option('malloc_trim').disabled() and \
|
|
cc.links('''#include <malloc.h>
|
|
int main(void) { malloc_trim(0); return 0; }''')
|
|
else
|
|
has_malloc_trim = false
|
|
malloc = cc.find_library(get_option('malloc'), required: true)
|
|
endif
|
|
if not has_malloc_trim and get_option('malloc_trim').enabled()
|
|
if get_option('malloc') == 'system'
|
|
error('malloc_trim not available on this platform.')
|
|
else
|
|
error('malloc_trim not available with non-libc memory allocator')
|
|
endif
|
|
endif
|
|
|
|
# Create config-host.h
|
|
|
|
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_MPATH_NEW_API', mpathpersist_new_api)
|
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
|
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_VNC_SASL', sasl.found())
|
|
config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.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('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])
|
|
|
|
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']
|
|
foreach k, v: config_host
|
|
if ignored.contains(k)
|
|
# do nothing
|
|
elif arrays.contains(k)
|
|
if v != ''
|
|
v = '"' + '", "'.join(v.split()) + '", '
|
|
endif
|
|
config_host_data.set(k, v)
|
|
elif k == 'ARCH'
|
|
config_host_data.set('HOST_' + v.to_upper(), 1)
|
|
elif strings.contains(k)
|
|
if not k.startswith('CONFIG_')
|
|
k = 'CONFIG_' + k.to_upper()
|
|
endif
|
|
config_host_data.set_quoted(k, v)
|
|
elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
|
|
config_host_data.set(k, v == 'y' ? 1 : v)
|
|
endif
|
|
endforeach
|
|
|
|
minikconf = find_program('scripts/minikconf.py')
|
|
config_all = {}
|
|
config_all_devices = {}
|
|
config_all_disas = {}
|
|
config_devices_mak_list = []
|
|
config_devices_h = {}
|
|
config_target_h = {}
|
|
config_target_mak = {}
|
|
|
|
disassemblers = {
|
|
'alpha' : ['CONFIG_ALPHA_DIS'],
|
|
'arm' : ['CONFIG_ARM_DIS'],
|
|
'avr' : ['CONFIG_AVR_DIS'],
|
|
'cris' : ['CONFIG_CRIS_DIS'],
|
|
'hppa' : ['CONFIG_HPPA_DIS'],
|
|
'i386' : ['CONFIG_I386_DIS'],
|
|
'x86_64' : ['CONFIG_I386_DIS'],
|
|
'x32' : ['CONFIG_I386_DIS'],
|
|
'lm32' : ['CONFIG_LM32_DIS'],
|
|
'm68k' : ['CONFIG_M68K_DIS'],
|
|
'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
|
|
'mips' : ['CONFIG_MIPS_DIS'],
|
|
'moxie' : ['CONFIG_MOXIE_DIS'],
|
|
'nios2' : ['CONFIG_NIOS2_DIS'],
|
|
'or1k' : ['CONFIG_OPENRISC_DIS'],
|
|
'ppc' : ['CONFIG_PPC_DIS'],
|
|
'riscv' : ['CONFIG_RISCV_DIS'],
|
|
'rx' : ['CONFIG_RX_DIS'],
|
|
's390' : ['CONFIG_S390_DIS'],
|
|
'sh4' : ['CONFIG_SH4_DIS'],
|
|
'sparc' : ['CONFIG_SPARC_DIS'],
|
|
'xtensa' : ['CONFIG_XTENSA_DIS'],
|
|
}
|
|
if link_language == 'cpp'
|
|
disassemblers += {
|
|
'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
|
|
'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
|
|
'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
|
|
}
|
|
endif
|
|
|
|
kconfig_external_symbols = [
|
|
'CONFIG_KVM',
|
|
'CONFIG_XEN',
|
|
'CONFIG_TPM',
|
|
'CONFIG_SPICE',
|
|
'CONFIG_IVSHMEM',
|
|
'CONFIG_OPENGL',
|
|
'CONFIG_X11',
|
|
'CONFIG_VHOST_USER',
|
|
'CONFIG_VHOST_VDPA',
|
|
'CONFIG_VHOST_KERNEL',
|
|
'CONFIG_VIRTFS',
|
|
'CONFIG_LINUX',
|
|
'CONFIG_PVRDMA',
|
|
]
|
|
ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
|
|
|
|
default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
|
|
actual_target_dirs = []
|
|
fdt_required = []
|
|
foreach target : target_dirs
|
|
config_target = { 'TARGET_NAME': target.split('-')[0] }
|
|
if target.endswith('linux-user')
|
|
if targetos != 'linux'
|
|
if default_targets
|
|
continue
|
|
endif
|
|
error('Target @0@ is only available on a Linux host'.format(target))
|
|
endif
|
|
config_target += { 'CONFIG_LINUX_USER': 'y' }
|
|
elif target.endswith('bsd-user')
|
|
if 'CONFIG_BSD' not in config_host
|
|
if default_targets
|
|
continue
|
|
endif
|
|
error('Target @0@ is only available on a BSD host'.format(target))
|
|
endif
|
|
config_target += { 'CONFIG_BSD_USER': 'y' }
|
|
elif target.endswith('softmmu')
|
|
config_target += { 'CONFIG_SOFTMMU': 'y' }
|
|
endif
|
|
if target.endswith('-user')
|
|
config_target += {
|
|
'CONFIG_USER_ONLY': 'y',
|
|
'CONFIG_QEMU_INTERP_PREFIX':
|
|
config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
|
|
}
|
|
endif
|
|
|
|
have_accel = false
|
|
foreach sym: accelerators
|
|
if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
|
|
config_target += { sym: 'y' }
|
|
config_all += { sym: 'y' }
|
|
if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
|
|
config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
|
|
endif
|
|
have_accel = true
|
|
endif
|
|
endforeach
|
|
if not have_accel
|
|
if default_targets
|
|
continue
|
|
endif
|
|
error('No accelerator available for target @0@'.format(target))
|
|
endif
|
|
|
|
actual_target_dirs += target
|
|
config_target += keyval.load('default-configs/targets' / target + '.mak')
|
|
config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
|
|
|
|
if 'TARGET_NEED_FDT' in config_target
|
|
fdt_required += target
|
|
endif
|
|
|
|
# Add default keys
|
|
if 'TARGET_BASE_ARCH' not in config_target
|
|
config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
|
|
endif
|
|
if 'TARGET_ABI_DIR' not in config_target
|
|
config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
|
|
endif
|
|
|
|
foreach k, v: disassemblers
|
|
if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
|
|
foreach sym: v
|
|
config_target += { sym: 'y' }
|
|
config_all_disas += { sym: 'y' }
|
|
endforeach
|
|
endif
|
|
endforeach
|
|
|
|
config_target_data = configuration_data()
|
|
foreach k, v: config_target
|
|
if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
|
|
# do nothing
|
|
elif ignored.contains(k)
|
|
# do nothing
|
|
elif k == 'TARGET_BASE_ARCH'
|
|
# Note that TARGET_BASE_ARCH ends up in config-target.h but it is
|
|
# not used to select files from sourcesets.
|
|
config_target_data.set('TARGET_' + v.to_upper(), 1)
|
|
elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
|
|
config_target_data.set_quoted(k, v)
|
|
elif v == 'y'
|
|
config_target_data.set(k, 1)
|
|
else
|
|
config_target_data.set(k, v)
|
|
endif
|
|
endforeach
|
|
config_target_h += {target: configure_file(output: target + '-config-target.h',
|
|
configuration: config_target_data)}
|
|
|
|
if target.endswith('-softmmu')
|
|
base_kconfig = []
|
|
foreach sym : kconfig_external_symbols
|
|
if sym in config_target or sym in config_host
|
|
base_kconfig += '@0@=y'.format(sym)
|
|
endif
|
|
endforeach
|
|
|
|
config_devices_mak = target + '-config-devices.mak'
|
|
config_devices_mak = configure_file(
|
|
input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
|
|
output: config_devices_mak,
|
|
depfile: config_devices_mak + '.d',
|
|
capture: true,
|
|
command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
|
|
config_devices_mak, '@DEPFILE@', '@INPUT@',
|
|
base_kconfig])
|
|
|
|
config_devices_data = configuration_data()
|
|
config_devices = keyval.load(config_devices_mak)
|
|
foreach k, v: config_devices
|
|
config_devices_data.set(k, 1)
|
|
endforeach
|
|
config_devices_mak_list += config_devices_mak
|
|
config_devices_h += {target: configure_file(output: target + '-config-devices.h',
|
|
configuration: config_devices_data)}
|
|
config_target += config_devices
|
|
config_all_devices += config_devices
|
|
endif
|
|
config_target_mak += {target: config_target}
|
|
endforeach
|
|
target_dirs = actual_target_dirs
|
|
|
|
# This configuration is used to build files that are shared by
|
|
# multiple binaries, and then extracted out of the "common"
|
|
# static_library target.
|
|
#
|
|
# We do not use all_sources()/all_dependencies(), because it would
|
|
# build literally all source files, including devices only used by
|
|
# targets that are not built for this compilation. The CONFIG_ALL
|
|
# pseudo symbol replaces it.
|
|
|
|
config_all += config_all_devices
|
|
config_all += config_host
|
|
config_all += config_all_disas
|
|
config_all += {
|
|
'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
|
|
'CONFIG_SOFTMMU': have_system,
|
|
'CONFIG_USER_ONLY': have_user,
|
|
'CONFIG_ALL': true,
|
|
}
|
|
|
|
# Submodules
|
|
|
|
capstone = not_found
|
|
capstone_opt = get_option('capstone')
|
|
if capstone_opt in ['enabled', 'auto', 'system']
|
|
have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
|
|
capstone = dependency('capstone', version: '>=4.0',
|
|
static: enable_static, method: 'pkg-config',
|
|
required: capstone_opt == 'system' or
|
|
capstone_opt == 'enabled' and not have_internal)
|
|
if capstone.found()
|
|
capstone_opt = 'system'
|
|
elif have_internal
|
|
capstone_opt = 'internal'
|
|
else
|
|
capstone_opt = 'disabled'
|
|
endif
|
|
endif
|
|
if capstone_opt == 'internal'
|
|
capstone_data = configuration_data()
|
|
capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
|
|
|
|
capstone_files = files(
|
|
'capstone/cs.c',
|
|
'capstone/MCInst.c',
|
|
'capstone/MCInstrDesc.c',
|
|
'capstone/MCRegisterInfo.c',
|
|
'capstone/SStream.c',
|
|
'capstone/utils.c'
|
|
)
|
|
|
|
if 'CONFIG_ARM_DIS' in config_all_disas
|
|
capstone_data.set('CAPSTONE_HAS_ARM', '1')
|
|
capstone_files += files(
|
|
'capstone/arch/ARM/ARMDisassembler.c',
|
|
'capstone/arch/ARM/ARMInstPrinter.c',
|
|
'capstone/arch/ARM/ARMMapping.c',
|
|
'capstone/arch/ARM/ARMModule.c'
|
|
)
|
|
endif
|
|
|
|
# FIXME: This config entry currently depends on a c++ compiler.
|
|
# Which is needed for building libvixl, but not for capstone.
|
|
if 'CONFIG_ARM_A64_DIS' in config_all_disas
|
|
capstone_data.set('CAPSTONE_HAS_ARM64', '1')
|
|
capstone_files += files(
|
|
'capstone/arch/AArch64/AArch64BaseInfo.c',
|
|
'capstone/arch/AArch64/AArch64Disassembler.c',
|
|
'capstone/arch/AArch64/AArch64InstPrinter.c',
|
|
'capstone/arch/AArch64/AArch64Mapping.c',
|
|
'capstone/arch/AArch64/AArch64Module.c'
|
|
)
|
|
endif
|
|
|
|
if 'CONFIG_PPC_DIS' in config_all_disas
|
|
capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
|
|
capstone_files += files(
|
|
'capstone/arch/PowerPC/PPCDisassembler.c',
|
|
'capstone/arch/PowerPC/PPCInstPrinter.c',
|
|
'capstone/arch/PowerPC/PPCMapping.c',
|
|
'capstone/arch/PowerPC/PPCModule.c'
|
|
)
|
|
endif
|
|
|
|
if 'CONFIG_S390_DIS' in config_all_disas
|
|
capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
|
|
capstone_files += files(
|
|
'capstone/arch/SystemZ/SystemZDisassembler.c',
|
|
'capstone/arch/SystemZ/SystemZInstPrinter.c',
|
|
'capstone/arch/SystemZ/SystemZMapping.c',
|
|
'capstone/arch/SystemZ/SystemZModule.c',
|
|
'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
|
|
)
|
|
endif
|
|
|
|
if 'CONFIG_I386_DIS' in config_all_disas
|
|
capstone_data.set('CAPSTONE_HAS_X86', 1)
|
|
capstone_files += files(
|
|
'capstone/arch/X86/X86Disassembler.c',
|
|
'capstone/arch/X86/X86DisassemblerDecoder.c',
|
|
'capstone/arch/X86/X86ATTInstPrinter.c',
|
|
'capstone/arch/X86/X86IntelInstPrinter.c',
|
|
'capstone/arch/X86/X86InstPrinterCommon.c',
|
|
'capstone/arch/X86/X86Mapping.c',
|
|
'capstone/arch/X86/X86Module.c'
|
|
)
|
|
endif
|
|
|
|
configure_file(output: 'capstone-defs.h', configuration: capstone_data)
|
|
|
|
capstone_cargs = [
|
|
# FIXME: There does not seem to be a way to completely replace the c_args
|
|
# that come from add_project_arguments() -- we can only add to them.
|
|
# So: disable all warnings with a big hammer.
|
|
'-Wno-error', '-w',
|
|
|
|
# Include all configuration defines via a header file, which will wind up
|
|
# as a dependency on the object file, and thus changes here will result
|
|
# in a rebuild.
|
|
'-include', 'capstone-defs.h'
|
|
]
|
|
|
|
libcapstone = static_library('capstone',
|
|
sources: capstone_files,
|
|
c_args: capstone_cargs,
|
|
include_directories: 'capstone/include')
|
|
capstone = declare_dependency(link_with: libcapstone,
|
|
include_directories: 'capstone/include/capstone')
|
|
endif
|
|
|
|
slirp = not_found
|
|
slirp_opt = 'disabled'
|
|
if have_system
|
|
slirp_opt = get_option('slirp')
|
|
if slirp_opt in ['enabled', 'auto', 'system']
|
|
have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
|
|
slirp = dependency('slirp', static: enable_static,
|
|
method: 'pkg-config',
|
|
required: slirp_opt == 'system' or
|
|
slirp_opt == 'enabled' and not have_internal)
|
|
if slirp.found()
|
|
slirp_opt = 'system'
|
|
elif have_internal
|
|
slirp_opt = 'internal'
|
|
else
|
|
slirp_opt = 'disabled'
|
|
endif
|
|
endif
|
|
if slirp_opt == 'internal'
|
|
slirp_deps = []
|
|
if targetos == 'windows'
|
|
slirp_deps = cc.find_library('iphlpapi')
|
|
endif
|
|
slirp_conf = configuration_data()
|
|
slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
|
|
slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
|
|
slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
|
|
slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
|
|
slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
|
|
slirp_files = [
|
|
'slirp/src/arp_table.c',
|
|
'slirp/src/bootp.c',
|
|
'slirp/src/cksum.c',
|
|
'slirp/src/dhcpv6.c',
|
|
'slirp/src/dnssearch.c',
|
|
'slirp/src/if.c',
|
|
'slirp/src/ip6_icmp.c',
|
|
'slirp/src/ip6_input.c',
|
|
'slirp/src/ip6_output.c',
|
|
'slirp/src/ip_icmp.c',
|
|
'slirp/src/ip_input.c',
|
|
'slirp/src/ip_output.c',
|
|
'slirp/src/mbuf.c',
|
|
'slirp/src/misc.c',
|
|
'slirp/src/ncsi.c',
|
|
'slirp/src/ndp_table.c',
|
|
'slirp/src/sbuf.c',
|
|
'slirp/src/slirp.c',
|
|
'slirp/src/socket.c',
|
|
'slirp/src/state.c',
|
|
'slirp/src/stream.c',
|
|
'slirp/src/tcp_input.c',
|
|
'slirp/src/tcp_output.c',
|
|
'slirp/src/tcp_subr.c',
|
|
'slirp/src/tcp_timer.c',
|
|
'slirp/src/tftp.c',
|
|
'slirp/src/udp.c',
|
|
'slirp/src/udp6.c',
|
|
'slirp/src/util.c',
|
|
'slirp/src/version.c',
|
|
'slirp/src/vmstate.c',
|
|
]
|
|
|
|
configure_file(
|
|
input : 'slirp/src/libslirp-version.h.in',
|
|
output : 'libslirp-version.h',
|
|
configuration: slirp_conf)
|
|
|
|
slirp_inc = include_directories('slirp', 'slirp/src')
|
|
libslirp = static_library('slirp',
|
|
sources: slirp_files,
|
|
c_args: slirp_cargs,
|
|
include_directories: slirp_inc)
|
|
slirp = declare_dependency(link_with: libslirp,
|
|
dependencies: slirp_deps,
|
|
include_directories: slirp_inc)
|
|
endif
|
|
endif
|
|
|
|
fdt = not_found
|
|
fdt_opt = get_option('fdt')
|
|
if have_system
|
|
if fdt_opt in ['enabled', 'auto', 'system']
|
|
have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
|
|
fdt = cc.find_library('fdt', static: enable_static,
|
|
required: fdt_opt == 'system' or
|
|
fdt_opt == 'enabled' and not have_internal)
|
|
if fdt.found() and cc.links('''
|
|
#include <libfdt.h>
|
|
#include <libfdt_env.h>
|
|
int main(void) { fdt_check_full(NULL, 0); return 0; }''',
|
|
dependencies: fdt)
|
|
fdt_opt = 'system'
|
|
elif have_internal
|
|
fdt_opt = 'internal'
|
|
else
|
|
fdt_opt = 'disabled'
|
|
endif
|
|
endif
|
|
if fdt_opt == 'internal'
|
|
fdt_files = files(
|
|
'dtc/libfdt/fdt.c',
|
|
'dtc/libfdt/fdt_ro.c',
|
|
'dtc/libfdt/fdt_wip.c',
|
|
'dtc/libfdt/fdt_sw.c',
|
|
'dtc/libfdt/fdt_rw.c',
|
|
'dtc/libfdt/fdt_strerror.c',
|
|
'dtc/libfdt/fdt_empty_tree.c',
|
|
'dtc/libfdt/fdt_addresses.c',
|
|
'dtc/libfdt/fdt_overlay.c',
|
|
'dtc/libfdt/fdt_check.c',
|
|
)
|
|
|
|
fdt_inc = include_directories('dtc/libfdt')
|
|
libfdt = static_library('fdt',
|
|
sources: fdt_files,
|
|
include_directories: fdt_inc)
|
|
fdt = declare_dependency(link_with: libfdt,
|
|
include_directories: fdt_inc)
|
|
endif
|
|
endif
|
|
if not fdt.found() and fdt_required.length() > 0
|
|
error('fdt not available but required by targets ' + ', '.join(fdt_required))
|
|
endif
|
|
|
|
config_host_data.set('CONFIG_CAPSTONE', capstone.found())
|
|
config_host_data.set('CONFIG_FDT', fdt.found())
|
|
config_host_data.set('CONFIG_SLIRP', slirp.found())
|
|
|
|
genh += configure_file(output: 'config-host.h', configuration: config_host_data)
|
|
|
|
# Generators
|
|
|
|
hxtool = find_program('scripts/hxtool')
|
|
shaderinclude = find_program('scripts/shaderinclude.pl')
|
|
qapi_gen = find_program('scripts/qapi-gen.py')
|
|
qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
|
|
meson.source_root() / 'scripts/qapi/commands.py',
|
|
meson.source_root() / 'scripts/qapi/common.py',
|
|
meson.source_root() / 'scripts/qapi/error.py',
|
|
meson.source_root() / 'scripts/qapi/events.py',
|
|
meson.source_root() / 'scripts/qapi/expr.py',
|
|
meson.source_root() / 'scripts/qapi/gen.py',
|
|
meson.source_root() / 'scripts/qapi/introspect.py',
|
|
meson.source_root() / 'scripts/qapi/parser.py',
|
|
meson.source_root() / 'scripts/qapi/schema.py',
|
|
meson.source_root() / 'scripts/qapi/source.py',
|
|
meson.source_root() / 'scripts/qapi/types.py',
|
|
meson.source_root() / 'scripts/qapi/visit.py',
|
|
meson.source_root() / 'scripts/qapi/common.py',
|
|
meson.source_root() / 'scripts/qapi-gen.py'
|
|
]
|
|
|
|
tracetool = [
|
|
python, files('scripts/tracetool.py'),
|
|
'--backend=' + config_host['TRACE_BACKENDS']
|
|
]
|
|
|
|
qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
|
|
meson.current_source_dir(),
|
|
config_host['PKGVERSION'], meson.project_version()]
|
|
qemu_version = custom_target('qemu-version.h',
|
|
output: 'qemu-version.h',
|
|
command: qemu_version_cmd,
|
|
capture: true,
|
|
build_by_default: true,
|
|
build_always_stale: true)
|
|
genh += qemu_version
|
|
|
|
hxdep = []
|
|
hx_headers = [
|
|
['qemu-options.hx', 'qemu-options.def'],
|
|
['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
|
|
]
|
|
if have_system
|
|
hx_headers += [
|
|
['hmp-commands.hx', 'hmp-commands.h'],
|
|
['hmp-commands-info.hx', 'hmp-commands-info.h'],
|
|
]
|
|
endif
|
|
foreach d : hx_headers
|
|
hxdep += custom_target(d[1],
|
|
input: files(d[0]),
|
|
output: d[1],
|
|
capture: true,
|
|
build_by_default: true, # to be removed when added to a target
|
|
command: [hxtool, '-h', '@INPUT0@'])
|
|
endforeach
|
|
genh += hxdep
|
|
|
|
SPHINX_ARGS = [config_host['SPHINX_BUILD'],
|
|
'-Dversion=' + meson.project_version(),
|
|
'-Drelease=' + config_host['PKGVERSION']]
|
|
|
|
if get_option('werror')
|
|
SPHINX_ARGS += [ '-W' ]
|
|
endif
|
|
|
|
sphinx_extn_depends = [ meson.source_root() / 'docs/sphinx/depfile.py',
|
|
meson.source_root() / 'docs/sphinx/hxtool.py',
|
|
meson.source_root() / 'docs/sphinx/kerneldoc.py',
|
|
meson.source_root() / 'docs/sphinx/kernellog.py',
|
|
meson.source_root() / 'docs/sphinx/qapidoc.py',
|
|
meson.source_root() / 'docs/sphinx/qmp_lexer.py',
|
|
qapi_gen_depends ]
|
|
|
|
# Collect sourcesets.
|
|
|
|
util_ss = ss.source_set()
|
|
stub_ss = ss.source_set()
|
|
trace_ss = ss.source_set()
|
|
block_ss = ss.source_set()
|
|
blockdev_ss = ss.source_set()
|
|
qmp_ss = ss.source_set()
|
|
common_ss = ss.source_set()
|
|
softmmu_ss = ss.source_set()
|
|
user_ss = ss.source_set()
|
|
bsd_user_ss = ss.source_set()
|
|
linux_user_ss = ss.source_set()
|
|
specific_ss = ss.source_set()
|
|
specific_fuzz_ss = ss.source_set()
|
|
|
|
modules = {}
|
|
hw_arch = {}
|
|
target_arch = {}
|
|
target_softmmu_arch = {}
|
|
|
|
###############
|
|
# Trace files #
|
|
###############
|
|
|
|
# TODO: add each directory to the subdirs from its own meson.build, once
|
|
# we have those
|
|
trace_events_subdirs = [
|
|
'accel/kvm',
|
|
'accel/tcg',
|
|
'crypto',
|
|
'monitor',
|
|
]
|
|
if have_user
|
|
trace_events_subdirs += [ 'linux-user' ]
|
|
endif
|
|
if have_block
|
|
trace_events_subdirs += [
|
|
'authz',
|
|
'block',
|
|
'io',
|
|
'nbd',
|
|
'scsi',
|
|
]
|
|
endif
|
|
if have_system
|
|
trace_events_subdirs += [
|
|
'audio',
|
|
'backends',
|
|
'backends/tpm',
|
|
'chardev',
|
|
'hw/9pfs',
|
|
'hw/acpi',
|
|
'hw/alpha',
|
|
'hw/arm',
|
|
'hw/audio',
|
|
'hw/block',
|
|
'hw/block/dataplane',
|
|
'hw/char',
|
|
'hw/display',
|
|
'hw/dma',
|
|
'hw/hppa',
|
|
'hw/hyperv',
|
|
'hw/i2c',
|
|
'hw/i386',
|
|
'hw/i386/xen',
|
|
'hw/ide',
|
|
'hw/input',
|
|
'hw/intc',
|
|
'hw/isa',
|
|
'hw/mem',
|
|
'hw/mips',
|
|
'hw/misc',
|
|
'hw/misc/macio',
|
|
'hw/net',
|
|
'hw/nvram',
|
|
'hw/pci',
|
|
'hw/pci-host',
|
|
'hw/ppc',
|
|
'hw/rdma',
|
|
'hw/rdma/vmw',
|
|
'hw/rtc',
|
|
'hw/s390x',
|
|
'hw/scsi',
|
|
'hw/sd',
|
|
'hw/sparc',
|
|
'hw/sparc64',
|
|
'hw/ssi',
|
|
'hw/timer',
|
|
'hw/tpm',
|
|
'hw/usb',
|
|
'hw/vfio',
|
|
'hw/virtio',
|
|
'hw/watchdog',
|
|
'hw/xen',
|
|
'hw/gpio',
|
|
'migration',
|
|
'net',
|
|
'softmmu',
|
|
'ui',
|
|
]
|
|
endif
|
|
trace_events_subdirs += [
|
|
'hw/core',
|
|
'qapi',
|
|
'qom',
|
|
'target/arm',
|
|
'target/hppa',
|
|
'target/i386',
|
|
'target/mips',
|
|
'target/ppc',
|
|
'target/riscv',
|
|
'target/s390x',
|
|
'target/sparc',
|
|
'util',
|
|
]
|
|
|
|
subdir('qapi')
|
|
subdir('qobject')
|
|
subdir('stubs')
|
|
subdir('trace')
|
|
subdir('util')
|
|
subdir('qom')
|
|
subdir('authz')
|
|
subdir('crypto')
|
|
subdir('ui')
|
|
|
|
|
|
if enable_modules
|
|
libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
|
|
modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
|
|
endif
|
|
|
|
# Build targets from sourcesets
|
|
|
|
stub_ss = stub_ss.apply(config_all, strict: false)
|
|
|
|
util_ss.add_all(trace_ss)
|
|
util_ss = util_ss.apply(config_all, strict: false)
|
|
libqemuutil = static_library('qemuutil',
|
|
sources: util_ss.sources() + stub_ss.sources() + genh,
|
|
dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
|
|
qemuutil = declare_dependency(link_with: libqemuutil,
|
|
sources: genh + version_res)
|
|
|
|
decodetree = generator(find_program('scripts/decodetree.py'),
|
|
output: 'decode-@BASENAME@.c.inc',
|
|
arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
|
|
|
|
subdir('audio')
|
|
subdir('io')
|
|
subdir('chardev')
|
|
subdir('fsdev')
|
|
subdir('libdecnumber')
|
|
subdir('target')
|
|
subdir('dump')
|
|
|
|
block_ss.add(files(
|
|
'block.c',
|
|
'blockdev-nbd.c',
|
|
'blockjob.c',
|
|
'job.c',
|
|
'qemu-io-cmds.c',
|
|
))
|
|
block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
|
|
|
|
subdir('nbd')
|
|
subdir('scsi')
|
|
subdir('block')
|
|
|
|
blockdev_ss.add(files(
|
|
'blockdev.c',
|
|
'iothread.c',
|
|
'job-qmp.c',
|
|
))
|
|
|
|
# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
|
|
# os-win32.c does not
|
|
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
|
|
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
|
|
|
|
softmmu_ss.add_all(blockdev_ss)
|
|
softmmu_ss.add(files(
|
|
'bootdevice.c',
|
|
'dma-helpers.c',
|
|
'qdev-monitor.c',
|
|
), sdl)
|
|
|
|
softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
|
|
softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
|
|
softmmu_ss.add(when: fdt, if_true: files('device_tree.c'))
|
|
|
|
common_ss.add(files('cpus-common.c'))
|
|
|
|
subdir('softmmu')
|
|
|
|
common_ss.add(capstone)
|
|
specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
|
|
specific_ss.add(files('exec-vary.c'))
|
|
specific_ss.add(when: 'CONFIG_TCG', if_true: files(
|
|
'fpu/softfloat.c',
|
|
'tcg/optimize.c',
|
|
'tcg/tcg-common.c',
|
|
'tcg/tcg-op-gvec.c',
|
|
'tcg/tcg-op-vec.c',
|
|
'tcg/tcg-op.c',
|
|
'tcg/tcg.c',
|
|
))
|
|
specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
|
|
|
|
subdir('backends')
|
|
subdir('disas')
|
|
subdir('migration')
|
|
subdir('monitor')
|
|
subdir('net')
|
|
subdir('replay')
|
|
subdir('hw')
|
|
subdir('accel')
|
|
subdir('plugins')
|
|
subdir('bsd-user')
|
|
subdir('linux-user')
|
|
|
|
bsd_user_ss.add(files('gdbstub.c'))
|
|
specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
|
|
|
|
linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
|
|
specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
|
|
|
|
# needed for fuzzing binaries
|
|
subdir('tests/qtest/libqos')
|
|
subdir('tests/qtest/fuzz')
|
|
|
|
block_mods = []
|
|
softmmu_mods = []
|
|
foreach d, list : modules
|
|
foreach m, module_ss : list
|
|
if enable_modules and targetos != 'windows'
|
|
module_ss = module_ss.apply(config_all, strict: false)
|
|
sl = static_library(d + '-' + m, [genh, module_ss.sources()],
|
|
dependencies: [modulecommon, module_ss.dependencies()], pic: true)
|
|
if d == 'block'
|
|
block_mods += sl
|
|
else
|
|
softmmu_mods += sl
|
|
endif
|
|
else
|
|
if d == 'block'
|
|
block_ss.add_all(module_ss)
|
|
else
|
|
softmmu_ss.add_all(module_ss)
|
|
endif
|
|
endif
|
|
endforeach
|
|
endforeach
|
|
|
|
nm = find_program('nm')
|
|
undefsym = find_program('scripts/undefsym.py')
|
|
block_syms = custom_target('block.syms', output: 'block.syms',
|
|
input: [libqemuutil, block_mods],
|
|
capture: true,
|
|
command: [undefsym, nm, '@INPUT@'])
|
|
qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
|
|
input: [libqemuutil, softmmu_mods],
|
|
capture: true,
|
|
command: [undefsym, nm, '@INPUT@'])
|
|
|
|
block_ss = block_ss.apply(config_host, strict: false)
|
|
libblock = static_library('block', block_ss.sources() + genh,
|
|
dependencies: block_ss.dependencies(),
|
|
link_depends: block_syms,
|
|
name_suffix: 'fa',
|
|
build_by_default: false)
|
|
|
|
block = declare_dependency(link_whole: [libblock],
|
|
link_args: '@block.syms',
|
|
dependencies: [crypto, io])
|
|
|
|
qmp_ss = qmp_ss.apply(config_host, strict: false)
|
|
libqmp = static_library('qmp', qmp_ss.sources() + genh,
|
|
dependencies: qmp_ss.dependencies(),
|
|
name_suffix: 'fa',
|
|
build_by_default: false)
|
|
|
|
qmp = declare_dependency(link_whole: [libqmp])
|
|
|
|
foreach m : block_mods + softmmu_mods
|
|
shared_module(m.name(),
|
|
name_prefix: '',
|
|
link_whole: m,
|
|
install: true,
|
|
install_dir: config_host['qemu_moddir'])
|
|
endforeach
|
|
|
|
softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
|
|
common_ss.add(qom, qemuutil)
|
|
|
|
common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
|
|
common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
|
|
|
|
common_all = common_ss.apply(config_all, strict: false)
|
|
common_all = static_library('common',
|
|
build_by_default: false,
|
|
sources: common_all.sources() + genh,
|
|
dependencies: common_all.dependencies(),
|
|
name_suffix: 'fa')
|
|
|
|
feature_to_c = find_program('scripts/feature_to_c.sh')
|
|
|
|
emulators = {}
|
|
foreach target : target_dirs
|
|
config_target = config_target_mak[target]
|
|
target_name = config_target['TARGET_NAME']
|
|
arch = config_target['TARGET_BASE_ARCH']
|
|
arch_srcs = [config_target_h[target]]
|
|
arch_deps = []
|
|
c_args = ['-DNEED_CPU_H',
|
|
'-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
|
|
'-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
|
|
link_args = emulator_link_args
|
|
|
|
config_target += config_host
|
|
target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
|
|
if targetos == 'linux'
|
|
target_inc += include_directories('linux-headers', is_system: true)
|
|
endif
|
|
if target.endswith('-softmmu')
|
|
qemu_target_name = 'qemu-system-' + target_name
|
|
target_type='system'
|
|
t = target_softmmu_arch[arch].apply(config_target, strict: false)
|
|
arch_srcs += t.sources()
|
|
arch_deps += t.dependencies()
|
|
|
|
hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
|
|
hw = hw_arch[hw_dir].apply(config_target, strict: false)
|
|
arch_srcs += hw.sources()
|
|
arch_deps += hw.dependencies()
|
|
|
|
arch_srcs += config_devices_h[target]
|
|
link_args += ['@block.syms', '@qemu.syms']
|
|
else
|
|
abi = config_target['TARGET_ABI_DIR']
|
|
target_type='user'
|
|
qemu_target_name = 'qemu-' + target_name
|
|
if 'CONFIG_LINUX_USER' in config_target
|
|
base_dir = 'linux-user'
|
|
target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
|
|
else
|
|
base_dir = 'bsd-user'
|
|
endif
|
|
target_inc += include_directories(
|
|
base_dir,
|
|
base_dir / abi,
|
|
)
|
|
if 'CONFIG_LINUX_USER' in config_target
|
|
dir = base_dir / abi
|
|
arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
|
|
if config_target.has_key('TARGET_SYSTBL_ABI')
|
|
arch_srcs += \
|
|
syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
|
|
extra_args : config_target['TARGET_SYSTBL_ABI'])
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
if 'TARGET_XML_FILES' in config_target
|
|
gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
|
|
output: target + '-gdbstub-xml.c',
|
|
input: files(config_target['TARGET_XML_FILES'].split()),
|
|
command: [feature_to_c, '@INPUT@'],
|
|
capture: true)
|
|
arch_srcs += gdbstub_xml
|
|
endif
|
|
|
|
t = target_arch[arch].apply(config_target, strict: false)
|
|
arch_srcs += t.sources()
|
|
arch_deps += t.dependencies()
|
|
|
|
target_common = common_ss.apply(config_target, strict: false)
|
|
objects = common_all.extract_objects(target_common.sources())
|
|
deps = target_common.dependencies()
|
|
|
|
target_specific = specific_ss.apply(config_target, strict: false)
|
|
arch_srcs += target_specific.sources()
|
|
arch_deps += target_specific.dependencies()
|
|
|
|
lib = static_library('qemu-' + target,
|
|
sources: arch_srcs + genh,
|
|
dependencies: arch_deps,
|
|
objects: objects,
|
|
include_directories: target_inc,
|
|
c_args: c_args,
|
|
build_by_default: false,
|
|
name_suffix: 'fa')
|
|
|
|
if target.endswith('-softmmu')
|
|
execs = [{
|
|
'name': 'qemu-system-' + target_name,
|
|
'gui': false,
|
|
'sources': files('softmmu/main.c'),
|
|
'dependencies': []
|
|
}]
|
|
if targetos == 'windows' and (sdl.found() or gtk.found())
|
|
execs += [{
|
|
'name': 'qemu-system-' + target_name + 'w',
|
|
'gui': true,
|
|
'sources': files('softmmu/main.c'),
|
|
'dependencies': []
|
|
}]
|
|
endif
|
|
if config_host.has_key('CONFIG_FUZZ')
|
|
specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
|
|
execs += [{
|
|
'name': 'qemu-fuzz-' + target_name,
|
|
'gui': false,
|
|
'sources': specific_fuzz.sources(),
|
|
'dependencies': specific_fuzz.dependencies(),
|
|
}]
|
|
endif
|
|
else
|
|
execs = [{
|
|
'name': 'qemu-' + target_name,
|
|
'gui': false,
|
|
'sources': [],
|
|
'dependencies': []
|
|
}]
|
|
endif
|
|
foreach exe: execs
|
|
emulators += {exe['name']:
|
|
executable(exe['name'], exe['sources'],
|
|
install: true,
|
|
c_args: c_args,
|
|
dependencies: arch_deps + deps + exe['dependencies'],
|
|
objects: lib.extract_all_objects(recursive: true),
|
|
link_language: link_language,
|
|
link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
|
|
link_args: link_args,
|
|
gui_app: exe['gui'])
|
|
}
|
|
|
|
if 'CONFIG_TRACE_SYSTEMTAP' in config_host
|
|
foreach stp: [
|
|
{'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
|
|
{'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
|
|
{'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
|
|
{'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
|
|
]
|
|
custom_target(exe['name'] + stp['ext'],
|
|
input: trace_events_all,
|
|
output: exe['name'] + stp['ext'],
|
|
capture: true,
|
|
install: stp['install'],
|
|
install_dir: qemu_datadir / '../systemtap/tapset',
|
|
command: [
|
|
tracetool, '--group=all', '--format=' + stp['fmt'],
|
|
'--binary=' + stp['bin'],
|
|
'--target-name=' + target_name,
|
|
'--target-type=' + target_type,
|
|
'--probe-prefix=qemu.' + target_type + '.' + target_name,
|
|
'@INPUT@',
|
|
])
|
|
endforeach
|
|
endif
|
|
endforeach
|
|
endforeach
|
|
|
|
# Other build targets
|
|
|
|
if 'CONFIG_PLUGIN' in config_host
|
|
install_headers('include/qemu/qemu-plugin.h')
|
|
endif
|
|
|
|
if 'CONFIG_GUEST_AGENT' in config_host
|
|
subdir('qga')
|
|
endif
|
|
|
|
# Don't build qemu-keymap if xkbcommon is not explicitly enabled
|
|
# when we don't build tools or system
|
|
if xkbcommon.found()
|
|
# used for the update-keymaps target, so include rules even if !have_tools
|
|
qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
|
|
dependencies: [qemuutil, xkbcommon], install: have_tools)
|
|
endif
|
|
|
|
if have_tools
|
|
qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
|
|
dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
|
|
qemu_io = executable('qemu-io', files('qemu-io.c'),
|
|
dependencies: [block, qemuutil], install: true)
|
|
qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
|
|
dependencies: [block, qemuutil], install: true)
|
|
|
|
subdir('storage-daemon')
|
|
subdir('contrib/rdmacm-mux')
|
|
subdir('contrib/elf2dmp')
|
|
|
|
executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
|
|
dependencies: qemuutil,
|
|
install: true)
|
|
|
|
if 'CONFIG_VHOST_USER' in config_host
|
|
subdir('contrib/libvhost-user')
|
|
subdir('contrib/vhost-user-blk')
|
|
subdir('contrib/vhost-user-gpu')
|
|
subdir('contrib/vhost-user-input')
|
|
subdir('contrib/vhost-user-scsi')
|
|
endif
|
|
|
|
if targetos == 'linux'
|
|
executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
|
|
dependencies: [qemuutil, libcap_ng],
|
|
install: true,
|
|
install_dir: get_option('libexecdir'))
|
|
|
|
executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
|
|
dependencies: [authz, crypto, io, qom, qemuutil,
|
|
libcap_ng, mpathpersist],
|
|
install: true)
|
|
endif
|
|
|
|
if 'CONFIG_IVSHMEM' in config_host
|
|
subdir('contrib/ivshmem-client')
|
|
subdir('contrib/ivshmem-server')
|
|
endif
|
|
endif
|
|
|
|
subdir('scripts')
|
|
subdir('tools')
|
|
subdir('pc-bios')
|
|
subdir('tests')
|
|
subdir('docs')
|
|
if 'CONFIG_GTK' in config_host
|
|
subdir('po')
|
|
endif
|
|
|
|
if host_machine.system() == 'windows'
|
|
nsis_cmd = [
|
|
find_program('scripts/nsis.py'),
|
|
'@OUTPUT@',
|
|
get_option('prefix'),
|
|
meson.current_source_dir(),
|
|
host_machine.cpu_family(),
|
|
'--',
|
|
'-DDISPLAYVERSION=' + meson.project_version(),
|
|
]
|
|
if build_docs
|
|
nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
|
|
endif
|
|
if 'CONFIG_GTK' in config_host
|
|
nsis_cmd += '-DCONFIG_GTK=y'
|
|
endif
|
|
|
|
nsis = custom_target('nsis',
|
|
output: 'qemu-setup-' + meson.project_version() + '.exe',
|
|
input: files('qemu.nsi'),
|
|
build_always_stale: true,
|
|
command: nsis_cmd + ['@INPUT@'])
|
|
alias_target('installer', nsis)
|
|
endif
|
|
|
|
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']}
|
|
if targetos != 'windows'
|
|
summary_info += {'local state directory': config_host['qemu_localstatedir']}
|
|
summary_info += {'Manual directory': get_option('mandir')}
|
|
else
|
|
summary_info += {'local state directory': 'queried at runtime'}
|
|
endif
|
|
summary_info += {'Doc directory': get_option('docdir')}
|
|
summary_info += {'Build directory': meson.current_build_dir()}
|
|
summary_info += {'Source path': meson.current_source_dir()}
|
|
summary_info += {'GIT binary': config_host['GIT']}
|
|
summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
|
|
summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
|
|
summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
|
|
if link_language == 'cpp'
|
|
summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
|
|
else
|
|
summary_info += {'C++ compiler': false}
|
|
endif
|
|
if targetos == 'darwin'
|
|
summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
|
|
endif
|
|
summary_info += {'ARFLAGS': config_host['ARFLAGS']}
|
|
summary_info += {'CFLAGS': ' '.join(get_option('c_args')
|
|
+ ['-O' + get_option('optimization')]
|
|
+ (get_option('debug') ? ['-g'] : []))}
|
|
if link_language == 'cpp'
|
|
summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
|
|
+ ['-O' + get_option('optimization')]
|
|
+ (get_option('debug') ? ['-g'] : []))}
|
|
endif
|
|
link_args = get_option(link_language + '_link_args')
|
|
if link_args.length() > 0
|
|
summary_info += {'LDFLAGS': ' '.join(link_args)}
|
|
endif
|
|
summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
|
|
summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
|
|
summary_info += {'make': config_host['MAKE']}
|
|
summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
|
|
summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
|
|
summary_info += {'genisoimage': config_host['GENISOIMAGE']}
|
|
# TODO: add back version
|
|
summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
|
|
if slirp_opt != 'disabled'
|
|
summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
|
|
endif
|
|
summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
|
|
if config_host.has_key('CONFIG_MODULES')
|
|
summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
|
|
endif
|
|
summary_info += {'host CPU': cpu}
|
|
summary_info += {'host endianness': build_machine.endian()}
|
|
summary_info += {'target list': ' '.join(target_dirs)}
|
|
summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
|
|
summary_info += {'sparse enabled': sparse.found()}
|
|
summary_info += {'strip binaries': get_option('strip')}
|
|
summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
|
|
summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
|
|
if targetos == 'darwin'
|
|
summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
|
|
endif
|
|
# TODO: add back version
|
|
summary_info += {'SDL support': sdl.found()}
|
|
summary_info += {'SDL image support': sdl_image.found()}
|
|
# TODO: add back version
|
|
summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
|
|
summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
|
|
summary_info += {'pixman': pixman.found()}
|
|
# TODO: add back version
|
|
summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
|
|
summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
|
|
summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
|
|
# TODO: add back version
|
|
summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
|
|
if config_host.has_key('CONFIG_GCRYPT')
|
|
summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
|
|
summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
|
|
endif
|
|
# TODO: add back version
|
|
summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
|
|
if config_host.has_key('CONFIG_NETTLE')
|
|
summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
|
|
endif
|
|
summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
|
|
summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
|
|
summary_info += {'iconv support': config_host.has_key('CONFIG_ICONV')}
|
|
summary_info += {'curses support': config_host.has_key('CONFIG_CURSES')}
|
|
# TODO: add back version
|
|
summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
|
|
summary_info += {'curl support': config_host.has_key('CONFIG_CURL')}
|
|
summary_info += {'mingw32 support': targetos == 'windows'}
|
|
summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
|
|
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 += {'Multipath support': mpathpersist.found()}
|
|
summary_info += {'VNC support': vnc.found()}
|
|
if vnc.found()
|
|
summary_info += {'VNC SASL support': sasl.found()}
|
|
summary_info += {'VNC JPEG support': jpeg.found()}
|
|
summary_info += {'VNC PNG support': png.found()}
|
|
endif
|
|
summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
|
|
if config_host.has_key('CONFIG_XEN_BACKEND')
|
|
summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
|
|
endif
|
|
summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')}
|
|
summary_info += {'Documentation': config_host.has_key('BUILD_DOCS')}
|
|
summary_info += {'PIE': get_option('b_pie')}
|
|
summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
|
|
summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
|
|
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 += {'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 += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
|
|
summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
|
|
if config_all.has_key('CONFIG_TCG')
|
|
summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
|
|
summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
|
|
endif
|
|
summary_info += {'malloc trim support': has_malloc_trim}
|
|
summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
|
|
summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
|
|
summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
|
|
summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
|
|
summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
|
|
summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
|
|
summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
|
|
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-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-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']}
|
|
if config_host['TRACE_BACKENDS'].split().contains('simple')
|
|
summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
|
|
endif
|
|
# TODO: add back protocol and server version
|
|
summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
|
|
summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')}
|
|
summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
|
|
summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
|
|
summary_info += {'U2F support': u2f.found()}
|
|
summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
|
|
summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
|
|
summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
|
|
summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
|
|
summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')}
|
|
summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')}
|
|
summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
|
|
if targetos == 'windows'
|
|
if 'WIN_SDK' in config_host
|
|
summary_info += {'Windows SDK': config_host['WIN_SDK']}
|
|
endif
|
|
summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
|
|
summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
|
|
summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
|
|
endif
|
|
summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
|
|
summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
|
|
summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
|
|
summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
|
|
summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
|
|
summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
|
|
summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
|
|
summary_info += {'gcov': get_option('b_coverage')}
|
|
summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
|
|
summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
|
|
summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
|
|
summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
|
|
summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')}
|
|
summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')}
|
|
summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')}
|
|
summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
|
|
summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
|
|
summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
|
|
summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
|
|
summary_info += {'memory allocator': get_option('malloc')}
|
|
summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
|
|
summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
|
|
summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
|
|
summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
|
|
summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
|
|
summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
|
|
summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
|
|
summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
|
|
summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
|
|
summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
|
|
summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
|
|
summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
|
|
summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
|
|
summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
|
|
summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
|
|
summary_info += {'libudev': libudev.found()}
|
|
summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
|
|
summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
|
|
summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
|
|
if config_host.has_key('HAVE_GDB_BIN')
|
|
summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
|
|
endif
|
|
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(summary_info, bool_yn: true)
|
|
|
|
if not supported_cpus.contains(cpu)
|
|
message()
|
|
warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
|
|
message()
|
|
message('CPU host architecture ' + cpu + ' support is not currently maintained.')
|
|
message('The QEMU project intends to remove support for this host CPU in')
|
|
message('a future release if nobody volunteers to maintain it and to')
|
|
message('provide a build host for our continuous integration setup.')
|
|
message('configure has succeeded and you can continue to build, but')
|
|
message('if you care about QEMU on this platform you should contact')
|
|
message('us upstream at qemu-devel@nongnu.org.')
|
|
endif
|
|
|
|
if not supported_oses.contains(targetos)
|
|
message()
|
|
warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
|
|
message()
|
|
message('Host OS ' + targetos + 'support is not currently maintained.')
|
|
message('The QEMU project intends to remove support for this host OS in')
|
|
message('a future release if nobody volunteers to maintain it and to')
|
|
message('provide a build host for our continuous integration setup.')
|
|
message('configure has succeeded and you can continue to build, but')
|
|
message('if you care about QEMU on this platform you should contact')
|
|
message('us upstream at qemu-devel@nongnu.org.')
|
|
endif
|