C CodでCコードをスクリプトのように扱う

 C Codは、C、C++、またはObjective-Cコンパイラのフロントエンドとして、C言語をスクリプティング言語のように扱うことを可能とするものである。C Codには、C Server Pagesが付属している。C Server Pagesは、ウェブアプリケーションをCまたはC++で記述し、それをオンデマンドで自動的にコンパイルできるようにするために、CGIをサポートする。

 Ubuntu、Fedora、openSUSE用のC Codパッケージは存在しない。今回は、64ビットのFedora 9マシン上でバージョン1.2.8のソースをビルドした。コンパイル中に小さな問題が生じたが、以下に示すように、CFLAGSにposition-independent code(PIC)のオプションを加えることにより解決することができた。PICコードは、メモリの別の場所にロードすることができるという利点がある。これは、共有ライブラリのコードをコンパイルする場合には好都合である。複数のライブラリが同じアドレスを使用しないように、それらを移動させることができるためだ。

$ tar xzvf /.../ccod-1.2.8.tar.gz
$ cd ./ccod-*/
$ ./configure
$ make
/usr/bin/ld: csp.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
csp.o: could not read symbols: Bad value

$ vi Makefile
PACKAG = ccod-1.2.8
LFLAGS = -shared -Wl,-soname,libcsp.so
CFLAGS = -O2 -fPIC
LIBSTA = *.a
$ make clean
$ make
$ sudo make install

 最初にccodを使用しようとしたとき、以下のようにSegmentation faultが生じた。

$ cat main1.c
#!/usr/bin/ccod
#pragma CCOD:script no

int main( int argc, char** argv )
{
    printf("hi there\n");
    return 0;
}

$ chmod +x main1.c
$ ./main1.c
Segmentation fault

 調べてみると、cksum()関数が原因であることがわかった。試行の結果、変数sのサイズを以下のように変更すると問題が修復された(少なくともクラッシュはしなくなった)。

$ gdb /usr/bin/ccod
(gdb) r main1.c
...
(gdb) bt
#0  0x0000000000404554 in cksum (path=0x10f3390 "/home/ben/testing/ccod/hello-world.c") at ccod.c:1306
#1  0x000000000040441b in get_sourcesum () at ccod.c:1203
#2  0x0000000000409605 in main (in_argc=2, in_argv=0x7fff6008bcd8) at ccod.c:3398
(gdb) q

$ vi /home/ben/testing/ccod/hello-world.c
...
static unsigned long
cksum(const unsigned char *path)
{
//	register unsigned long  i, c, s = 0;
	register unsigned long  i, c = 0;
    int s = 0;
...

... ccodを再コンパイル・再インストール ...

$ ./main1.c
hi there

 先ほどの例では、ソースコードをできるだけ標準のCファイルに近い形のままにしてccodを使用した。単一ファイルからなる簡単なプログラムならば、ソースコードの上に2行追加するだけで、ccodを使用することができる。ccodのウェブサイトにあるサンプルのほとんどは、PHPに倣って定義された、混在モードのC構文を用いている。たとえば以下の例に示すように、main()関数は存在せず、<?ブロックの外にあるテキストは、プログラム実行時にそのまま端末に出力される。

$ cat ./main2.c
#!/usr/bin/ccod

hi there

<?
    printf("and more\n");
    return 0;
?>

$ chmod +x ./main2.c
$ ./main2.c

hi there

and more

 この構文は、提供されるC Server Pagesインターフェースを用いたウェブプログラミングにccodを使用する場合に適している。ドキュメントページには、C Server Pagesを用いたCGIプログラミングをかなり容易にしてくれる、ちょっとした関数の集合が提供されている。セッション処理、クッキー、フォーム、クエリ文字列へのアクセス、リダイレクトなど、ウェブプログラミングに必要となる関数が、C Server Pageアプリケーション向けの一般的なC関数としてすべて提供されている。

 最初に示した例では、「#pragma CCOD:script」を用いて、ccodがCソースファイルを扱う方法を指定している。同プロジェクトでは、このようなpragmaが10種類ほど提供されており、使用するコンパイラ、コンパイラに指定するフラグ、プログラムにリンクするその他のライブラリ、C Server Pageプログラム特有のオプション数種を指定することができる。

 ccodはコンパイル済みのバイナリをキャッシュするため、実行の度にソースコードがコンパイルされるわけではない。もちろん、今回私がcksum関数に加えたちょっとした変更は、しっかりとテストしたわけではないので、キャッシュ処理を妨害してしまっているかもしれない。問題は、変数sに大きすぎる値が代入されていることのようであったため、データ型を変更した。別のチェックサム関数をどこかから持ってきて、cksum関数の中身を完全に入れ替えてしまうというのも解決策の1つかもしれない。

 CまたはC++で書かれたコードが既に存在し、その機能の一部をプロトタイプとしてウェブに公開したいという場合には、C Codが最適だろう。簡単なコーディング、コンパイル、テスト実行を繰り返す作業においてC Codを用いれば、makefileを作成したり、コンパイルプロセスを気にしたりする煩わしさから解放してくれる。

Ben Martin 10年以上にわたってファイルシステムを研究。博士課程を修了し、現在、libferris、ファイルシステム、検索ソリューションを中心にコンサルティングをしている。

Linux.com 原文(2008年11月18日)