From b1eaaa0638605ea270baef344610e2922123e7fc Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 12 Apr 2021 22:35:09 +0200 Subject: [PATCH] Fix ABI compatibility with 32-bit VST3 plugins #80 This would cause 32-bit VST3 plugins to crash in mysterious ways. What ended up being the issue is that the plugins expected doubles to be 8-byte aligned in structs, while GCC doesn't do that by default in x86 code for legacy ABI compatibility reasons. Figuring out what exactly was the issue took months, but luckily the fix was to just add an `-malign-double`! --- CHANGELOG.md | 5 +++++ README.md | 8 ++++---- meson.build | 25 +++++++++++++++---------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acdefa74..2c9d7d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +- Added support for using 32-bit Windows VST3 plugins in 64-bit Linux VST3 + hosts. + ### Fixed - Added a workaround for a bug present in every _Bluecat Audio_ VST3 plugin diff --git a/README.md b/README.md index 294d4f29..3052be7a 100644 --- a/README.md +++ b/README.md @@ -180,10 +180,10 @@ ln -s "$HOME/.wine/drive_c/Program Files/Steinberg/" ~/.vst/yabridge-steinberg If you have downloaded the prebuilt version of yabridge or if have followed the instructions from the [bitbridge](#32-bit-bitbridge) section below, then -yabridge is also able to load 32-bit VST2 plugins. The installation procedure -for 32-bit plugins is exactly the same as for 64-bit plugins. Yabridge will -automatically detect whether a plugin is 32-bit or 64-bit on startup and it will -handle it accordingly. +yabridge is also able to load 32-bit VST2 and VST3 plugins. The installation +procedure for 32-bit plugins is exactly the same as for 64-bit plugins. Yabridge +will automatically detect whether a plugin is 32-bit or 64-bit on startup and it +will handle it accordingly. ### Wine prefixes diff --git a/meson.build b/meson.build index 37c84ede..76458da4 100644 --- a/meson.build +++ b/meson.build @@ -39,6 +39,11 @@ compiler_options = [ # https://github.com/boostorg/asio/issues/312 '-DBOOST_ASIO_DISABLE_CONCEPTS', ] +# NOTE: GCC doesn't 8-byte align doubles in structs on x86 for ABI-compatibilty +# reasons, but MSVC++ does. We need to force this same alignment to be +# ABI-compatible with 32-bit binaries created with MSVC++ on Windows. +wine_32bit_compiler_options = ['-m32', '-malign-double'] +wine_64bit_compiler_options = ['-m64'] with_bitbridge = get_option('with-bitbridge') with_static_boost = get_option('with-static-boost') @@ -356,7 +361,7 @@ if with_vst3 vst3_base_wine_64bit = static_library( 'vst3_base_wine_64bit', vst3.get_variable('base_sources'), - cpp_args : vst3_compiler_options + vst3_wine_compiler_options + ['-m64', '-Wno-cpp'], + cpp_args : vst3_compiler_options + vst3_wine_compiler_options + wine_64bit_compiler_options + [ '-Wno-cpp'], include_directories : vst3_include_dir, override_options : ['warning_level=0'], native : false, @@ -364,7 +369,7 @@ if with_vst3 vst3_pluginterfaces_wine_64bit = static_library( 'vst3_pluginterfaces_wine_64bit', vst3.get_variable('pluginterfaces_sources'), - cpp_args : vst3_compiler_options + vst3_wine_compiler_options + ['-m64'], + cpp_args : vst3_compiler_options + vst3_wine_compiler_options + wine_64bit_compiler_options, include_directories : vst3_include_dir, override_options : ['warning_level=0'], native : false, @@ -373,7 +378,7 @@ if with_vst3 'vst3_sdk_hosting_wine_64bit', vst3.get_variable('sdk_common_sources') + vst3.get_variable('sdk_hosting_sources'), link_with : [vst3_base_wine_64bit, vst3_pluginterfaces_wine_64bit], - cpp_args : vst3_compiler_options + vst3_wine_compiler_options + ['-m64', '-Wno-multichar'], + cpp_args : vst3_compiler_options + vst3_wine_compiler_options + wine_64bit_compiler_options + ['-Wno-multichar'], include_directories : vst3_include_dir, override_options : ['warning_level=0'], native : false, @@ -392,7 +397,7 @@ if with_vst3 vst3_base_wine_32bit = static_library( 'vst3_base_wine_32bit', vst3.get_variable('base_sources'), - cpp_args : vst3_compiler_options + vst3_wine_compiler_options + ['-m32', '-Wno-cpp'], + cpp_args : vst3_compiler_options + vst3_wine_compiler_options + wine_32bit_compiler_options + ['-Wno-cpp'], include_directories : vst3_include_dir, override_options : ['warning_level=0'], native : false, @@ -400,7 +405,7 @@ if with_vst3 vst3_pluginterfaces_wine_32bit = static_library( 'vst3_pluginterfaces_wine_32bit', vst3.get_variable('pluginterfaces_sources'), - cpp_args : vst3_compiler_options + vst3_wine_compiler_options + ['-m32'], + cpp_args : vst3_compiler_options + vst3_wine_compiler_options + wine_32bit_compiler_options, include_directories : vst3_include_dir, override_options : ['warning_level=0'], native : false, @@ -409,7 +414,7 @@ if with_vst3 'vst3_sdk_hosting_wine_32bit', vst3.get_variable('sdk_common_sources') + vst3.get_variable('sdk_hosting_sources'), link_with : [vst3_base_wine_32bit, vst3_pluginterfaces_wine_32bit], - cpp_args : vst3_compiler_options + vst3_wine_compiler_options + ['-m32', '-Wno-multichar'], + cpp_args : vst3_compiler_options + vst3_wine_compiler_options + wine_32bit_compiler_options + ['-Wno-multichar'], include_directories : vst3_include_dir, override_options : ['warning_level=0'], native : false, @@ -539,7 +544,7 @@ executable( native : false, include_directories : include_dir, dependencies : host_64bit_deps, - cpp_args : compiler_options + ['-m64'], + cpp_args : compiler_options + wine_64bit_compiler_options, link_args : ['-m64'], ) @@ -549,7 +554,7 @@ executable( native : false, include_directories : include_dir, dependencies : host_64bit_deps, - cpp_args : compiler_options + ['-m64'], + cpp_args : compiler_options + wine_64bit_compiler_options, link_args : ['-m64'], ) @@ -560,7 +565,7 @@ if with_bitbridge native : false, include_directories : include_dir, dependencies : host_32bit_deps, - cpp_args : compiler_options + ['-m32'], + cpp_args : compiler_options + wine_32bit_compiler_options, link_args : ['-m32'], ) @@ -570,7 +575,7 @@ if with_bitbridge native : false, include_directories : include_dir, dependencies : host_32bit_deps, - cpp_args : compiler_options + ['-m32'], + cpp_args : compiler_options + wine_32bit_compiler_options, link_args : ['-m32'], ) endif