aboutsummaryrefslogtreecommitdiff
path: root/meson.build
diff options
context:
space:
mode:
Diffstat (limited to 'meson.build')
-rw-r--r--meson.build158
1 files changed, 142 insertions, 16 deletions
diff --git a/meson.build b/meson.build
index 4ea1984fc5..aecc381932 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project('qemu', ['c'], meson_version: '>=1.1.0',
+project('qemu', ['c'], meson_version: '>=1.5.0',
default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
version: files('VERSION'))
@@ -70,6 +70,19 @@ if host_os == 'darwin' and \
all_languages += ['objc']
objc = meson.get_compiler('objc')
endif
+have_rust = false
+if not get_option('rust').disabled() and add_languages('rust', required: get_option('rust'), native: false)
+ rustc = meson.get_compiler('rust')
+ have_rust = true
+ if rustc.version().version_compare('<1.80.0')
+ if get_option('rust').enabled()
+ error('rustc version ' + rustc.version() + ' is unsupported: Please upgrade to at least 1.80.0')
+ else
+ warning('rustc version ' + rustc.version() + ' is unsupported: Disabling Rust compilation. Please upgrade to at least 1.80.0 to use Rust.')
+ have_rust = false
+ endif
+ endif
+endif
dtrace = not_found
stap = not_found
@@ -322,6 +335,10 @@ elif host_os == 'windows'
endif
endif
+# Choose instruction set (currently x86-only)
+
+qemu_isa_flags = []
+
# __sync_fetch_and_and requires at least -march=i486. Many toolchains
# use i686 as default anyway, but for those that don't, an explicit
# specification is necessary
@@ -338,7 +355,7 @@ if host_arch == 'i386' and not cc.links('''
sfaa(&val);
return val;
}''')
- qemu_common_flags = ['-march=i486'] + qemu_common_flags
+ qemu_isa_flags += ['-march=i486']
endif
# Pick x86-64 baseline version
@@ -354,29 +371,31 @@ if host_arch in ['i386', 'x86_64']
else
# present on basically all processors but technically not part of
# x86-64-v1, so only include -mneeded for x86-64 version 2 and above
- qemu_common_flags = ['-mcx16'] + qemu_common_flags
+ qemu_isa_flags += ['-mcx16']
endif
endif
if get_option('x86_version') >= '2'
- qemu_common_flags = ['-mpopcnt'] + qemu_common_flags
- qemu_common_flags = cc.get_supported_arguments('-mneeded') + qemu_common_flags
+ qemu_isa_flags += ['-mpopcnt']
+ qemu_isa_flags += cc.get_supported_arguments('-mneeded')
endif
if get_option('x86_version') >= '3'
- qemu_common_flags = ['-mmovbe', '-mabm', '-mbmi1', '-mbmi2', '-mfma', '-mf16c'] + qemu_common_flags
+ qemu_isa_flags += ['-mmovbe', '-mabm', '-mbmi', '-mbmi2', '-mfma', '-mf16c']
endif
# add required vector instruction set (each level implies those below)
if get_option('x86_version') == '1'
- qemu_common_flags = ['-msse2'] + qemu_common_flags
+ qemu_isa_flags += ['-msse2']
elif get_option('x86_version') == '2'
- qemu_common_flags = ['-msse4.2'] + qemu_common_flags
+ qemu_isa_flags += ['-msse4.2']
elif get_option('x86_version') == '3'
- qemu_common_flags = ['-mavx2'] + qemu_common_flags
+ qemu_isa_flags += ['-mavx2']
elif get_option('x86_version') == '4'
- qemu_common_flags = ['-mavx512f', '-mavx512bw', '-mavx512cd', '-mavx512dq', '-mavx512vl'] + qemu_common_flags
+ qemu_isa_flags += ['-mavx512f', '-mavx512bw', '-mavx512cd', '-mavx512dq', '-mavx512vl']
endif
endif
+qemu_common_flags = qemu_isa_flags + qemu_common_flags
+
if get_option('prefer_static')
qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
endif
@@ -935,7 +954,9 @@ have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
################
# When bumping glib minimum version, please check also whether to increase
-# the _WIN32_WINNT setting in osdep.h according to the value from glib
+# the _WIN32_WINNT setting in osdep.h according to the value from glib.
+# You should also check if any of the glib.version() checks
+# below can also be removed.
glib_req_ver = '>=2.66.0'
glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
method: 'pkg-config')
@@ -985,6 +1006,9 @@ glib = declare_dependency(dependencies: [glib_pc, gmodule],
# TODO: remove this check and the corresponding workaround (qtree) when
# the minimum supported glib is >= 2.75.3
glib_has_gslice = glib.version().version_compare('<2.75.3')
+# Check whether glib has the aligned_alloc family of functions.
+# <https://docs.gtk.org/glib/func.aligned_alloc.html>
+glib_has_aligned_alloc = glib.version().version_compare('>=2.72.0')
# override glib dep to include the above refinements
meson.override_dependency('glib-2.0', glib)
@@ -2158,6 +2182,7 @@ endif
config_host_data = configuration_data()
+config_host_data.set('CONFIG_HAVE_RUST', have_rust)
audio_drivers_selected = []
if have_system
audio_drivers_available = {
@@ -2516,6 +2541,7 @@ config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
+config_host_data.set('HAVE_GLIB_WITH_ALIGNED_ALLOC', glib_has_aligned_alloc)
config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
@@ -2806,7 +2832,7 @@ config_host_data.set('CONFIG_ATOMIC64', cc.links('''
__atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
__atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
return 0;
- }'''))
+ }''', args: qemu_isa_flags))
has_int128_type = cc.compiles('''
__int128_t a;
@@ -2840,7 +2866,7 @@ if has_int128_type
__atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
return 0;
}'''
- has_atomic128 = cc.links(atomic_test_128)
+ has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags)
config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
@@ -2849,7 +2875,8 @@ if has_int128_type
# without optimization enabled. Try again with optimizations locally
# enabled for the function. See
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
- has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
+ has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128,
+ args: qemu_isa_flags)
config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
if not has_atomic128_opt
@@ -2860,7 +2887,7 @@ if has_int128_type
__sync_val_compare_and_swap_16(&x, y, x);
return 0;
}
- '''))
+ ''', args: qemu_isa_flags))
endif
endif
endif
@@ -3097,7 +3124,8 @@ host_kconfig = \
(host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
(multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
(vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
- (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
+ (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \
+ (have_rust ? ['CONFIG_HAVE_RUST=y'] : [])
ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
@@ -3491,6 +3519,7 @@ qom_ss = ss.source_set()
system_ss = ss.source_set()
specific_fuzz_ss = ss.source_set()
specific_ss = ss.source_set()
+rust_devices_ss = ss.source_set()
stub_ss = ss.source_set()
trace_ss = ss.source_set()
user_ss = ss.source_set()
@@ -3877,6 +3906,74 @@ common_all = static_library('common',
implicit_include_directories: false,
dependencies: common_ss.all_dependencies())
+if have_rust and have_system
+ rustc_args = run_command(
+ find_program('scripts/rust/rustc_args.py'),
+ '--config-headers', meson.project_build_root() / 'config-host.h',
+ capture : true,
+ check: true).stdout().strip().split()
+ rustc_args += ['-D', 'unsafe_op_in_unsafe_fn']
+ bindgen_args = [
+ '--disable-header-comment',
+ '--raw-line', '// @generated',
+ '--ctypes-prefix', 'core::ffi',
+ '--formatter', 'rustfmt',
+ '--generate-block',
+ '--generate-cstr',
+ '--impl-debug',
+ '--merge-extern-blocks',
+ '--no-doc-comments',
+ '--use-core',
+ '--with-derive-default',
+ '--no-size_t-is-usize',
+ '--no-layout-tests',
+ '--no-prepend-enum-name',
+ '--allowlist-file', meson.project_source_root() + '/include/.*',
+ '--allowlist-file', meson.project_source_root() + '/.*',
+ '--allowlist-file', meson.project_build_root() + '/.*'
+ ]
+ c_enums = [
+ 'DeviceCategory',
+ 'GpioPolarity',
+ 'MachineInitPhase',
+ 'MemoryDeviceInfoKind',
+ 'MigrationPolicy',
+ 'MigrationPriority',
+ 'QEMUChrEvent',
+ 'QEMUClockType',
+ 'device_endian',
+ 'module_init_type',
+ ]
+ foreach enum : c_enums
+ bindgen_args += ['--rustified-enum', enum]
+ endforeach
+ c_bitfields = [
+ 'ClockEvent',
+ 'VMStateFlags',
+ ]
+ foreach enum : c_bitfields
+ bindgen_args += ['--bitfield-enum', enum]
+ endforeach
+
+ # TODO: Remove this comment when the clang/libclang mismatch issue is solved.
+ #
+ # Rust bindings generation with `bindgen` might fail in some cases where the
+ # detected `libclang` does not match the expected `clang` version/target. In
+ # this case you must pass the path to `clang` and `libclang` to your build
+ # command invocation using the environment variables CLANG_PATH and
+ # LIBCLANG_PATH
+ bindings_rs = import('rust').bindgen(
+ input: 'rust/wrapper.h',
+ dependencies: common_ss.all_dependencies(),
+ output: 'bindings.rs',
+ include_directories: include_directories('.', 'include'),
+ bindgen_version: ['>=0.69.4'],
+ args: bindgen_args,
+ )
+ subdir('rust')
+endif
+
+
feature_to_c = find_program('scripts/feature_to_c.py')
if host_os == 'darwin'
@@ -3970,6 +4067,29 @@ foreach target : target_dirs
arch_srcs += target_specific.sources()
arch_deps += target_specific.dependencies()
+ if have_rust and have_system
+ target_rust = rust_devices_ss.apply(config_target, strict: false)
+ crates = []
+ foreach dep : target_rust.dependencies()
+ crates += dep.get_variable('crate')
+ endforeach
+ if crates.length() > 0
+ rlib_rs = custom_target('rust_' + target.underscorify() + '.rs',
+ output: 'rust_' + target.underscorify() + '.rs',
+ command: [find_program('scripts/rust/rust_root_crate.sh')] + crates,
+ capture: true,
+ build_by_default: true,
+ build_always_stale: true)
+ rlib = static_library('rust_' + target.underscorify(),
+ rlib_rs,
+ dependencies: target_rust.dependencies(),
+ override_options: ['rust_std=2021', 'build.rust_std=2021'],
+ rust_args: rustc_args,
+ rust_abi: 'c')
+ arch_deps += declare_dependency(link_whole: [rlib])
+ endif
+ endif
+
# allow using headers from the dependencies but do not include the sources,
# because this emulator only needs those in "objects". For external
# dependencies, the full dependency is included below in the executable.
@@ -4308,6 +4428,12 @@ if 'objc' in all_languages
else
summary_info += {'Objective-C compiler': false}
endif
+summary_info += {'Rust support': have_rust}
+if have_rust
+ summary_info += {'rustc version': rustc.version()}
+ summary_info += {'rustc': ' '.join(rustc.cmd_array())}
+ summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']}
+endif
option_cflags = (get_option('debug') ? ['-g'] : [])
if get_option('optimization') != 'plain'
option_cflags += ['-O' + get_option('optimization')]