Unable to host VST3 plugins on macOS "The bundle is damaged or missing necessary resources."

Hi,
I’ve been trying to host a VST3 on macOS (Mojave 10.14.6). For know i’m trying the very simple following code:

AudioPluginFormatManager formatManager;
formatManager.addFormat(new VST3PluginFormat());
KnownPluginList pluginList;
OwnedArray<PluginDescription> typesFound;

String path { "/Path/to/plugin.vst3" };
pluginList.scanAndAddDragAndDroppedFiles(formatManager, StringArray(path), typesFound);

for (PluginDescription* desc : typesFound)
{
  if (desc->fileOrIdentifier == String(path))
  {
    DBG("loaded");
  }
}

This works fine in an Xcode project generated by the Projucer, but fails at runtime in my project which is built using CMake. I’ve tried with both a Juce-made VST3 and a non-Juce made VST3. I’m pretty confident the issue comes from the host as both plugins load fine in my Projucer generated test app.

I’m getting an assert in IPluginFactory* JUCE_CALLTYPE getPluginFactory() in juce_VST3PluginFormat.cpp. This assert is because the CFBundleLoadExecutableAndReturnError() call in the open() method of that same file fails, and returns the following error: “The bundle is damaged or missing necessary resources.”

I imagine that my project build settings differ from the Projucer generated settings and cause the issue. I’ve been playing “Spot the difference” for a day now, and I can’t figure out what might be causing this error. Any ideas?

So only the build system changes? You’re not using different versions of JUCE or the VST3 headers by accident?

Have you tried building the AudioPluginHost from JUCE using CMake to see whether it can load a VST3 plugin?

Which generator are you using with CMake? If you are using the Xcode generator, you could upload the project.pbxproj file (inside the .xcodeproj folder) generated by CMake and the one generated by Projucer, and I can take a look at them.

I would be more than happy to help you solve this problem, but with that little information it is very hard to guess :sweat_smile:

Hi,

Thanks for your help!
Sadly I can’t share the actual project files publicly, so I’ve just spent a few hours trying to create a minimal example (generating an Xcode project file using the projucer or Cmake) to try to reproduce the issue, but I cant have that new Cmake project fail in the same way.

My project uses some options which are provided by global company macros, I suspect that one of them might be causing the issue. I’ll do more digging on that side.

I’m using juce 5.4.2 and the embedded VST3 SDK.

I’m now wondering what might be preventing the plugin (at that stage, it’s just any other shared library) from loading. I’m pretty sure it’s because of some dependencies of the plugin that should be provided by the host, but I’m not super familiar with the way these things work…

Ok so I finally found out what was causing the problem. My host has the hardened runtime enabled, and therefore needs the correct entitlements to be able to load dynamic libraries that are signed by a different developper… The error message “The bundle is damaged or missing necessary resources.” is very misleading…

Here is the Cmake fix:

set_target_properties(<Target> PROPERTIES 
	XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES
    XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/pathTo/entitlements.xcent"
)

With the entitlements.xcentfile contents being:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
</dict>
</plist>
4 Likes

I just went through the same process, with that assert in getPluginFactory. And the fix was the same as what you describe - adding the correct entitlement for an app with hardened runtime.

(In Projucer, this entitlement is “Runtime Exceptions: Disable Library Validation”.)

The comment above the assert in getPluginFactory could really use some additional hints. Currently it says:

// The plugin NEEDS to provide a factory to be able to be called a VST3!
// Most likely you are trying to load a 32-bit VST3 from a 64-bit host
// or vice versa.

And that really led me on a wild goose chase.