RakeでC++をビルドする

ちょっとC++ソースコード書きたいときにVisual Studio立ち上げるのが億劫になったので、Vimでさくっと書ける環境を整えてます。

ただ、ビルドするのにmakefileを書きたくなかったので色々調べてたら、RakeでC++をビルドできるみたいなので書いてみました。

環境

Rakefile

一番単純なものはネットで検索すると出てくるんですが、少し物足りなかったので機能を追加しました。

  • ビルド, リビルド, クリーンを実装
  • 中間生成物(オブジェクトファイルなど)はビルド用ディレクトリに格納
  • 依存情報ファイル(.mf)を使ってヘッダファイルの依存関係に対応

rakefile for C++ source build.

解説

使い方は最初にRakefile内の定数を編集して、

CPPFLAGS = %w[]   # コンパイルオプション
LDFLAGS  = %w[]   # リンクオプション
INC_DIRS = []     # インクルードディレクトリ
LIB_DIRS = []     # ライブラリディレクトリ
TARGET   = "app"  # 生成する実行ファイル名

SRC_ROOT = "."    # ソースファイルが格納されているディレクトリ

LIBS = FileList[] # ライブラリファイル

ビルドするときは、

$ rake

生成したファイルを削除したいときは、

$ rake clean   # オブジェクトファイルなどの中間生成物のみ削除する
$ rake clobber # 実行ファイルとビルド用ディレクトリも削除する

リビルドしたいときは、

$ rake rebuild

という感じです。

今回はヘッダーファイルを含めた依存関係を扱いたかったのでその情報を"gcc -MM"でファイルに出力してるんですが、そのファイルの情報を使うときに問題が出て苦労しました。

Rakeにはimportというメソッドがあってこれで出力したファイルを読み込めるんですが、どうもソースファイルとオブジェクトファイルが同じディレクトリにないとうまく動かないようです。
でも今回はオブジェクトファイルなんかのビルド用中間ファイルは別ディレクトリに出力したかったので、自前でファイルを読み込んで依存関係を設定してます。

その設定はオブジェクトファイルの依存ファイルをdependenciesメソッドを呼び出して(154行目)動的に行っています。
dependenciesメソッドでは、

  1. file(depfile).invokeで、対象のオブジェクトファイルと対応する依存情報ファイルとの間に依存関係を設定して解決する。(95行目)
  2. load_depfileメソッドを呼び出して対象のオブジェクトファイルが依存しているファイル名のリストを取得する。(97行目)

という処理をしていて、1で依存情報ファイルを更新する必要があるときはそのファイルのルール(160行目)が呼び出されてファイルが更新される、という仕組みです。

わかると難しくないんですが、Rubyはほとんど書いたことがない上にRakeの仕組みを勉強しつつやってたら1週間くらいかかりました。 おかげでだいぶRubyにもRakeに慣れたんですが、まだまだ腕が足りないですね。がんばります。

参考

Boost.勉強会#14東京に参加してきました

初めましてlocaです。

3/1(土)のBoost.勉強会 #14 東京に参加してきて意識高まったので、ブログを始めて感想をまとめてみました。

Boost.勉強会 #14 東京

今回私は勉強会への参加自体が初だった上に優秀な人達がたくさん参加してたので、自分が行って大丈夫なのか不安でしたがとても楽しめました。

今回勉強会に参加して技術の勉強になった以上に、

  • 優秀な人達は相当な努力している
  • みんなほんとに楽しそうに発表を聞いたりコード書いたりしてる

と感じたのが一番印象深いです。

私は技術書を読んだりネットで技術記事を読んだりは結構してきたつもりですが、アウトプットを全然してませんでした。これを機に手を動かして学んだことをブログにまとめていきたいと思います。

全体の感想は以上で、以下から個々の発表の感想です。

cpprefjpを支える技術

cpprefjpはリファレンス以上の情報もあるのでそういう情報が知りたいときや、日本語でSTLの情報が知りたいときに見てます。

今のcpprefjpはgithubリポジトリにあるMarkdownからHTML生成してGoogle Sitesにアップロードしてるという話で、裏でいろいろ動いてると思ってませんでした。

Google Sitesからデータ持ってきたり、今のGoogle Sitesとの同期の仕組みを作るときの苦労話が聞けて面白かったです。

Boost.Graphの設計と、最短経路アルゴリズムの使い方いろいろ

Boost.Graphは前に少し触ったことがあったんですが、頂点を取るときにメンバ関数じゃなくてフリー関数のvertices()を使うのに違和感がありました。この方法だとBoost.GraphのアルゴリズムにBoost.Graphのコンセプトを満たすいろいろなグラフ型を適用できるようです。すごい。

プロパティマップは複数プロパティを持たせたいときにネストさせるのが好きじゃなかったんですが、バンドルを使うとクラスをプロパティに持たせられると聞いたのであとで調べてみようと思います。

最短経路アルゴリズムdijkstra_shortest_paths()の例ですが、正直この関数の使い方難しいなぁと感じました。 たぶん自分で使ってみたら理解できるのかなという感じです。 それと始点と終点を指定してその最短経路を求める関数がないのはなんででしょう? あったほうが便利な気がする・・・ スライド49ページの話がこれに関係してるかもしれないけれど、そのページの意味を理解できてないのでわかりません。

最短経路の方はあんまり消化できてないんですが、設計の話が勉強になりました。またBoost.Graphを使うときに役立ちそうです。

いつからFIFOがスケールしないと錯覚していた?

Elimination Stackはなんとなく理解はできたんですが、本題のElimination Queueはよく理解できませんでした。 でも発表は一番楽しかった!これ以上ないくらい早口でしたけどネタもあって楽しかったです。 とりあえず魔導書読み返してみます。

ロックフリー「今日はこのへんにしといてやらぁ」

余談ですが、FIFOってファイフォって発音するんですね。 今までフィーフォって言ってました。

glfw3 OpenGLを使ったGUIフレームワーク

OpenGL使ったGUIフレームワーク作ってるよという話でした。 私も簡単な3Dグラフィックスを使うプログラムを書くことがあるので、興味のある話でした。

ただ発表は全体的に言葉や説明が具体的でない感じで、なんだかもやっとしててよくわかりませんでした。 "他のオープンソースGUIとはちょっと違う"という所とか、具体的に比較して説明すると良かったと思います。

私は今までfreeglutを使ったりしてましたがボタンを簡単に配置したりできるフレームワークあるといいなぁと思っていたので今後に期待してます。

データサイエンスワールドからC++を眺めてみる

RとC++が連携できるのを知りました。それなら色々おもしろいことできそうで、とくにQt使ってパラメータをリアルタイムに変えてみるアプリが作れるのはどこかで使えそうだなと思いました。覚えておくと役に立ちそうです。

C++やBoostにはまだ統計処理まわりのライブラリが不足してるみたいですね。 私は統計処理界隈のことは全然わからないんですが、試行錯誤するところはC++よりPythonみたいなスクリプト言語のほうが適してるからな気がします。

パフォーマンスの要求はどうなんでしょう?Pythonで不十分ならC++系のライブラリも増えてくるのかなと思います。

.NETとかが当たり前にやってること、C++だとどうするか

C#関連のことを調べるときにいつもお世話になってるサイトの人でした。 唯一の1時間発表かつハイペースの発表にもかかわらず濃い内容をわかりやすく発表していて、聞くのは大変でしたがとても勉強になりました。 たくさん勉強になったんですが書くと長くなるので1つだけ書くと、yeildの実装の話を聞いて今まであまり理解できていなかったyeildの動作が腑に落ちたのが個人的に1番の収穫でした。

あ、勉強会の時はC#でググっても岩永さんのサイトでなかったんですが、今やったら2番目に出てきました。 かっこいい。

新しい並列for構文のご提案

マルチコア活用するコード書いてなくてすみません。

並列処理ライブラリの話とC++1y向けに提案されている並列拡張の話でした。 ライブラリの方は物自体は知っていましたが、後半のC++並列拡張は初めて聞きました。 STLアルゴリズムに並列処理を行うオーバーロードを追加するもので、第一引数に実行ポリシーを指定するだけで簡単に使えるのがすごくいいと思いました。 まだドラフトで変更されるかもしれないとのことでしたが、これはぜひほしいです。

それと情報をマトリックスにうまく整理できる人はちょっと尊敬します。とてもわかり易かったです。

魔導書発売記念:GPGPUの今からとこれから

GPGPU周りの基本とパフォーマンス/ワットやAPUなんかの最新情報がまとまっていてよかったです。 GPU関係の知識はPCWatchで仕入れてたんですが、知識の整理ができました。 それとAMDのAPUではメモリバンド幅が足りないと聞いて、そういえばそうだなと思う反面CPUとメモリアドレス共有できるので転送しなくてもよい部分もあると思うんですが、どうなんでしょう?実際に測ってみないとわからないですかね。

この記事書いてて思いたんですが、GPGPUってグラフィックスと物理シミュレーション以外だと何に使われてるんでしょう? GPGPUには興味あるんですがこれ以外の用途がないと広く普及するのは難しいんじゃないかなという気がしています。


なんだか思ったより長くなりましたが、今回頑張って参加してよかったなと思います。 技術の知識が増えたことよりモチベーションが高まったり考え方変わったりしたのが大きいです。

こうしてブログを始めるきっかけになったBoost.勉強会に感謝です。

主催者の@cpp_akiraさんと発表者と参加者の方々、お疲れ様でした。そしてありがとう!