こんにちは、高木です。
そろそろPHPを使ってC言語やC++の前処理を行う話題も終わりにしようと思います。今回で完全に終われるかどうかは何とも言えませんが、とりあえずそこに目標を設定しましょう。
PHPを使ってC言語やC++のソースファイルをコンパイルする方法についてはすでに解説しました。ただし、そのときはコンパイルに成功することが前提で、失敗したとしてもエラーメッセージをユーザーが自分で読むしかありませんでした。せめて、コンパイルに成功したか失敗したかぐらいは自動的に判別したいものす。
コンパイル結果を知るためには、PHPのpassthru関数の第2引数に終了コード格納用の変数を渡します。コンパイルを実行したあと、終了コード格納用変数に0が格納されていれば成功、0以外が格納されていれば失敗です。
0 1 2 3 4 |
$command = "g++ -MMD -o $target_file $source_file $libs"; passthru($command, $result); var_dump($result); // 成功すれば0、失敗すれば0以外が格納される。 |
さて、本題はここからです。単にコンパイルに成功したかどうかを知るだけであれば、わざわざPHPを使う必要はありません。もし、コンパイルに失敗したときエラーメッセージの内容を格納したり、コンパイルできなければ成功とみなしたりする際に、PHPでコンパイルする方法が活きてきます。
コンパイラのエラーメッセージを解析するには、標準エラーを読み込まなければなりません。一番安直な方法は、passthru関数に渡すコマンドで標準エラーをファイルにリダイレクトして、そのファイルを読み込むことです。もう少し凝ったことをするには、passthru関数の代わりにproc_open関数を使う方がいいかもしれません。詳細は割愛しますので、必要な方はPHPの公式ドキュメントを参照してください。
コンパイルできなければ成功というのは奇妙ですが、実際にそういう使い方をしたいことはあります。たとえば、ライブラリやフレームワークを開発する際、セマンティックがおかしい使い方をしたときには適切にコンパイルエラーにしてあげるのが気の利いた設計というものです。つまり、間違った使い方をしたときにコンパイルエラーにできるかどうかもテストしたいことがあるのです。典型的にはstatic_assertを書いた場合がそうですね。
このように、テストプログラムを書くときには、コンパイルできることは前提で実行時の動作だけをテストするのではなく、コンパイルできるかどうかもテスト項目とした方がいいのです。通常はコンパイルできればテストに合格ですが、ときにはコンパイルできなければテストに合格するケースもあり得るということです。
ということで、今回でPHPを使ってC言語やC++の前処理を行う話題はいったん終わりにします。また新しいネタが出てくれば、随時追加することもあると思います。