TEA(Tcl Extension Architecture)とは?
 これまでご紹介してきたように、Tcl/TkはC言語で簡単に拡張できるため、 世界中で拡張ライブラリがどんどん開発され、 その中でも便利なものはTclコミュニティを通じて世界中のTcl開発者に広まってきました。 しかし、 それらは拡張の開発者によってインストール手順やインストール場所がまちまちだったために、 複数の拡張を同時に使おうとする拡張ユーザー=Tcl開発者を混乱させる結果となりました。
 そこで、Tcl/Tk開発の総本山AjubaSolutions社(当時は前身のScriptics社) が御自らこの事態の収拾に乗り出しました。 そして1999年夏、Tcl/Tk 8.2のリリースに合わせて、 TEA(Tcl Extension Architecture)なる、 Tcl/Tkの拡張を開発・配布する際の統一的なスタイルガイドを提唱しました。 このスタイルに沿うと、(UNIX上で)拡張をインストールしたいユーザーは 「sh configure; make; make install」 というよく知られた方法でインストールを行うことができます。 TEAの登場に合わせて、全世界で使われている有名なTcl拡張の大半が 「sh configure; make; make install」 でインストールできるようになり、とてもわかりやすくなりました。

 あれ? ということはなんですか? 私達がTcl拡張を作るときにもこのTEAのスタイルガイドに従うのがよいというわけですか。

 で、Tcl拡張の開発者はこのTEAのスタイルに合ったconfigureスクリプトや Makefileのテンプレートを用意しないといけないわけですが、 1からそれらを作ろうとするとこれがなかなか大変です。 例えば、ccコンパイラにどのようなオプションをつけてコンパイルしたらよいか、 というのはUNIX系の各種プラットフォーム、 つまりSolaris、HP-UX、IRIX、DEC OSF/1、Linux、FreeBSD、etc、etc... で全く違いますし、インストールしたいユーザーがtclshやwish をどのような環境でインストールしたかを把握する処理をconfigureに全部詰め込むのはUNIX上での開発に慣れたエンジニアでもものすごくホネなはずです。 そんなスタイルガイドを守りましょうだ? 寝言もいい加減にしてくれよう、という我々のような軟弱どもを拾う神あり。 AjubaSolutionsはTEAのドキュメントのほかに、 TEAに則った開発の実例を「sampleextension」というアーカイブで配布しています。 ここではsampleextensionまるまるではなく、 とりあえずこんな感じで作ればよいのかなあという程度のメモとして紹介してみます。


サンプルプログラム
 はい、また出て来ました。例の「max」拡張のソースプログラムであります。 今度はTEA準拠方式でライブラリをビルドできるようにしてみます。 が、ソースプログラム自体はTEA準拠云々は関係なく、 普通に普通の普通な感じで作れば大OKです。
/* max.c */
#include <stdlib.h>
#include <string.h>
#include "tcl.h"

static int maxHandleProc(ClientData clientData, Tcl_Interp* interp,
                         int argc, char* argv[]){
  int  i;
  double maxvalue = 0;
  char result[200];

  if(argc == 1){
    sprintf(result, "Ootto! too few arguments, usage:%s num num...",
            argv[0]);
    Tcl_SetResult(interp, result, TCL_VOLATILE);
    return TCL_ERROR;
  }
  for(i=1; i<argc; i++){
    double v;
    if(sscanf(argv[i], "%lf", & v) == 0){
      sprintf(result, "Ootto! not numeric argument: %-100s", argv[i]);
      Tcl_SetResult(interp, result, TCL_VOLATILE);
      return TCL_ERROR;
    }
    if(i == 1 || v > maxvalue) maxvalue = v;
  }
  sprintf(result, "%g", maxvalue);
  Tcl_SetResult(interp, result, TCL_VOLATILE);
  return TCL_OK;
}

DLLEXPORT int Max_Init(Tcl_Interp* interp){
#ifdef USE_TCL_STUBS
  Tcl_InitStubs(interp, "8.1", 0);
#endif
  Tcl_CreateCommand(interp, "max", maxHandleProc, NULL, NULL);
  return Tcl_PkgProvide(interp, "max", "0.10");
}
/* end. */


用意するもの
 max拡張TEA版のソースアーカイブを作ってみました。 ここでリストするファイルは全部入っています。 これらは「max.c」を除けば、 全部「sampleextension」アーカイブからも抜いてくることができます。
  • aclocal.m4
  • tcl.m4
  • install-sh
  • mkinstalldirs
  • mkIndex.tcl.in
この5つのファイルは、sampleextensionに入っているものをそのまま使います。 通常は編集の必要はありません。
  • configure.in
  • Makefile.in
この2つがビルド作業の設定情報の中枢部となります。テキストエディタで開き、 拡張の名前やソースプログラムのリストを内容に応じて書き換えます。
  • max.c(ソースプログラム)
ライブラリのコードが含まれる全ソースプログラムを用意します。


拡張アーカイブを作る
 拡張を配布できるようにするには、「configure.in」から「configure」 スクリプトを生成する必要があります。 autoconfはまさにこの作業をするユーティリティで、 フリーで配布されています。 まだインストールされていなかったらどこからか入手して先にインストールしておきます。
% cd 作業ディレクトリ
% autoconf
configureができたら、これを圧縮アーカイバでナニすれば、 配布できるアーカイブの完成です。


インストールしてみよう
 では実際に、この拡張の最初のユーザーとして、インストールをしてみましょう。 rootで作業することになるので、 いきなり基幹サーバ機上で実行するのは絶対に避けてください。 試してみたらいいんじゃないですか? と言いつつそっと後ずさりするような感じで。知ーらないーもーん。
% sh configure
% make
% su root
# make install
「sh configure --help」で見ると、 たくさんのスイッチが指定できるように (そして実際にそれらの通りの動作をするように) 設定されているのがわかると思います。 これらの動作はconfigure.inとtcl.m4の2つのファイルに書かれている処理を反映したものですが、 その詳細に立ち入る必要はないでしょう。 興味のある方はテキストエディタで覗いてみてください。

 さてこのmax拡張ではnroffドキュメント(いわゆるman)を用意していないので、 何か最後にエラー終了するはずですが、 ライブラリのインストール自体はうまくいっているはずです。 ドキュメントをつけたくなったら、 「*.1」とか「*.n」というファイル名で作業ディレクトリ上に置いておけば、 勝手にインストールしてくれます。

 で、実際にインストールされたファイルは

  • /usr/local/lib/libmax-0.2.so
  • /usr/local/lib/max/pkgIndex.tcl
の2つです。/usr/localの部分は環境に応じて適当に読み変えてください。 このインストールされるファイルの位置もTEAのスタイルに含まれるので、 パスはいじらない方がよいと思います。また、 実行形式やヘッダファイルなどその他のファイルもMakefile.inで適当に(適切に) 指定すればインストールできると思います。


使ってみよう
 インストールできたら、 「package require」だけで拡張が使えるようになるはずです。 簡単な例で確認してみましょう。
package require max
label .laba -text "result=[max 10.1 12.2 13.3 12.1 13.2]"
pack .laba
というわけで、TEAのREADMEを簡単に読み下しながら適当に駆け足で紹介してみました。 さらに深くはまた今度、ということで!

なもなも top
(first uploaded 2000/08/27 last updated 2001/06/11 , Urano398 )