モダンなC, C++の開発環境の構築方法
まだC, C++がないようなので書いてみた。主にLinux(DebianとかUbuntu)での環境構築について。
コンパイラ
まずはapt-getでコンパイラをインストールする。UbuntuやDebianなら以下のコマンドでgccやg++および標準ライブラリ等がインストールされる。
$ sudo apt-get install build-essential
ビルドツール
C, C++のビルドツールといえばまずmakeが浮かぶけど、最近ではSConsやCMakeなどの代替ツールでビルドするOSSを見かけることが増えてきた感がある。とはいえ、依然としてビルドにmakeが必要なプロジェクトはたくさんあるので、とりあえずmakeは入れる。
$ sudo apt-get install make
テスト
CならCUnit、C++ならgoogletestがオススメ。ほかにもCppUnitがあるけど、何というかあれはCUnitをものすごく書きにくくしたような物に仕上がっているので、個人的にオススメできない。
$ sudo apt-get install libcunit1 libcunit1-dev # CUnit $ sudo apt-get install libgtest0 libgtest-dev # googletest
テストカバレッジ
テストカバレッジにはgcovを使う。これはGCCに組み込まれているものと考えていい。
$ gcc -coverage -o prog prog.c $ ./prog $ gcov prog.gcda File 'prog.c' Lines executed:87.25% of 102 $
上記の通りにコマンドを実行するとprog.gcovというファイルができる。また、この場合のカバレッジ率は87.25%になっている。gcovの中身は以下のような感じ。「#」で始まっている行が実行されていない(テストできていないこと)を表している。
6146: 154: for (int i=0;i<c;++i) { 6139: 155: fnv_ent_t *tail = ents[i].next; 12366: 156: while (tail) { 88: 157: fnv_ent_t *current = tail; 88: 158: tail = tail->next; 88: 159: FNV_FREE(current); -: 160: } -: 161: } 7: 162: FNV_FREE(tbl); 7: 163:} -: 164: -: 165:/** -: 166: * print entries of hash table -: 167: */ #####: 168:void fnv_tbl_print(fnv_tbl_t *tbl, size_t c) { #####: 169: fnv_ent_t *ents = tbl->ents; #####: 170: for (int i=0;i<c;++i) { #####: 171: fnv_ent_t *ent = &ents[i]; #####: 172: if (ent->k == NULL) continue; #####: 173: printf("i = %d, key = %s, val = %s", i, ent->k, (char *)ent->v); #####: 174: if (ent->next != NULL) { #####: 175: fnv_ent_t *tail = ent->next; #####: 176: while (tail) { #####: 177: printf(" -> key = %s, val = %s", tail->k, (char *)tail->v); #####: 178: tail = tail->next; -: 179: } -: 180: } #####: 181: printf("\n"); -: 182: } #####: 183:}
プロファイラ
C, C++のプロファイラだとgprofあるいはgoogle-perftools等がある。(追記:gprofはoprofileではなくbinutilsをインストールする。 2010/8/1 12:10)
$ sudo apt-get install binutils # gprof(最初から入ってるかも) $ sudo apt-get install libgoogle-perftools0 libgoogle-perftools-dev # google-peftools
ソースコード索引
C, C++のソースコード索引にはGNU GLOBALがオススメ。etagsやctagsにはない複数候補への対応や定義元だけでなく参照元へのジャンプや検索をサポートしているのがとても便利。あとエディタに依存しない。Emacs使いならgtags.el、vim使いならgtags.vimをインストールしよう。この二つのファイルはGNU GLOBALのソースコードに含まれている。
$ sudo apt-get install global
索引を生成するにはソースコードがあるディレクトリでgtagsコマンドを実行する。
$ gtags -v # -v:verbose
gtagsは既に索引があるかどうかに関わらず最初から索引を全部作り直すので、既にある索引を更新する場合はglobalコマンドに-uを付加して実行する。
$ global -uv # -v:verbose
パッケージシステム
C, C++においてPerlのCPANやRubyのgems、PHPのPEARに相当するパッケージシステムは存在しない。でもまあ基本的に開発に最低限必要なパッケージはyumとかaptで十分カバーできるので、特に困らない。むしろ複数のパッケージシステム(yumとPEARとか)をごちゃ混ぜに扱ったり、統一するためにrpmやdebパッケージをいちいち作らなければいけないケースはLLに比べて少ないと思う。
たまにはGCC以外でもビルドしてみよう
僕は普段からLinux上でほぼCUIなターミナルで開発しているけど、自分が作ってるライブラリの動作確認のためにWindows7(64bit版)を立ち上げてVisual Studioでビルドすることがたまにある。LinuxやMacでは問題なく動いていたのにWindowsだとそもそもコンパイルが通らないというケースもある。*1それに開発者がWindows上での動作を完全には保証しない方針を採っているのだとしてもVisual Studioはコンパイラのチェックが(デフォルトの)GCCに比べて厳しいので、プログラムをVisual Studioのコンパイラに通すだけでもプログラムの潜在的なリスクを検出するのには役立つ。GCCでも適切に複数のオプションを付加すればいいんだろうけど、真面目に付加していくと結構な量になるし、すべての警告オプションを付けるのもアレなので、自分が必要だと思うオプションを適宜付加していくのが正しい選択だと思う。でも少なくとも-Wallくらいは付けようね。
その他の言語
*1:例:unistd.hがないとかstdint.hがないとか言われて