macospluginsdynamic-linkingdylib

What happens when two macOS .plugin depend on same .dylib and each bundles it separately inside plugins' folder?


I have two plugins pluginA.plugin and pluginB.plugin which are both depend on same library libC.dylib. When plugins are built, I recursively go over dynamic dependencies (use otool -L), copy all dependencies inside each plugin's libs folder and adjust dependencies paths using install_name_tool, i.e. "carrying all all my stuff with me" approach.

I'm trying to understand what is happening when those two plugins will be loaded by some program? Will libC.dylib be loaded twice and this will cause runtime crash? Or will runtime realize that there are two copies of the same dylib (based on versions?) and use just one?


Solution

  • The order of dynamic library search and load is described in Apple's Dynamic Library Usage Guidelines

    In short, if paths to depended library in your plugins matches then this library will be loaded only once. On every next load only internal counter will be increased:

    The dlopen function returns the same library handle it returned in the first call, but it also increments the reference count associated with the handle

    If paths to library is different than different copies of library will be loaded.

    Note: While checking whether the library is already loaded, the absolute path to it is used. It may be directly set in dependency, discovered during search in global directories or resolved from @rpath.

    And about potential confilcts during symbol resolving:

    Name conflicts between dynamic shared libraries are not discovered at compile time, link time, or runtime. The dlsym function uses string matching to find symbols. If two libraries use the same name for a function, the dynamic loader returns the first one that matches the symbol name given to dlsym.

    So several copies will not crash program if both plugins uses the same library. If they expect different libraries under the same name than it's a big problem and you should use version compatibility mechanism - see Dynamic Library Design Guidelines