Specifying GraphViz plugins folder under MacOS?

Hi all,

I’m maintaining a C++/Qt application that uses GraphViz to render diagrams using the “neato” plugin. Overall it’s working fine.

One issue is that GraphViz needs to find the file libgvplugin_neato_layout.6.dylib at runtime in order to work. When the application is built using our Jenkins build server, that’s no problem; the build-script is set up to copy that file (along with all of the other necessary files) into MyApp.app/Contents/Frameworks, so everything “just works” when the user installs the app.

My question is about developer builds, though – when building the app locally on my machine using qmake, qmake doesn’t know that the plugin files need to be copied in to the Frameworks folder, so after I manually build the program (using qmake ; make) and try to run it, I get a crash-on-startup (as shown below). Then I have to run a separate shell script to copy the files over, and after that the app runs okay.

My question is, is there any way that I could avoid having to copy the files over in this situation, e.g. by programmatically specifying a directory-path where graphviz should look to find its plugins? That would be a bit more elegant than having to make a copy of the plugins every time I do a clean build.

FWIW I tried adding the path to the plugins to my LD_LIBRARY_PATH environment variable, but that did not seem to make any difference.

Thanks,
Jeremy


Termination Reason: Namespace DYLD, Code 1 Library missing
Library not loaded: @rpath/libgvplugin_neato_layout.6.dylib
Referenced from: /Users/USER/*/MyApp.app/Contents/MacOS/MyApp
Reason: tried: ‘/Users/jaf/sandbox/apps/MyApp/build/release/MyApp.app/Contents/Frameworks/libgvplugin_neato_layout.6.dylib’ (no such file),
‘/Users/jaf/qt-everywhere-src-5.15.14/qtbase/lib/libgvplugin_neato_layout.6.dylib’ (no such file),
‘/System/Volumes/Preboot/Cryptexes/OS/Users/jaf/qt-everywhere-src-5.15.14/qtbase/lib/libgvplugin_neato_layout.6.dylib’ (no such file),
‘/Users/jaf/sandbox/apps/MyApp/build/release/MyApp.app/Contents/Frameworks/libgvplugin_neato_layout.6.dylib’ (no such file),
‘/Users/jaf/qt-everywhere-src-5.15.14/qtbase/lib/libgvplugin_neato_layout.6.dylib’ (no such file),
‘/System/Volumes/Preboot/Cryptexes/OS/Users/jaf/qt-everywhere-src-5.15.14/qtbase/lib/libgvplugin_neato_layout.6.dylib’ (no such file),
‘/usr/local/lib/libgvplugin_neato_layout.6.dylib’ (no
(terminated at launch; ignore backtrace)

Thread 0 Crashed:
0 dyld 0x7ff81c258c42 __abort_with_payload + 10
1 dyld 0x7ff81c272fd7 abort_with_payload_wrapper_internal + 82
2 dyld 0x7ff81c273009 abort_with_payload + 9
3 dyld 0x7ff81c1f78f0 dyld4::halt(char const*) + 375
4 dyld 0x7ff81c1f4b71 dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 4526
5 dyld 0x7ff81c1f33bd start + 1805

Digging in to this a bit further, it appears that the problem arises because the GraphViz libraries are referenced via @rpath instead of via their absolute-file-paths:

$ otool -L ./MyApp.app/Contents/MacOS/MyApp
./MyApp.app/Contents/MacOS/MyApp:
        @rpath/libgvplugin_neato_layout.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        @rpath/libgvplugin_dot_layout.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        @rpath/libgvc.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        @rpath/libxdot.4.dylib (compatibility version 4.0.0, current version 4.0.0)
        @rpath/libcgraph.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        @rpath/libcdt.5.dylib (compatibility version 5.0.0, current version 5.0.0)
        @rpath/libpathplan.4.dylib (compatibility version 4.0.0, current version 4.0.0)
        /Users/jaf/sandbox/3rdparty/libsndfile/src/.libs/lib/libsndfile.1.dylib (compatibility version 2.0.0, current version 2.28.0)
        [...]

I’m not sure how/why that happens, though. Is there some way to force the absolute file-paths to be used in this case (e.g. as is done for libsndfile.1.dylib above)?

relevant codeI admire your optimism :-). In the last few months, with our failed migration to Mac M1 in gitlab, oops I forgot my homework, graphviz MacOS support has become so thin that MacOS is being “temporarily” dropped from the CI build in the hopes that we can at least make new releases again. John Ellson probably wrote the plugin loader and related config file code, long ago, and hopefully, is now relaxing on a beautiful beach somewhere.

It turns out the relevant code is: lib/gvc/gvconfig.c · main · graphviz / graphviz · GitLab which gives some hopes you could try setting the GVBINDIR [sic] environment variable. Otherwise, someone who feels motivated needs to read the code and try to reconstruct what is going on here.

Possibly someone else with more knowledge about this may want to weigh in.

Best regards
Stephen North

I think you want DYLD_LIBRARY_PATH on macOS.

Yes, setting DYLD_LIBRARY_PATH did the trick. Thanks! :slight_smile:

Thanks. We should document this, er, somewhere.