@@ -334,6 +334,10 @@ elif host_os == 'windows'
# We use this compilation option instead of relying on gcc_struct attribute
# because clang does not support it (but supports the option).
qemu_common_flags += ['-mno-ms-bitfields']
+
+ if compiler.get_id() == 'clang' and compiler.get_linker_id() != 'ld.lld'
+ error('On windows, you need to use lld with clang - use msys2 clang64/clangarm64 env')
+ endif
endif
# Choose instruction set (currently x86-only)
@@ -12,7 +12,7 @@ if get_option('plugins')
t += shared_module(i, files(i + '.c') + 'win32_linker.c',
include_directories: '../../include/qemu',
link_depends: [win32_qemu_plugin_api_lib],
- link_args: ['-Lplugins', '-lqemu_plugin_api'],
+ link_args: win32_qemu_plugin_api_link_flags,
dependencies: glib)
else
t += shared_module(i, files(i + '.c'),
@@ -11,14 +11,15 @@ if not enable_modules
capture: true,
command: ['sed', '-ne', 's/^[[:space:]]*\\(qemu_.*\\);/_\\1/p', '@INPUT@'])
emulator_link_args += ['-Wl,-exported_symbols_list,plugins/qemu-plugins-ld64.symbols']
+ elif host_os == 'windows' and meson.get_compiler('c').get_id() == 'clang'
+ # LLVM/lld does not support exporting specific symbols. However, it works
+ # out of the box with dllexport/dllimport attribute we set in the code.
else
emulator_link_args += ['-Xlinker', '--dynamic-list=' + (meson.project_source_root() / 'plugins/qemu-plugins.symbols')]
endif
endif
if host_os == 'windows'
- dlltool = find_program('dlltool', required: true)
-
# Generate a .lib file for plugins to link against.
# First, create a .def file listing all the symbols a plugin should expect to have
# available in qemu
@@ -27,12 +28,27 @@ if host_os == 'windows'
output: 'qemu_plugin_api.def',
capture: true,
command: ['sed', '-e', '0,/^/s//EXPORTS/; s/[{};]//g', '@INPUT@'])
+
# then use dlltool to assemble a delaylib.
+ # The delaylib will have an "imaginary" name (qemu.exe), that is used by the
+ # linker file we add with plugins (win32_linker.c) to identify that we want
+ # to find missing symbols in current program.
+ win32_qemu_plugin_api_link_flags = ['-Lplugins', '-lqemu_plugin_api']
+ if meson.get_compiler('c').get_id() == 'clang'
+ # With LLVM/lld, delaylib is specified at link time (-delayload)
+ dlltool = find_program('llvm-dlltool', required: true)
+ dlltool_cmd = [dlltool, '-d', '@INPUT@', '-l', '@OUTPUT@', '-D', 'qemu.exe']
+ win32_qemu_plugin_api_link_flags += ['-Wl,-delayload=qemu.exe']
+ else
+ # With gcc/ld, delay lib is built with a specific delay parameter.
+ dlltool = find_program('dlltool', required: true)
+ dlltool_cmd = [dlltool, '--input-def', '@INPUT@',
+ '--output-delaylib', '@OUTPUT@', '--dllname', 'qemu.exe']
+ endif
win32_qemu_plugin_api_lib = configure_file(
input: win32_plugin_def,
output: 'libqemu_plugin_api.a',
- command: [dlltool, '--input-def', '@INPUT@',
- '--output-delaylib', '@OUTPUT@', '--dllname', 'qemu.exe']
+ command: dlltool_cmd
)
endif
specific_ss.add(files(
@@ -5,9 +5,8 @@ if get_option('plugins')
t += shared_module(i, files(i + '.c') + '../../../contrib/plugins/win32_linker.c',
include_directories: '../../../include/qemu',
link_depends: [win32_qemu_plugin_api_lib],
- link_args: ['-Lplugins', '-lqemu_plugin_api'],
+ link_args: win32_qemu_plugin_api_link_flags,
dependencies: glib)
-
else
t += shared_module(i, files(i + '.c'),
include_directories: '../../../include/qemu',
Windows uses a special mechanism to enable plugins to work (DLL delay loading). Option for lld is different than ld. Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> --- meson.build | 4 ++++ contrib/plugins/meson.build | 2 +- plugins/meson.build | 24 ++++++++++++++++++++---- tests/tcg/plugins/meson.build | 3 +-- 4 files changed, 26 insertions(+), 7 deletions(-)