2014年5月2日金曜日

Coin 3D:現状とビルド

Coin 3Dってご存知でしょうか?3DのGraphics Libraryですが、20年位前その分野で有名だったのがSGIというコンピュータ会社でした。そこが今では業界標準になっているOpenGL(大胆にも、GLはGraphics Libraryの略です)を作り、更により上位のライブラリとしてOpenInventorを作りました。(Inventorは1995年くらいだったかな?)
当時のSGIは非常にバカ高いWS(Work Station)を販売しており、そこでしかOpenInventorは使えませんでした。そのとき、有志で互換のライブラリを作ろうと出てきたのがCoinでした。(皆、興味がなくなったのかぐぐっても、情報がないですね。)

1.概要
2009年頃書いていたブログ(今とは別の所で書いてました)にその当時のCoinの状況を書いてました。
SGIの経営が2000年を越えてしばらくしてから怪しくなり、Inventorの権利を別会社に販売したり、OpenInventorと命名して(Openを頭文字に入れた)、ソースを公開していました。(2005年くらいだったかな。OpenInventor2.1.5が最後に公開されたソースコードで、当時RedHat9でビルドができました。)
結局SGIは3Dグラフィクス分野からは手を引き(日本SGIに確かその分野を譲渡し、NECが資本を注入してました。)、完全にOpenInventorのソースコードが中に浮いてしまった状態になりました。(その前にInventorのライセンスを買った会社は今でもOpenInventorのメンテナンス、といっても新しいプラットフォームへの対応、バグとり程度しかしてませんが、これがまた高い!こちらのソースコードは非公開なので、全く独立にメンテされています)
2009年の2、3年前にCoinがフリーになったOpenInventorのソースコードを使うことの許可をSGIに得て(それまではAPI定義だけを元に、独自の実装をしていた)、メンテナンスを行うという発表を見た記憶がありました。その後、2009年に調べてみたら、なんかCoin 3Dがどこかの会社(資源探査会社?)に買い取られ、Qtのようなダブルライセンスになっていました。当時、CentOS5でビルドしてみましたが、あっさりビルドできて動いた記憶があります。(ただ見た目がまだかなり、本物のOpenInventorとは違っているところがありました。はっきりいって「いけてない」感じのデザインでした。)

さて2014年現在ですが、なんとCoin3Dはその会社が放棄していました!!(2012年)商売にならないと判断されたのでしょう、現在では一部の有志だけで公開されているようです。(JIRAで有名なAtlassianが行っているSourceForgeのようなサービスでプロジェクトを公開していました。リポジトリはgitではなく、Mercurialを使っていました。そこではwikiサービスも行っており、JIRAのようなタスク管理も動いていましたが、活動があまり活発ではありませんでした。)
従って、ソースコードも2012年から更新されていないようです。

2.Coin 3Dのビルド
さて現状のバージョンはCoin-3.1.3となっています。これをDLしてきて、以下の環境でビルドしてみます。

・Ubuntu 13.10
・g++-4.8.1

(1)configureでのエラー
何も考えずに、no-optionでconfigureすると以下のエラーがでて、configureができなかった。cc_debugerror_post()の関数定義で、先行定義してあるデバッグ用関数において、gcc-4.7以降ではtemplateの解釈が変わったらしく、namespaceの範囲解釈が変わり問題がでるようになった。
 元々、trickyな定義がしてあったらしい。解決方法が見つからないので、debugをスルーするようにした。

$ configure --disable-debug

これで当該エラーはでなくなり、ビルドができるようになった。

(2)g++のバグ
ビルドをしてみると、以下のエラーがでた。

In file included from ../../../Coin-3.1.3/src/base/dict.h:31:0,
from ../../../Coin-3.1.3/src/fonts/freetype.cpp:142:
/usr/include/c++/4.8/cstdlib: In function ‘long long int std::abs(long long int)’:
/usr/include/c++/4.8/cstdlib:174:20: error: declaration of C function ‘long long int std::abs(long long int)’ conflicts with
abs(long long __x) { return __builtin_llabs (__x); }
^
/usr/include/c++/4.8/cstdlib:166:3: error: previous declaration ‘long int std::abs(long int)’ here
abs(long __i) { return __builtin_labs(__i); }


どうもabs()関数の多重定義に関するエラーらしい。ただ問題が、abs()関数を使うところではなく、abs()関数をinline定義しているcstdlibをincludeしているところで発生しているため、どう対処したらいいのかがわからない。

英語でぐぐってみたら、gcc-4.8のバグで、cstdlib(c++用)がstdlib.h(c用)を含めてマクロ定義を多重に読み込むのを防ぐときのバグらしい。(cで書かれたプログラムをc++で流用するときが多分にあり、そのとき両方がincludeされることが多々発生するが、同じマクロ定義が行われていることが多い。その問題を解決するのにg++側でバグがでているっぽい)
別のプロジェクトのブログに解決法として、両方includeしているようならcstdlibをやめろ(stdlib.hだけにしろ)というのがあったので、ソースを一部修正してみると、ビルドが先に進んだ。
(src/base/dict.h:31  cstdlibのincludeをコメントアウトした)

(3)namespace指定の問題
更にビルドが進むと、以下のエラーがでた。

g++ -DHAVE_CONFIG_H -I../../include -I../../../Coin-3.1.3/include -I../../src -I../../../Coin-3.1.3/src -D_REENTRANT -DNDEBUG -DCOIN_DEBUG=0 -DCOIN_INTERNAL -g -O2 -W -Wall -Wno-unused -Wno-multichar -Woverloaded-virtual -MT glyph.lo -MD -MP -MF .deps/glyph.Tpo -c ../../../Coin-3.1.3/src/fonts/glyph.cpp -fPIC -DPIC -o .libs/glyph.o
../../../Coin-3.1.3/src/fonts/glyph.cpp:41:12: error: ‘std::free’ has not been declared
using std::free;


std::freeというnamespaceがg++-4.8にはないらしい。とりあえずコメントアウトしてみる。

 free()はstdlib.h内に定義してあるが、includeしてないせずにnamespaceの定義だけでエラーを逃げようとしたらしい。他にもmallocでも別の近い箇所でエラーでる。
どうも(2)で述べた、stdlib.hとcstdlibの多重includeで問題がおきて、一部ソースではstdlib.hをincludeするのをやめ、using std::freeとかのnamespace定義で逃げようとしたらしいが、それが問題になったらしい。(先に、cstdlibのincludeをコメントアウトしたせいか?)

 かわりに#include <stdlib.h>してやれば先に進んだ。
結果として、これでビルドはパスし、make installができた。(/usr/local以下にヘッダ、ライブラリはインストールされた)


3.サンプルプログラムの作成
さて実際にビルドが成功したかを確認するために、サンプルプログラムとして、Inventor mentorの最初にある、Red Coneをコンパイルしてみます。
しかし、これだけではビルドができません。よく見たら、Coin-3.1.3のtarボールにあるのはOpenInventor本体だけであり、それをwindow上に表示するためのSoXt(WindowsならSoWin等)がありません。Coin3DのHPに別途、SoXt-1.3.0があり、それをインストールする必要があります。

(1)configureでのエラー
何も考えずにconfigureすると、Coinと同じようにcc_debugerror_post()の関数定義でエラーがでました。同じように、--dsiable-debugオプションで逃げます。

(2)実行時にエラーがでる
これでSoXtのビルドは成功、インストールできました。しかしサンプルプログラムを実行すると以下のエラーがでます。

Coin error in SoXtGLWidget::buildWidget(): SoXt does not support detecting best visual/colormap without the Xmu library (yet)

よくわかりませんが、ビルド環境を調べてみるとXmuのランタイムは入っていますが、開発環境(libxmu-dev)までは入ってませんでした。試しにインストールしてSoXtを再ビルドしてみましたが、状況はかわりません。

このエラーを出している箇所を調べてみると、場所は、SoXtGLWidget.cpp:1064らしい。

#ifndef HAVE_LIBXMU
SoDebugError::post("SoXtGLWidget::buildWidget",
"SoXt does not support detecting best visual/colormap without the Xmu library (yet)");
exit(1);
#else // HAVE_LIBXMU


内容的には、Xmuライブラリを持っていなかったらとのフラグでここに入っているが、当該環境にはXmuライブラリはインストール済みである。configureに問題があるらしい。
config.logを見ると、環境調査の中で以下の箇所で問題がでていた。

configure:22291: g++ -o conftest -g -O2 -W -Wall -Wno-unused -Wno-multichar -Woverloaded-virtual\
  -DNDEBUG -DSOXT_DEBUG=0 -DSOXT_INTERNAL      conftest.cpp -lXmu -lXext  -lSM -lICE -lX11  -ldl\
  >&5
conftest.cpp:31:41: fatal error: X11/Xmu/Xmu.h: No such file or directory
                 #include <X11/Xmu/Xmu.h>
                                         ^
compilation terminated.

おそらくこのエラーのせいで、Xmuライブラリが環境に存在しないと判断されたらしい。しかしなぜこんなエラーが出てくるのか不明。(当環境には、当該位置にXmuは入っている)
再度、通常のターミナルでSoXtをmakeし直しました。(前回はおそらくemacs内のshellで行っている。通常、ログをあとで確認するためよくemacs内のshellでビルドをしているくせがついている。)
するとXmu関係のエラーがconfig.log内にでなくなり、SoXtを再インストールしたら動きました!


4.サンプルプログラムの実行
2個ほど、実行結果を示します。

(1) HelloCone
まずはmentorの最初にでてくる一番シンプルなものです。

画面の真ん中に、赤い3角錐が表示されるだけです。

(2)ExaminarViewerの実装
最初のCoinにはまだ実装がなかったんですが、OpenInventorではとても便利なViewerだったExaminar Viewerです。

ぱっと見、大して変わらないように見えますが、このViewerではマウスで表示中のモデルを自由に視点を回したり、拡大/縮小ができます。右端の一文字のボタンが何か昔のSGIの実装とは違いますが(確かアイコンで機能が表示されていたはずなんですが、一文字になってますね)、とりあえず動作には問題がありません。

と、まあ一応は動くようです。(g++周りの実装が変わったことによるエラーには少し悩みました。昨年末、やっとc++第4版の仕様が確定したらしいという話を聞いたせいか、多少実装に変更があったようです。)

Ubuntuも14.04LTSが発表されたところで、今の環境だと「アップデートするか?」と毎回聞かれますが、こんな時にg++のバージョンが変わってしまったら訳がわからなくなりますから、そのままにしてあります。

0 件のコメント:

コメントを投稿