とりあえずサンプルはmakeできるんだけど、自分で.cfgを書き換えてmakeすると
"SEM_xxx_xxx is duplicated"
とか
"TSK_xxx_xxx is duplicated"
とかのエラーが頻発して出る。
makeのどこでエラーが出ているかを調べると、コンフィグレータcfgを呼び出す中でエラーが発生していた。個人的な意見だけれど、どうもこのコンフィグレータの存在がちょっと鬱陶しく感じる。何をやっているかがよく分からないからだ。とにかく、cfgがエラーを出すならcfgのソースを拾ってきて追っかけるしかない。
う~ん、なかなか難しい。最終的に理解したのは以下の通り。
- 指定された.cfg定義ファイルを、cfg1_out.cというCソースコードに変換する。
- INCLUDEディレクティブ(Cプリプロセッサの#includeとは関係ない)を処理して、インクルードされた.cfgを連鎖的に読み込む。
- .cfgファイルにある「キーワード」を引っかけて、uITRONで使用される可能性のあるすべてのオブジェクト名を内部に記憶するとともに、オブジェクトIDの定義をCソースコードとして吐き出す。
- キーワードに引っかからない行は、そのままcfg1_out.cというソースコードに落とす。特に重要なのは#ifdefや#endifなどのCプリプロセッサディレクティブで、それらはそのままcfg1_out.cに出力する。
- 「キーワード」は.csvファイルで定義されていて、その定義に従って静的APIとオブジェクト名を区別するのであって、静的APIの名前自体がコンフィグレータ内にハードコーディングされているわけではない。
- こうして出力されたcfg1_out.cには.cfgファイルで定義されていて使用される可能性のあるすべてのオブジェクトIDが含まれている。
- cfg1_out.cはGCCでコンパイルされ、その出力からシンボルだけを取り出す。ここで重要なのは、コンパイラのプリプロセッサ機能を借りることで#ifdef~#else~#endifブロックを処理させて、実際に必要とされるオブジェクトIDだけをふるいに掛けることにある。
- cfg1_out.cをコンパイルして得られたシンボル情報を処理して、target_cfg.hにオブジェクトIDを#defineしたものを書き込んでいく。
だいたいこんな感じかな(勘違いがあればご指摘お願いします>誰か)。
この調査の課程で分かったのは、前述の"xxx is duplicated"というエラーが発生する原因は、.cfgファイル(INCLUDEされたものを含む)をスキャンして得られたオブジェクト名のリストと、cfg1_out.cから得られたオブジェクト名のシンボルとに矛盾が生じているからのようだ。それは何故かというと・・・
.cfgファイルを書き換えてmakeを実行しても、cfg1_out.cやシンボルを更新してくれないから!
依存関係を調べて必要なファイルを自動的に更新してくれないのなら、いったい何のためのmakefileなの?と思ってしまう(ちょっと、怒)。
とりあえずの回避策は、.cfgファイルを変更したら、make clean; makeとすること。
こんなしょうもないことで少なくとも丸2日は潰れたな(再び、怒)
0 件のコメント:
コメントを投稿