[BUG] Can't Load Video SDK Framework from Plugin

Description
My implementation of the Zoom Video SDK resides in a plugin that is loaded by another app.

  • The plugin is linked against all 24 of the Zoom Video SDK libraries (asproxy.framework, cmmlib.framework, etc.) and copies all of these into the Frameworks folder of my plugin.

  • I have set the Runpath Search Paths (@rpath) in XCode build settings set to @loader_path/../Frameworks

Yet the call

[[ZMVideoSDK sharedVideoSDK] initialize:initParams]

fails with

ZMVideoSDKErrors_Load_Module_Error

However, if I move all 24 libraries into the Frameworks folder of the main application (i.e., the one that loads the plugin) then the call to [[ZMVideoSDK sharedVideoSDK] initialize:initParams] succeeds and everything else works as expected.

It is important to note that calling

ZMVideoSDKInitParams *initParams = [[[ZMVideoSDKInitParams alloc] init] autorelease] 

works, which actually proves that the Video SDK libraries are being loaded successfully.

Are you calling [NSBundle mainBundle] in your internal code?

I have a strong suspicion that you are calling [NSBundle mainBundle] to get a path to one of the Zoom Video SDK libraries in your internal code. Because this ignores the @rpath, you end up looking in the Frameworks folder of the main application instead of the Frameworks folder of the plugin.

Which Desktop Video SDK version?
MacOS v1.1.0

To Reproduce(If applicable)
Steps to reproduce the behavior:

  1. Create a plugin that uses the Zoom Video SDK that will be loaded by some other app
  2. Link against that all 24 of the Zoom Video SDK and ensure they are copied to the Frameworks folder of the plugin (MyPlugin.bundle/Contents/Frameworks)
  3. When the plugin is loaded, attempt to init the Video SDK with [[ZMVideoSDK sharedVideoSDK] initialize:initParams]
  4. The call returns the error ZMVideoSDKErrors_Load_Module_Error

Device (please complete the following information):

  • Device: Apple MacBook Pro 15"
  • OS: macOS Mojave 10.13

Additional context

Thinking that you might be using the working directory, I tried changing the working directory to the plugin’s dylib, the plugin’s Frameworks folder and other paths related to the plugin. This did not prevent the error.

In addition, I have logging enabled for library loading this appears in the console output, showing that the libraries are actually being loaded upon calling [[ZMVideoSDKInitParams alloc] init]

dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/Zoom Instant Receiver
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/viper.framework/Versions/A/viper
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/tp.framework/Versions/A/tp
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/asproxy.framework/Versions/A/asproxy
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/protobuf.framework/Versions/A/protobuf
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/libssl.dylib
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/libminizip.dylib
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/curl64.framework/Versions/A/curl64
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/nydus.framework/Versions/A/nydus
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/libcrypto.dylib
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/util.framework/Versions/A/util
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/xmpp_framework.framework/Versions/A/xmpp_framework
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/VideoSDK.dylib
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/cmmlib.framework/Versions/A/cmmlib
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/ZMVideoSDK.framework/Versions/A/ZMVideoSDK
dyld: loaded: /Library/Application Support/XXXXXXX/XXXXXXXPlugins_x64/Zoom Instant Receiver.izzyplug/Contents/MacOS/…/Frameworks/libjson.dylib

Hi @mark_coniglio, thanks for the post.

It is entirely possible that your suspicions are correct, but there are some other potential causes of this behavior. Due to the complex structure of the SDK, it is also possible to import the SDK incorrectly in such a way that only certain areas of functionality will misbehave. Can you provide a screenshot of the SDK files in your project’s Build Phases in Xcode?

Thanks!

@jon.lieblich

Here’s the screenshot of the libraries.

As you can see, all the libraries are there in the Frameworks folder of my plugin:

In this configuration, the call ZMVideoSDKInitParams *initParams = [[[ZMVideoSDKInitParams alloc] init] autorelease] works as expected.

But when I call [[ZMVideoSDK sharedVideoSDK] initialize:initParams] it returns ZMVideoSDKErrors_Load_Module_Error

HOWEVER if I simply copy all 24 of those dylibs/Framworks/bundles from the plugin’s Frameworks folder to the Frameworks folder of the app that is loading the plugin, then everything works – the session opens, I can send video, etc. etc…

Best Wishes,
Mark

Hi @mark_coniglio,

Thanks for providing those screenshots. Can you please also confirm that you have also linked the binaries of the files listed in our documentation here?

Thanks!

@jon.lieblich

Dear Jon,

Thanks for pointing me to the link about the prerequisites for building on macOS. I had totally missed the bit about which libraries to include and which ones not too, i.e:

Select your project and navigate to the Build Phases tab. Open Link Binary With Libraries and ensure that only the follow SDK files are present:

  • libjson.dylib
  • libssl.dylib
  • libminizip.dylib
  • libcrypto.dylib
  • ZMVideoSDK.framework
  • ZMVideoSDK.dylib

Sadly, following this prerequisite didn’t solve the problem.

  1. I deleted all of the Zoom SDK libraries and frameworks from my app’s Frameworks folder.
  2. Checked that I was copying all 24 of those libraries to my plugin’s Frameworks folder
  3. Changed the “Link Binaries with Libraries” to include only the libraries listed above as shown in the screen shot below.

NOTE There is no library called ZMVideoSDK.dylib as listed in your requirements. I assume you mean VideoSDK.dylib which is in the 1.10 release.

link-binary-with-libraries

The error remains the same. When I execute the code below, I still get the ZMVideoSDKErrors_Load_Module_Error error.

ZMVideoSDKInitParams *initParams = [[[ZMVideoSDKInitParams alloc] init] autorelease];
// set domain
initParams.domain = @"https://zoom.us";
// set raw data memory mode
initParams.audioRawDataMemoryMode = ZMVideoSDKRawDataMemoryMode_Stack;
initParams.videoRawDataMemoryMode = ZMVideoSDKRawDataMemoryMode_Stack;
initParams.shareRawDataMemoryMode = ZMVideoSDKRawDataMemoryMode_Stack;
// set to enable indirect raw data
// set to enable SDK logging
initParams.enableLog = true;
// set to specify the prefix of the log file name
initParams.logFilePrefix = @"prefix";
NSDebugLog(@"Zoom SDK Param Initialized");

NSDebugLog(@"About to Init Zoom SDK");
ZMVideoSDKErrors zoomErr = [[ZMVideoSDK sharedVideoSDK] initialize:initParams];
NSDebugLog(@"Init Zoom SDK Complete - Error = %d / %s", (int) zoomErr, ZMVideoSDKErrorToName(zoomErr));

As a further test, I did the following:

  1. Removed the phase that copied all of the Zoom Libraries to my plugin’s Framework’s folder. In other words, my plugin’s Frameworks folder was empty.
  2. Restored the 24 zoom libraries to my application’s Framework’s folder.
  3. Ran the app that uses the plugin

Upon doing this, the plugin works.

I believe this serves as pretty strong proof that your libraries are not respecting the value of @rpath (again, it’s set to @loader_path/../Frameworks as shown in the screen capture below.)

Thanks for the continued support,
Mark

Hi @mark_coniglio,

Thanks for giving that a try. Also regarding the incorrect dylib name, I submitted a ticket to our documentation team to have that corrected, thank you for pointing that out!

Based on the information you have provided, I think you may be correct. We will need to investigate this and let you know as soon as we have any updates.

Thanks!

@jon.lieblich

Dear Jon,

I spent quite a few hours with install_name_tool trying to adjust the rpaths entries of your code to attempt to get them to load. But I could not find a solution.

Since your team is going to look into this, I would humbly suggest that you reconfigure things so that all of those extra libraries reside in a Frameworks folder within the ZMVideoSDK framework. Like this

ZMVideoSDK.framework
– Versions
– – A
– – – Headers
– – – Modules
– – – Resources
– – – Frameworks
– – – – the 23 additional libraries
– – – ZMVideoSDK

This would make things so much cleaner: to work with the Zoom SDK, developers would only need link with the one framework, and also would need to copy only the ZMVideoSDK.framework to their app or plugins Frameworks folder.

Given that the ZMVideoSDK shows this in otool:

Load command 20
cmd LC_RPATH
cmdsize 40
path @loader_path/Frameworks (offset 12)

It seems like someone was already thinking in this direction. :wink:

Best Wishes,
Mark

1 Like

Hi @mark_coniglio,

Thanks for the suggestion! We have actually discussed making the process of adding the SDK to a project in Xcode easier, but have not been able to improve that experience just yet. :slightly_smiling_face:

I will be sure to let you know if we are able to identify any workarounds for this, but I’m assuming that this will require an update to the SDK to fully resolve. Either way, I will be sure to keep you updated!

Thanks!

@jon.lieblich

Thanks for pursuing this.

For what it’s worth: not being one to give up, I made one last attempt to get these libraries out of the main app, I wrote a script to go through every one and use install_name_tool to change any reference to @rpath to a fixed path that was not within the app. The result was the same: the Framework loaded, but calling initialize resulted in ZMVideoSDKErrors_Load_Module_Error.

I can’t give my plugins to the testing team until this problem is addressed. So I’m hoping an update can come soon.

Best Wishes,
Mark

Hi @mark_coniglio,

Thanks for the update. We are still looking into this, but it is possible that this will require an SDK update to resolve. I will keep you updated as soon as we have any definite information.

Thanks!