Category Archives: Tips

PaperHouseでCをコンパイルする

1 はじめに

PaperHouse は C のソースコードをコンパイルするための強力な Rake タスクライブラリです.Trema の一部は C で書かれていますが,Trema はこの C で書かれた部分をコンパイルするのに PaperHouse を使っています.

PaperHouse がコンパイルできるターゲットは次の 4 つです.

  1. 実行ファイル
  2. スタティックライブラリ
  3. 共有ライブラリ
  4. Ruby の C 拡張ライブラリ

今日はこのうち,実行ファイルをコンパイルする方法を紹介します.素の Rake も十分強力ですが,PaperHouse を使えばもっと簡潔に書けることを示します.

2 実行ファイルを作る

まずは一番単純な例から見てみましょう.あるディレクトリに *.c*.h があって,これらをコンパイルして実行ファイル hello を作るには Rakefile を次のように書きます.

PaperHouse::ExecutableTask.new :hello

なんとたったの一行です.PaperHouse::ExecutableTask クラスを使うと,次の 3 つの Rake タスクが自動的に使えるようになります.

rake hello
カレントディレクトリに hello という実行ファイルをコンパイルします.
rake clean
オブジェクトファイル (*.o) を消します.
rake clobber
実行ファイル (hello) とオブジェクトファイルをすべて消します.

もちろん,(再) コンパイルでは必要なファイルだけをコンパイルします.PaperHouse は賢くて,*.c と *.h ファイルの依存関係を解析して更新したファイルと依存するファイルだけをコンパイルしてくれます.まるでうまく書かれた make ファイルのようにです.

3 rake で書くとどうなるか

ためしに,まったく同じことをする Rakefile を Rake の標準機能だけを使って書くとどうなるでしょうか?

file :hello => FileList['*.o'] do
  sh "gcc -o #{t.name} #{t.prerequisites.join ' '}"
end

rule '.o' => '.c' do |t|
  sh "gcc -o #{t.name} #{t.source}"
end

CLEAN.include '*.o'
CLOBBER.include "hello"

6 行かかりました.これとまったく同じことが PaperHouse では 1 行だけでできるのです.

4 PaperHouse の特長

今まで見てきたように,PaperHouse は Rake で C をコンパイルするときに便利な gem です.素の rake が提供してくれる文法を使うよりも,もっと短く手軽に Rakefile を書けます.

大きな特長は Pure Ruby であることです.PaperHouse に似た Ruby のツールはいくつかありますが,それらは依存関係の解析に外部ツールの力を借りています.つまり,使うためには makedepend などの別ツールを別途インストールしなくてはなりません.

一方で,PaperHouse は依存関係解析を gcc の機能だけを使って行います.仕組みの詳細は省きますが,gcc や gcc から派生したコンパイラがインストールされていさえすれば,PaperHouse をすぐに使いはじめることができます.もともと C のプログラムをコンパイルしようとしているのですから,gcc がインストールされているのは当然ですね.

Pure Ruby なので Linux や Mac でも動作します.加えて,Ruby のメジャーバージョン (2.0, 1.9.3, 1.8.7) のすべてで動作します.

5 そのほかのオプション

上で見てきた単純な例のほかに,PaperHouse::ExecutableTask は次のようなオプションもサポートします.

PaperHouse::ExecutableTask.new :hello do | task |
  task.executable_name = 'hello'
  task.target_directory = 'objects'
  task.sources = 'sources/*.c'
  task.includes = 'includes'
  task.cflags = %w(-Wall -Wextra)
  task.ldflags = "-Llib"
  task.library_dependencies = %w(sqlite3 pthread mylib)
end
  • 実行ファイル名の指定 (タスク名と異なる場合)
  • ソースファイルやヘッダファイル,オブジェクトファイルを置くディレクトリの指定
  • コンパイルオプション (CFLAGS) やリンカオプション (LDFLAGS) の指定
  • リンクするライブラリの指定

このように,Makefile でできることはほとんど PaperHouse でもできます.しかもずっと簡潔に書けるのです。

6 おわりに

ちょっとした C のプログラムを書くときには,ゴリゴリと Makefile を書くかわりに PaperHouse を検討してみてください.小規模なプロジェクトであれば PaperHouse で十分な場面も多いはずです.ぜひ試してみてください.

Tagged ,

仮想ネットワークで任意のアプリを動かす

最近の Trema では、仮想ネットワークに network namespace をつなげることができるようになりました。この機能を使うと、Trema の標準的な仮想ホスト (vhost) だけでなく iperf など任意のアプリケーションでコントローラをテストできるようになります。

Continue reading

Tagged , ,

「読みやすさ」を最適化する

ごちゃごちゃとしたコードは読みにくく、バグを発見しづらいものです。ふつう、コードというものは書くよりも読む回数の方が圧倒的に多いので、ごちゃごちゃとした部分を減らすことで「読みやすさ」を最適化しなければなりません。読みやすいコードほどバグを発見しやすく、機能を付け加えるのも簡単です。

Continue reading

Tagged ,

Trema API のチートシート

Trema Ruby ライブラリのクラスは 100 個以上ありますが、そのうちよく使うものはせいぜい 10 個とかそこらです。そこで今日は、このようなよく使うクラスやメソッドだけを集めた便利な URL を紹介します。

Continue reading

Tagged

API を素早く調べる

Trema でプログラムを書いているとよく API を調べたくなります。Trema のホームページから API リファレンスへのリンクをたどってもいいのですが、ちょっと面倒ですよね。そこで、もっと簡単に開くショートカットがあります。

それが trema ruby コマンドです。ターミナルで trema ruby を実行すると、次のようにデフォルトブラウザで Trema Ruby API のページが開きます。

プログラミング中いつでもコマンド一発でリファレンスを開けるので大変便利です。