使用Boost Graphviz读取图时遇链接错误求助
read_graphviz and Custom Vertex/Edge Structures Problem Description
I'm trying to read the following Graphviz dot structure using Boost's Graphviz module:
graph G { 0[label="1"]; 1[label="0"]; 2[label="1"]; 3[label="1"]; 0--1 [label="1.2857"]; 1--2 [label="4.86712"]; 1--3 [label="2.29344"]; }
But every compilation throws an undefined reference error. I've tried compiling with g++ -lboost_graph test.cpp and even tried including <libs/graph/src/read_graphviz_new.cpp> (which breaks the build entirely).
Error Message
/tmp/ccnZnPad.o: In function "bool boost::read_graphviz_new<boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge, boost::no_property, boost::listS> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge, boost::no_property, boost::listS>&, boost::dynamic_properties&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)": test.cpp(.text._ZN5boost17read_graphviz_newINS_14adjacency_listINS_4vecSES2_NS_11undirectedSE6Vertex4EdgeNS_11no_propertyENS_5listSEEEEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_RNS_18dynamic_propertiesESG_[_ZN5boost17read_graphviz_newINS_14adjacency_listINS_4vecSES2_NS_11undirectedSE6Vertex4EdgeNS_11no_propertyENS_5listSEEEEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_RNS_18dynamic_propertiesESG_]+0x98): undefined reference to `boost::detail::graph::read_graphviz_new(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, boost::detail::graph::mutate_graph*)' collect2: error: ld returned 1 exit status
My Code
#include <fstream> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphviz.hpp> #include <boost/property_map/dynamic_property_map.hpp> //#include <libs/graph/src/read_graphviz_new.cpp> //breaks if I try to include #include <boost/graph/graph_utility.hpp> struct Vertex { bool isLeaf; }; struct Edge { double weight; }; typedef boost::adjacency_list<boost::vecS,boost::vecS, boost::undirectedS, Vertex, Edge> Graph; int main() { Graph g; boost::dynamic_properties dp; dp.property("label", get(&Vertex::isLeaf, g)); dp.property("label", get(&Edge::weight, g)); std::ifstream dot("baseTree.dot"); boost::read_graphviz(dot,g,dp); write_graphviz_dp(std::cout, g, dp); }
Solution
1. Fix the Linker Error (Undefined Reference)
The error happens because the implementation of read_graphviz_new (used internally by read_graphviz) isn't being linked into your binary. Here are two ways to fix this:
Option 1: Compile with the Boost Graph source file
Find theread_graphviz_new.cppfile in your Boost installation (usually located inboost/libs/graph/src/). Include it directly in your compile command:g++ test.cpp /path/to/boost/libs/graph/src/read_graphviz_new.cpp -lboost_graph -o testReplace
/path/to/boostwith your actual Boost library path (e.g.,/usr/local/include/booston Linux, or your installed Boost directory on Windows/macOS).Option 2: Install the full Boost Graph development package
If you're using a package manager (likeapton Ubuntu), make sure you have the complete development library installed:sudo apt install libboost-graph-devSome distributions include the
read_graphvizimplementation in the precompiledlibboost_graph.solibrary, so your original compile command may work after installing this package.
2. Fix Property Mapping Issues
Even after fixing the linker error, your code will fail due to type mismatches and conflicting property names:
Conflicting "label" properties: You've mapped both vertex and edge data to the same
"label"property. While Boost can distinguish between vertex/edge properties contextually, this is error-prone. It's safer to use distinct names if possible, or ensure the types align with the dot file.Type mismatch for
Vertex::isLeaf: Your dot file uses string values ("1","0") for vertex labels, butVertex::isLeafis abool. This will cause parsing failures. You have two options:Option A: Update the Vertex structure to match the dot file
ChangeisLeafto astd::stringto directly accept the label values:struct Vertex { std::string label; };Then update the property mapping:
dp.property("label", get(&Vertex::label, g)); dp.property("label", get(&Edge::weight, g));Option B: Add a type converter
Keep thebool isLeaffield, but use atransform_value_property_mapto convert the string values from the dot file to booleans:#include <boost/property_map/transform_value_property_map.hpp> // Helper function to convert "1"/"0" strings to bool bool string_to_bool(const std::string& s) { return s == "1"; } int main() { // ... auto leaf_map = boost::make_transform_value_property_map( string_to_bool, get(&Vertex::isLeaf, g) ); dp.property("label", leaf_map); dp.property("label", get(&Edge::weight, g)); // ... }
内容的提问来源于stack exchange,提问作者Sailanarmo

