專欄導讀
本專欄第一篇文章「專欄開篇」列出了專欄的完整目錄,按目錄順序閱讀,有助於你的理解。
前言
codeviz官網:https://github.com/petersenna/codeviz
codeviz是一款分析C/C++源代碼函數調用關係的工具,通過它可以生成函數調用關係圖(call graph)。其基本原理是給gcc打個補丁,讓gcc在編譯每個源文件時,將其中的函數的調用關係以文本形式保存在 .cdepn 文件中,然後使用 Perl 腳本(genfull和gengraph)把 .cdepn 文件轉成 dot 文件,最後由graphviz 將dot文件轉成圖片文件(如gif、png等)。
給gcc打補丁的過程是:
1. 下載codeviz要求的特定版本的gcc源碼(跟你環境中已安裝的gcc是不同的);
2. 使用codeviz的補丁文件修改gcc源碼(即打補丁);
3. 編譯gcc源碼,得到打完補丁的gcc可執行文件(利用這個gcc可執行文件再來編譯我們項目的源文件,從而得到函數調用關係);
在安裝codeviz的過程中,最難的也就是編譯打完補丁的gcc源碼,會遇到各種編譯出錯,得逐個解決,大部分時間也是耗在這上面。整個安裝過程大致步驟如下:
- 安裝graphviz,因爲codeviz依賴graphviz,所以要先安裝graphviz。
- 安裝codeviz,這裏麪包括腳本自動下載依賴的gcc源碼,自動打補丁,自動編譯gcc源碼,最後安裝codeviz。
安裝graphviz
codeviz 依賴 graphviz,所以要先安裝 graphviz:
# sudo apt-get install graphviz
安裝codeviz
codeviz源碼包下載地址:
https://web.archive.org/web/20150502053825/http://www.csn.ul.ie/~mel/projects/codeviz/#download
安裝步驟:
# wget https://web.archive.org/web/20150802030038/http://www.csn.ul.ie/~mel/projects/codeviz/codeviz-1.0.12.tar.gz
# tar zxvf codeviz-1.0.12.tar.gz
# cd codeviz-1.0.12/
# ./configure && make && make install
執行make的過程中,codeviz的安裝腳本 compilers/install_gcc-4.6.2.sh 會自動檢測 compilers 目錄下是否有其依賴的 gcc 版本的源碼包(版本codeviz-1.0.12 依賴的是 gcc-4.6.2),如果沒有,則會將 gcc-4.6.2.tar.gz 源碼自動下載到 compilers 目錄中,並將 gcc-4.6.2.tar.gz 解壓到 gcc-graph 目錄,然後打上補丁,最後開始編譯。這個過程,其實是codeviz-1.0.12/compilers/install_gcc-4.6.2.sh腳本自動實現的。
codeviz-1.0.12/
├── bin
├── compilers
│ ├── install_gcc-4.6.2.sh <-- 執行該腳本將:
│ ├── gcc-4.6.2.tar.gz 1. download gcc-4.6.2.tar.gz
│ ├── gcc-graph 2. mkdir gcc-graph
│ │ ├── gcc-4.6.2 3. untar it into gcc-graph
│ ├── gcc-patches 4. patch it
│ 5. compile it
我在編譯的過程中,遇到了以下幾個問題,最後一個問題沒能解決,所以安裝也宣告失敗,不管怎樣,把這次安裝過程做個記錄,留給需要的人蔘考。
問題1:無法自動下載gcc-4.6.2
如果出現無法正常下載gcc的情況,就要檢查下install_gcc-4.6.2.sh腳本了。截取該腳本部分內容:
#!/bin/bash
INSTALL_PATH=$HOME/gcc-graph
if [ "$1" != "" ]; then INSTALL_PATH=$1; fi
if [ "$2" = "compile-only" ]; then export COMPILE_ONLY=yes; fi
echo Installing gcc to $INSTALL_PATH
NCFTP=`which ncftpget`
EXIT=$?
if [ "$EXIT" != "0" ]; then
NCFTP=ftp
fi
if [ ! -e gcc-4.6.2.tar.gz ]; then
echo gcc-4.6.2.tar.gz not found, downloading
$NCFTP ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.6.2/gcc-4.6.2.tar.gz
if [ ! -e gcc-4.6.2.tar.gz ]; then
echo Failed to download gcc, download gcc-4.6.2.tar.gz from www.gnu.org
exit
fi
fi
......
因爲我的環境沒有安裝ncftpget,但有wget,所以我將:
NCFTP=`which ncftpget`
改爲:
NCFTP=`which wget`
就能順利下載gcc了。
當然,你也可以自己下載 gcc-4.6.2.tar.gz ,再把它拷貝到 codeviz-1.0.12/compilers 目錄中。我還是更傾向於修改 install_gcc-4.6.2.sh 腳本,讓這些過程「自動化」。
問題2:找不到依賴庫gmp、mpfr、mpc
編譯gcc-4.6.2的過程遇到如下錯誤:
configure: error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+.
這是因爲缺少相應的依賴庫,要先執行gcc源碼中自帶的依賴庫安裝腳本download_prerequisites,如下所示:
# cd codeviz-1.0.12/compilers/gcc-graph/gcc-4.6.2/
# ./contrib/download_prerequisites
注意:以上 cd 的路徑是有講究的,務必跟以上命令保持一致,這樣gmp、mpfr、mpc才能下載到codeviz-1.0.12/compilers/gcc-graph/gcc-4.6.2/目錄下,才能保證順利編譯。
爲了讓這個過程「自動化」,也可以把以上命令放到 install_gcc-4.6.2.sh 腳本中去執行。當然,如果你的環境沒有報這個錯,就沒必要了。
問題3:linux-unwind.h編譯失敗
編譯gcc-4.6.2的過程遇到如下錯誤:
../../../../gcc-4.6.2/libgcc/../gcc/config/i386/linux-unwind.h:138:17: error: field ‘info’ has incomplete type
解決方法1:
這是因爲我的環境是linux 64-bit內核, struct siginfo不兼容64-bit內核,將以下文件:
codeviz-1.0.12/compilers/gcc-graph/gcc-4.6.2/gcc/config/i386/linux-unwind.h
中的 struct siginfo 替換爲siginfo_t 即可,因爲每次重新執行make,腳本install_gcc-4.6.2.sh都會重新解壓gcc-4.6.2並覆蓋linux-unwind.h,所以這樣的替換要在 install_gcc-4.6.2.sh 腳本中執行,按如下修改install_gcc-4.6.2.sh 腳本內容:
tar -zxf gcc-4.6.2.tar.gz -C gcc-graph || exit
sed -i 's/struct siginfo/siginfo_t/g' ./gcc-graph/gcc-4.6.2/gcc/config/i386/linux-unwind.h
即在解壓gcc-4.6.2後,使用sed命令將linux-unwind.h文件中的struct siginfo 替換爲siginfo_t,如此,重新執行make指令即可編譯通過。
解決方法2:
在腳本 install_gcc-4.6.2.sh 文件中增加編譯選項:
--disable-multilib
問題4:找不到crt1.o
編譯gcc-4.6.2的過程遇到如下錯誤:
cannot find crt1.o: No such file or directory
先找出crt1.o在哪(你的路徑可能跟我不一樣):
# find /usr/ -name crti.o
/usr/lib/x86_64-linux-gnu/crti.o
解決方法:
# export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu && make
問題5:找不到CXXABI_1.3.8
編譯gcc-4.6.2的過程遇到如下錯誤:
msgfmt: /opt/codeviz-1.0.12/compilers/gcc-graph/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/lib/x86_64-linux-gnu/libicuuc.so.55)
根據提示,查看其 libstdc++.so.6,確實沒有 CXXABI_1.3.8:
# strings /opt/codeviz-1.0.12/compilers/gcc-graph/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6 | grep CXXABI
CXXABI_1.3
CXXABI_1.3.1
CXXABI_1.3.2
CXXABI_1.3.3
CXXABI_1.3.4
CXXABI_1.3.5
CXXABI_1.3
CXXABI_1.3.2
CXXABI_1.3.1
CXXABI_1.3.5
CXXABI_1.3.4
CXXABI_1.3.3
嘗試了網上說的很多方法,該問題依然沒有解決,感覺跟版本依賴性有關,水挺深的,最終放棄,如果有讀者知道怎麼解決,誠盼你的留言告知。
總結
由於codeviz必須依賴特定版本的gcc(給其打補丁,並重新編譯),codeviz 的版本迭代遠遠跟不上gcc,造成安裝過於費勁(甚至以失敗告終,本次體驗就沒能安裝成功),讓人望而卻步