ysflight.com - 64-bit Ubuntu上で32-bit用のOpenGLプログラムをクロスコンパイル

2014/07/11

とりあえず、2014年7月11日にこの文章を書いてるけど、普通にやってOpenGLプログラムのクロスコンパイルができないのは、バグだから、すぐに誰かが直してくれて、こんな文章は不要になっていて欲しい。ただ、検索した限りでは、僕と同じ問題を持っていて、解決を質問してる人は見つかったけど、解決策を答えてる人が見つからなかったから、多分彼らは今でも困っていると思う。僕が今日見つけた方法が何かの助けになればいいと思う。

これまで、僕は、Linux用バイナリを作るとき、32-bit用バイナリは32-bit Ubuntuで、64-bit用バイナリは、64-bit Ubuntuで、VirtualBox上で起動してコンパイルしていた。これだと、何が面倒かというと、同じLinux用のバイナリを作るのに、32-bit版、64-bit版でスクリプト一発でまとめて一気にできないのが面倒だった。同じOSなんだから、コマンド一発、ワンタッチで32-bitバイナリ、64-bitバイナリができて、アップロードするパッケージになってほしい。

gccのオプションで、-m32, -m64というオプションをつければ、強制的に32-bit, 64-bitを分けることができる、ということになっているが、64-bit Ubuntu上で-m32でコンパイルすると、コンパイル時にpredef.hが見つからないというエラーが出て、コンパイルできなかった。が、今日思い立って、そのpredef.hが見つからないというエラーはなんぞや、と、思って調べたところ、どうやら、multilibなるパッケージをインストールするとエラーが消えるらしいことがわかった。

その後調べると、他のライブラリも sudo apt-get install lib???:i386 によって32-bit用を追加できるらしいことがわかった。だったら、ちょっと手を換えれば、64-bit Ubuntu上で両方できちゃうんじゃないか。

と、思ったところ、問題発生。libGLとlibGLUが見つからないという。だったら、libgl1-mesa-dev:i386, libglu1-mesa-dev:i386をインストールすれば、と、思ったらエラーが出てできない。どうやら、調べたところ、これはUbuntuの既知のバグのようだ。

https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/1317113

マイクロソフトが既知のバグを長い間放置すると(OfficeのDrawing toolみたいに)、「なんだ、みっともない」、と、思うけど、フリーのオープンソースだとねえ。仕方ないというか、どうにもならないというか。オープンソースだと、世界中の人が参加して、エラーなんてすぐ直る、っていうのも、あれは迷信だよね。普通は、しょうがないと、思ってあきらめるしかない。

だけど、今回はあきらめなかった僕は、せっかく32-bit Ubuntuがあるんだから、そこからライブラリファイルをコピーしてくれば済むんじゃないか、と、思った。ということで、約半日かけて、成功。

どうやらネットで調べた感じだと同じ問題で困ってる人がいるようだったから、どうやって成功したか、以下にまとめておこうと思った。

Step 1. 32-bit Ubuntuに開発環境とMesaライブラリをインストール

一応、VirtualBoxで実行してるってつもりで書くけど、まず、32-bit Ubuntu上で一通り開発環境をセットアップする。多分、32-bit版と64-bit版は同じバージョンのUbuntuである必要があると思う。僕は、12.04を使ってる.

OpenGLのライブラリを64-bit環境に持っていこうってんだから、libgl1-mesa-dev, libglu1-mesa-devは忘れずにセットアップする。

それから、共有フォルダをひとつ作ってマウントする。僕は/ysshareっていうフォルダにしてるけど、これは、後ほど64-bit Ubuntuからも同じところを共有してライブラリファイルを持っていくために使う。

ちなみに、僕の場合だとALSAとPulse Audioも持っていかなきゃならなかったから、そのセットアップも必要だった、というか、すでにしてあった。

Step 2. 32-bit Ubuntu上で、ライブラリファイルを共有フォルダにコピー

まず、

% locate libGL

と、やって、OpenGL関係のライブラリの所在を確認する。で、そのファイルを全部共有フォルダにコピー。僕の環境だと、

/usr/lib/i386-linux-gnu/libGL*
/usr/lib/i386-linux-gnu/mesa/libGL*

をコピーする必要があった。

なお、ALSAとPulse Audioも同じ手で、locate libpulse, locate libasoundで場所を確認して、同様にライブラリファイルをごっそりコピーした。でもOpenGLを使うだけだったら、ALSAとPulse Audioはもちろん不要。

これで、もう32-bit Ubuntuに用は無い。(用があるとすれば、実行ファイルの動作確認ぐらい)

Step 3. 64-bit Ubuntu上でmultilibをインストール

64-bit Ubuntu上で次のようにタイプして、multilibをインストール。

 % sudo apt-get install gcc-multilib
% sudo apt-get install g++-multilib

こうすると、クロスコンパイルで使う32-bit用ライブラリのディレクトリができる。僕の環境だと/lib32だったけど、検索すると/usr/lib32だと主張してる人もいるから、どっちかは、自分で確認する必要がある。

Step 4. 32-bit Ubuntuから抜き出してきたライブラリファイルを、32-bit用ライブラリディレクトリにコピー

ここで、64-bit Ubuntu上で、Step 2で使ったのと同じ共有フォルダを共有してマウントする必要がある。いや、USBメモリかなんか経由してもいいのかな。重要なのは、Step 2で抜き出したライブラリファイルをStep 3で探した32-bit用ライブラリディレクトリにコピーするってことだ。/lib32はsuperuser権限じゃないとファイルを書き込めなかったから、

% sudo cp /ysshare/libGL* /lib32

でOKだった。/ysshareのところは、それぞれの環境で使ってる共有フォルダね。

ワンクッション入れて、後に混乱しないように、抜き出してきたライブラリは/lib_copiedみたいなところに置いて、シンボリックリンクを張ってもいいかもしれない。

Stpe 5. その他、OpenGLプログラムに必要なi386ライブラリをインストール

とりあえず、以下のパッケージをインストールする必要があった。

% sudo apt-get install libX11-6:i386
% sudo apt-get install libxcb-glx0:i386
% sudo apt-get install libdrm-dev:i386
% sudo apt-get install libxdamage-dev:i386
% sudo apt-get install libx11-xcb-dev:i386
% sudo apt-get install libglapi-mesa:i386
% sudo apt-get install libxext6:i386
% sudo apt-get install libxxf86vm-dev:i386

あとは、gccのオプションに-m32をつけるだけど、32-bit用OpenGLプログラムを64-bit Ubuntu上でコンパイルできるようになった。PolygonCrestとYSFLIGHT両方この手を使って64-bit Ubuntu上でコンパイルした32-bitバイナリを32-bit Ubuntuで実行できたから、多分成功してるんじゃないかと思う。

なお、64-bit Ubuntu上で32-bitバイナリを実行しようと思ったら???.so.1が見つからない、というようなエラーが出るかもしれない。そうなったら

% sudo ldconfig

で、多分直ると思う。

それで、PolygonCrestのパッケージスクリプトはLinux用がほぼ完成したんで、あとはMac用を作ればアップロードできるようになる予定。

 

 

Comments are welcome.  Send E-Mail to:

RETURN TO TOP PAGE

このページはリンクフリーですが、リンク先は、http://www.ysflight.com にお願いします。よかったら以下のバナーのうちのひとつをお使いください。