GraphvizをC++のライブラリとして使用する

## 目的

- GraphvizをC++から使用して、グラフを描画する

## 環境

- M1 MacBook Air Sonoma 14.7.1
- GCC 14.2.0
- Homebrew 4.4.13
- CMake 3.31.3
- Graphviz 12.2.1

## 前提条件

- MacOSである
- Homebrewが使用可能である
- Cmakeが使用可能である
- GCCの環境が整っている

## 手順

### Graphvizをinstall

```shell
$ brew install graphviz
```

https://formulae.brew.sh/formula/graphviz

installされたか確認する。

```shell
$ ls -l /opt/homebrew/lib/ | grep graphviz            
lrwxr-xr-x    1 user  admin     38 Dec 26 15:16 graphviz -> ../Cellar/graphviz/12.2.1/lib/graphviz
lrwxr-xr-x    1 user  admin     44 Dec 26 15:16 libcdt.5.dylib -> ../Cellar/graphviz/12.2.1/lib/libcdt.5.dylib
lrwxr-xr-x    1 user  admin     42 Dec 26 15:16 libcdt.dylib -> ../Cellar/graphviz/12.2.1/lib/libcdt.dylib
lrwxr-xr-x    1 user  admin     47 Dec 26 15:16 libcgraph.6.dylib -> ../Cellar/graphviz/12.2.1/lib/libcgraph.6.dylib
lrwxr-xr-x    1 user  admin     45 Dec 26 15:16 libcgraph.dylib -> ../Cellar/graphviz/12.2.1/lib/libcgraph.dylib
lrwxr-xr-x    1 user  admin     44 Dec 26 15:16 libgvc.6.dylib -> ../Cellar/graphviz/12.2.1/lib/libgvc.6.dylib
lrwxr-xr-x    1 user  admin     42 Dec 26 15:16 libgvc.dylib -> ../Cellar/graphviz/12.2.1/lib/libgvc.dylib
lrwxr-xr-x    1 user  admin     45 Dec 26 15:16 libgvpr.2.dylib -> ../Cellar/graphviz/12.2.1/lib/libgvpr.2.dylib
lrwxr-xr-x    1 user  admin     43 Dec 26 15:16 libgvpr.dylib -> ../Cellar/graphviz/12.2.1/lib/libgvpr.dylib
lrwxr-xr-x    1 user  admin     49 Dec 26 15:16 libpathplan.4.dylib -> ../Cellar/graphviz/12.2.1/lib/libpathplan.4.dylib
lrwxr-xr-x    1 user  admin     47 Dec 26 15:16 libpathplan.dylib -> ../Cellar/graphviz/12.2.1/lib/libpathplan.dylib
lrwxr-xr-x    1 user  admin     45 Dec 26 15:16 libxdot.4.dylib -> ../Cellar/graphviz/12.2.1/lib/libxdot.4.dylib
lrwxr-xr-x    1 user  admin     43 Dec 26 15:16 libxdot.dylib -> ../Cellar/graphviz/12.2.1/lib/libxdot.dylib
```

### テスト用プロジェクトを作成

```shell
graphviz_test
├── CMakeLists.txt
└── main.cpp

1 directory, 3 files
```

### サンプルコード

**main.cpp**

```c++
#include <iostream>
#include <cstring>
#include <graphviz/gvc.h>

int main()
{
  GVC_t *gvc = gvContext(); // Create a Graphviz context

  // Create a new graph
  Agraph_t *g = agopen("my_graph", Agdirected, nullptr);

  // グラフにラベルを設定
  agsafeset(g, "label", "My Graph", "");

  // Create nodes
  Agnode_t *n1 = agnode(g, "Node 1", true);
  Agnode_t *n2 = agnode(g, "Node 2", true);
  Agnode_t *n3 = agnode(g, "Node 3", true);

  // Create edges
  Agedge_t *e1 = agedge(g, n1, n2, nullptr, true);
  Agedge_t *e2 = agedge(g, n2, n3, nullptr, true);
  Agedge_t *e3 = agedge(g, n3, n1, nullptr, true);

  // edgeにラベルを設定
  agsafeset(e1, "label", "Edge 1", "");

  // 受理状態を表示
  agsafeset(n1, "shape", "doublecircle", "");

  // set graph attributes
  agsafeset(g, "rankdir", "LR", "");

  // Generate output
  gvLayout(gvc, g, "dot");
  gvRender(gvc, g, "png", fopen("graph.png", "w"));

  // Clean up
  gvFreeLayout(gvc, g);
  agclose(g);
  gvFreeContext(gvc);

  std::cout << "Graph created successfully!" << std::endl;
  return 0;
}

```

### CMakeLists.txtを作成

```cmake
# cmakeのバージョンを指定する
cmake_minimum_required(VERSION 3.10)

set(CMAKE_CXX_STANDARD 11)

# プロジェクトの名前を指定する
project(graphviz_test)

# 実行ファイルを作成
add_executable(
    graphviz_test
    main.cpp
)

# ライブラリをリンク
target_link_libraries(
    graphviz_test
    cgraph
    gvc
)

```

### ビルド

```shell
$ cmake -S . -B build
$ cmake --build build
```

### 実行

```shell
$ ./build/graphviz_test
Graph created successfully!
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2630841/489b42fb-57c3-21aa-61d6-1034c6299a3e.png)
graph.png が生成されます。


## 参考

https://hirokio.jp/programming/cpp-graphviz/

https://formulae.brew.sh/formula/graphviz

https://graphviz.org/docs/library/