https://stackoverflow.com/questions/5373714/how-to-generate-a-calling-graph-for-c-code/5373814#5373814
ここの記載を参考にやってみた、というお話です。
やってみた、調べた、をメモがてら残そうと思った記事なので、話の裏どりはあまりしていません。
検証環境
- MacOS11.1
- clang++(homebrew) 11.0.0
homebrewで必要なツールをインストール
- macにプリインストールされているllvmではoptコマンドが入っていないので、homebrewを使ってインストールしました。
- dotファイルのプレビュー用にgraphvizというソフトをインストールしました。
記事を参考に実行
dotファイルの作成
下記のコマンドを実行することで、main_cpp.callgraph.dotというファイルが出力されます。
/usr/local/opt/llvm/bin/clang++ -S -emit-llvm main.cpp -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -o - | /usr/local/opt/llvm/bin/opt -analyze -dot-callgraph --callgraph-dot-filename-prefix=main_cpp
オプション。
clang++
- -isysroot
- sysrootを起点にusr/includeなどのヘッダファイルのディレクトリを探しに行きます。macでは/Library/Developer/CommandLineTools/SDKs/MacOSX.sdkになると思います。(これを指定しないとinclude_nextディレクティブで指定されているヘッダファイルを見つからなくてコンパイルが通りませんでした。参考 : https://qiita.com/coil_msp123/items/00bfa7a1e42602883882)
- -S
- プリプロセスとコンパイルだけ。リンクはしない、ってことだと理解。
- -emit-llvm
- アセンブラやオブジェクトファイルの表現として、LLVMの表現形式を利用。
- -o -
- -oが出力ファイル名を指定。 多分標準出力に結果を出力、だと思ったのですが、パッと文献を見つけられなかったので深追いはしていません。
opt
opt自体はllvmの各パスを調査するためのツール、みたいな説明でしたがllvmにおけるパスの意味がしっかりわかっていないので深追いはしません。
- -analyze
- 分析を行う。最適化なし。
- -dot-callgraph
- dot形式でグラフを出力
- --callgraph-dot-filename-prefix
- dotファイルの接頭辞です。指定しないと<stdin>が用いられて扱いにくいファイルができます。(このオプションは—help-hiddenで確認できます。参考 : https://nothingcosmos.wiki.fc2.com/wiki/optの概要)
dotファイルをpngに
dotコマンド(Graphviz)は/usr/local/binにインストールされる。
dot -Tpng -ocallgraph.png main_cpp.callgraph.dot
オプションは-Tで形式指定、-oで出力ファイル名、という感じだと思う。