Using GraphViz as an embeddable library

Hello Folks; I'm trying to embed GraphViz as a library into my C++/Qt project in OSX. I would like to do this to prevent having the user from having to install Graphviz.

However, when I try to create a graph with the FDP layout I receive the following error message from my application :

Error: Layout type: "fdp" not recognized.

Here's the code I'm using to set the layout:


void GraphVizModel::ApplyLayout()
{
DEBUG_METHOD();
try {
// m_GVC is of type GVC_t*
// m_Graph is of type Agraph_t*
gvFreeLayout(m_GVC, m_Graph);
char* engine="fdp";
agsafeset(m_Graph, (char*)"layout", engine, engine);
if(gvLayout(m_GVC, m_Graph, engine) != 0)
{
// My own class to pop a dialog with an error message
DialogHelper dh;
dh.ShowErrorMessageGUI(qApp->applicationDirPath(),
tr("Unable to apply layout: %1: \"%2\"")
.arg(agerrors())
.arg(QString::fromLocal8Bit(aglasterr())),
tr("GraphVizModel Error"));
}
// Output the dot definition for debugging
qDebug() << "==== agwrite() ====";
agwrite(m_Graph, stdout);
}
catch(std::exception &e)
{
QLOG_ERROR() << "Error in " << QsLogging::Logger::instance().TruncateFileName(__FILE__).append("->").append(__FUNCTION__)<< e.what();
}
}

Here's what I've done so far to attempt to get GraphViz to be embedded in my application:

  1. Included libcdt, libcgraph, libgvc, libexpat, libltdl, libpathplan, libxdot, and libz within my application in /Contents/Frameworks.
  2. Used the install_name_tool to change the paths in those libraries to be "@executable_path/../Frameworks/[library].dylib, i.e.:


> otool -L ./libgvc.6.dylib
libgvc.6.dylib:
/opt/local/lib/libgvc.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/../Frameworks/libltdl.7.dylib (compatibility version 11.0.0, current version 11.0.0)
@executable_path/../Frameworks/libxdot.4.dylib (compatibility version 5.0.0, current version 5.0.0)
@executable_path/../Frameworks/libcdt.5.dylib (compatibility version 6.0.0, current version 6.0.0)
@executable_path/../Frameworks/libcgraph.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/../Frameworks/libpathplan.4.dylib (compatibility version 5.0.0, current version 5.0.0)
@executable_path/../Frameworks/libexpat.1.dylib (compatibility version 8.0.0, current version 8.0.0)
@executable_path/../Frameworks/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

Is it possible to embed GraphViz as a library in an application? If so, what am I missing? Thank you very much, Squimbelly

By default, Graphviz consists

By default, Graphviz consists of a small core library gvc. When you invoke a layout program, gvc dynamically loads the appropriate plug-in dynamic library. If libgvc*dylib is in the directory $DIR, gvc will look for the plug-ins in $DIR/graphviz, so you will need to provide a copy of the graphviz sub-directory in the same relative position in your package. (This directory can be placed elsewhere, in which case you can use an environment variable to indicate its whereabouts, but the libraries still need to be provided.)

Alternatively, your code can create a GVC_t which will cause a list of desired plug-ins to be statically linked in. And there are other options in between. Let me know if you wish to pursue this latter course.

Just to clarify

Hello Erg;

Thank you very much for your reply.

Simply to clarify, so that I understand you properly: I installed Graphviz with homebrew, so I've a directory /usr/local/Graphviz/2.38.0. As well, I'm storing libgvc.dylib in MyApp.app/Contents/Frameworks.

Are you saying that I should copy /usr/local/Graphviz/2.38.0/libs/graphviz to MyApp.app/Contents/Frameworks/graphviz?

Thank you,

ST

Just to clarify...

Hello Erg;

Thank you very much for your reply.

To clarify that I understand you properly: I installed Graphviz via homebrew, and therefore have a directory /usr/local/Graphviz/2.38.0/.

Are you saying that I should include the directory /usr/local/Graphviz/2.38.0/lib/graphviz in my package, as a peer of libgvc.dylib?

To clarify what I'm saying:

  1. I'm storing libgvc.dylib in Myapp.app/Contents/Frameworks/libgvc.dylib
  2. I should copy /usr/local/Graphviz/2.38.0/lib/graphviz to Myapp.app/Contents/Frameworks/graphviz

Thank you,

ST

Yes. Obviously, if you still

Yes. Obviously, if you still have problems, let me know.

Thank you Erg, will do. ST

Thank you Erg, will do.

ST

Recent comments