-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix MSVC VST compilation #4421
Fix MSVC VST compilation #4421
Conversation
This will probably break everything, but it was needed to load 32bit VST plugins with MSVC.
Older versions of MinGW don't provide std::mutex or std::thread
* locale: using path instead of individual files to reduce command line size * remotevstplugin: changed order return type & calling convention (compiler error) * lmmsobj: removed single quotes for command line defines * added vcpkg support & std::make_unique for MSVC * carla: include exports header * package_linux: corrected RemoteVstPlugin name * vstbase: toolchain file conditional on MSVC * Added install for remotevstplugin * msvc: installer works with vcpkg Remotevst 64bit install removed due to an ApImage problem
* Remove trial-and-error approach of detecting VST's machine types. Read PE headers instead. * Add RemoteVstPlugin64 to AppImage
(with backward compatibility for SDL1).
The zero index device may not be the default device. Many thanks to @PhysSong.
cmake/linux/winegcc_wrapper.in
Outdated
#!/bin/sh | ||
# Wrapper script for winegcc to remove .exe file ending automatically | ||
# appended by winebuild. | ||
# Usage: winegcc <args ...> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your usage says winegcc
. I'm sure this was intentional, but more accurately...
# Usage: winegcc_wrapper <args ...>
# --- OR ---
# Usage:
# CONFIGURE_FILE("path/to/winegcc_wrapper.in winegcc_wrapper @ONLY)
# SET(WINEGCC "path/to/winegcc_wrapper")
# winegcc <args ...>
Probably nitpicking, but didn't know if it was a typo or intentional. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't intentional, I don't even know why I wrote this in the first place. :) Although your version is definitely better, I think I'll replace it with a note to FindWine.cmake
since it's not supposed to be used outside of that context anyway.
winegcc_wrapper.in is only intended to be used within FindWine.cmake. Also moved it to the same directory for this reason.
I'll be merging this shortly if there are no objections. This changes a lot of things in CMake, so I it's possible it breaks the build for some Linux users. Feel free to complain to me if that's the case. |
m_badDllFormat = false; | ||
tryLoad( "32/RemoteVstPlugin32" ); | ||
case PE::MachineType::amd64: | ||
tryLoad( "RemoteVstPlugin64" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, this will try to load 64bit DLL in 32bit system using nonexistent RemoteVstPlugin64
. It will print an error message, but Windows users can't see that.
Do we need to try this on 32bit LMMS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is correct, there's no visible error message in the GUI when loading fails. This PR doesn't change that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think error message issue can be fixed later, but do we ever need to try to load VST with RemoteVstPlugin64
on 32bit systems?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theoretically, we could ship a RemoteVstPlugin64
with our 32bit Windows installers for users who install 32bit LMMS because they're unaware of the difference. In that case, it's good to try RemoteVstPlugin64
. In any other case, there's no harm done here. tryLoad
will discover that RemoteVstPlugin64
doesn't exist and will abort, at which point we can easily add an error message later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, I didn't think about that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we may try to detect processor in runtime if possible, though it looks like out of scope.
Qt provides QSysInfo::currentCpuArchitecture
as of Qt 5.4, and it's also possible to use OS-dependent detection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened #4447 to track it.
Anything left to change @PhysSong or should I merge? |
I'll review this shotrly. If it looks fine, you can go ahead. |
@@ -24,6 +31,10 @@ STRING(REPLACE " " ";" WINEBUILD_FLAGS "${WINEBUILD_OUTPUT}") | |||
|
|||
FOREACH(FLAG ${WINEBUILD_FLAGS}) | |||
IF("${FLAG}" MATCHES "libwinecrt0.a.*") | |||
STRING(REGEX REPLACE "/wine/libwinecrt0.a.*" "" FLAG "${FLAG}") | |||
|
|||
SET(WINE_64_LIBRARY_DIR "${FLAG}/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unusual, but it is possible to use 32-bit WINE toolchain wine32-tools
on 64-bit Debian/Ubuntu. In that case, 64-bit VST compilation needs the inverse replacing(32-bit toolchain uses 32-bit libraries, even if -m64
is specified).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that something we have supported before and that this PR breaks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that something we have supported
It's an issue when building 64-bit VST on Linux, so no.
vst_base | ||
vestige |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's no reason to move this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is, vestige
links to vstbase
, so vst_base
needs to be processed first. Otherwise, the target doesn't exist when vestige
tries to link to it.
@@ -7,8 +7,10 @@ | |||
#include <memory> | |||
#include <utility> | |||
|
|||
#if (__cplusplus >= 201402L) | |||
#if (__cplusplus >= 201402L || _MSC_VER) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks VS 2012 incompatible.
#4352 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine. VS 2012 doesn't even implement C++11, so we can't support it.
plugins/vst_base/RemoteVstPlugin.cpp
Outdated
{ | ||
sendMessage( IdVstBadDllFormat ); | ||
} | ||
DWORD error = GetLastError(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, but a tab before =
doesn't look good here.
m_badDllFormat = false; | ||
tryLoad( "32/RemoteVstPlugin32" ); | ||
case PE::MachineType::amd64: | ||
tryLoad( "RemoteVstPlugin64" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think error message issue can be fixed later, but do we ever need to try to load VST with RemoteVstPlugin64
on 32bit systems?
src/core/RemotePlugin.cpp
Outdated
@@ -62,7 +63,10 @@ void ProcessWatcher::run() | |||
{ | |||
fprintf( stderr, | |||
"remote plugin died! invalidating now.\n" ); | |||
|
|||
#ifndef SYNC_WITH_SHM_FIFO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why did you add this check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you look at the commit that added this change (9db8cbf#diff-b6e06d3d61c47ede770ac49ad9ea8f9e), you can see that I removed an invalidate()
call guarded by the same check in processFinished
. I removed it because it prevented receiving messages after the plugin died (related: #4103 (comment), #4371, 4fd8ecd). I figured @jasp00
had a reason to add the check though and simply missed this invalidate
call, because I couldn't see a point in doing the invalidate
twice. So I added the checks here because I removed them together with the invalidate
call in processFinished
. I'm not sure about this though, it's mostly guesswork. Maybe @DomClark or @Wallacoloo have any insight on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since SYNC_WITH_SHM_FIFO
is defined on Windows, this check will prevent LMMS from invalidating plugin. There's no other calls to invalidate
on Windows, so it may cause crashes/hangs when remote plugin crashes.
Also, dropping the call in processFinished
may result in delaying invalidation because it checks process state every 200ms. I guess call was added for immediate invalidation.
I guess we can somehow work around the delay and/or the IPC issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I remove the check? Re-adding the call in processFinished
will render @justnope's/@Wallacoloo's 4fd8ecd useless again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I remove the check?
I think yes. There's no reason to check that here.
Re-adding the call in
processFinished
(...) 4fd8ecd useless
It does, but can't we work around this? Though it's not necessary for now and might be hard, I don't think it's impossible. I don't want to block merging this because of the call though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does, but can't we work around this?
We probably can, but I have no idea how to do it.
Anyway, I'll revert both changes because this PR doesn't depend on them any more since the VstBadDllFormat
message was replaced by the PE file detection.
Reverts some changes made in 9db8cbf. The consequences of this changes are unsure, so reverting them for now. Since a VST plugin's architecture is now detected before trying to load it, this fix is not needed any more for 64&32-bit VSTs to work, as the idVstBadDllFormat-message-mechanism was removed. It should be noted however that the bug still exists, probably rendering 4fd8ecd ineffective.
plugins/vst_base/RemoteVstPlugin.cpp
Outdated
@@ -675,11 +691,11 @@ void RemoteVstPlugin::init( const std::string & _plugin_file ) | |||
|
|||
|
|||
|
|||
static void close_check( int fd ) | |||
static void close_check( FILE* fd ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, but it's not a file descriptor anymore. Might fd
be confusing?
# Conflicts: # plugins/vst_base/RemoteVstPlugin.cpp # plugins/vst_base/VstPlugin.cpp
FileInfo(QString filePath) | ||
: m_file(filePath) | ||
{ | ||
m_file.open(QFile::ReadOnly); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file open can fail if the path passed to VstPlugin
is relative. So I can't load some VSTs...
There should be a path check logic like one in VstPlugin::tryLoad
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed via 7ddca85
@@ -33,12 +44,19 @@ FOREACH(FLAG ${WINEBUILD_FLAGS}) | |||
# WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging) | |||
STRING(REPLACE "/lib64/wine/" "/lib/wine/" FLAG "${FLAG}") | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic doesn't work anymore because we drop /wine/
before it and causes #4501.
Some possible solutions:
- Use a regular expression to match trailing
lib64
- Remove
/wine/libwinecrt0.a.*
after replacing - Always replace
lib64
withlib
if it doesn't break other platforms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for tracking this down. Fixed with 515fefa.
This PR fixes VST compilation with MSVC (see #3999). Changes made include:
RemoteVstPlugin
is now built usingExternalProject_Add
when the target platform doesn't match, and is namedRemoteVstPlugin32
andRemoteVstPlugin64
for 32bit and 64bit respectively. WineGCC isn't used directly any more, but is passed to the CMake external project with-DCMAKE_CXX_COMPILER=...
-GenerateExportHeader
instead of the hand-writtenexport.h
. TheEXPORT
define was renamed toLMMS_EXPORT
.RemoteVstPlugin.cpp
was ported to use C++11 threads instead of POSIX threads. mingw-std-threads is included as a submodule and used for MinGW versions that don't support C++11 threads natively.RemoteVstPlugin32
orRemoteVstPlugin64
. Thanks @tresf for the suggestion.As a positive side-effect, this enables 64bit VSTs for Linux (fixes #4103). Here's an AppImage: https://transfer.sh/LFwDB/lmms-1.2.0-rc5.137-linux-x86_64.AppImage