ARMボードでQt4を動かす

ARM SoCを搭載したCPUボードArmadillo-440でQt4を動かしてみます。

環境は以下の通りです。
*1: CodeSourcery由来のもの(一般的にはこちらの方が多い?)の場合、arm-none-linux-gnueabi-g++等の名前になりますが、今回はarm-linug-gnueabi-g++を使う前提で話を進めます。
*2: Qt SDKをインストールすると、自動でインストールされます。

情報源

Qt SDKのインストール

最初に、ホスト用のSDKをインストールします。Qt SDKは、オープンソース版と商用版のデュアルライセンスになっていますが、今回はオープンソース(LGPL)版を使用します。

最新のQt SDK等は、Nokia社のQtのダウンロードページからダウンロードします。ホストPCに合わせて、Qt SDK for Linux/X11 64-bitか32-bitを選択してください。

SDKをインストールするには、ダウンロードしたファイルに実行権限をつけ、実行します。Linux/X11 64-bit LGPL版 2010.05.1の場合は、以下のような手順になります。

Qt SDKのインストール

[PC ~]$ wget http://get.qt.nokia.com/qtsdk/qt-sdk-linux-x86_64-opensource-2010.05.1.bin
[PC ~]$ chmod +x qt-sdk-linux-x86_64-opensource-2010.05.1.bin
[PC ~]$ sudo ./qt-sdk-linux-x86_64-opensource-2010.05.1.bin

SDKのインストール手順については、Qtラボジャパンの以下の記事で詳しく説明されていますので、そちらも参考にしてください。

ターゲット用ライブラリのインストール

続いて、ターゲット用のライブラリをインストールします。ターゲット用のライブラリは、ソースコードを取得してきて、自前でビルドする必要があります。

最新版は、SDKと同様にNokia社のQtのダウンロードページからダウンロードします。組み込みLinux版Qtライブラリを選択してください。

組み込みLinux版Qtライブラリ4.7.1の場合は、以下のようにしてソースを取得し、展開します。

組み込みLinux版Qtライブラリの取得

[PC ~/]$ wget http://get.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.1.tar.gz
[PC ~/]$ tar xzvf qt-everywhere-opensource-src-4.7.1.tar.gz

インストール方法を説明したドキュメントは以下にあります。一度目を通しておいてください。
qt-everywhere-opensource-src-4.7.1/doc/html/qt-embedded-install.html

クロスコンパイラの名称がQtが想定しているものとは異なるので、設定ファイルを一部修正します。

qt-everywhere-opensource-src-4.7.1/mkspecs/qws/linux-arm-gnueabi-g++/qmake.conf
の「arm-none-linux-gnueabi-*」を「arm-linux-gnueabi-*」に書き換えてください。

具体的には、

qmake.conf修正前

# modifications to g++.conf
QMAKE_CC                = arm-none-linux-gnueabi-gcc
QMAKE_CXX               = arm-none-linux-gnueabi-g++
QMAKE_LINK              = arm-none-linux-gnueabi-g++
QMAKE_LINK_SHLIB        = arm-none-linux-gnueabi-g++

# modifications to linux.conf
QMAKE_AR                = arm-none-linux-gnueabi-ar cqs
QMAKE_OBJCOPY           = arm-none-linux-gnueabi-objcopy
QMAKE_STRIP             = arm-none-linux-gnueabi-strip

qmake.conf修正後

# modifications to g++.conf
QMAKE_CC                = arm-linux-gnueabi-gcc
QMAKE_CXX               = arm-linux-gnueabi-g++
QMAKE_LINK              = arm-linux-gnueabi-g++
QMAKE_LINK_SHLIB        = arm-linux-gnueabi-g++

# modifications to linux.conf
QMAKE_AR                = arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY           = arm-linux-gnueabi-objcopy
QMAKE_STRIP             = arm-linux-gnueabi-strip
に修正します。

後は、お馴染みのconfigure/make/make installをするだけです。今回は、OpenGLを使わず、マウスの制御にtslibを使いたいので、以下のように指定しました。なお、このとき指定できるオプションの一覧は、「./configure -embedded -help」で確認できます。

Qtライブラリのconfigure

[PC ~/]$ cd qt-everywhere-opensource-src-4.7.1/
[PC ~/]$ ./configure -opensource -embedded arm-gnueabi -no-armfpa -little-endian -no-opengl -qt-mouse-tslib

この際、ライセンスに同意するか聞かれますので、ライセンスに同意する場合は「yes」と入力してください。

テキスト ボックス

This is the Qt for Embedded Linux Open Source Edition.

You are licensed to use this software under the terms of
the Lesser GNU General Public License (LGPL) versions 2.1.
You are also licensed to use this software under the terms of
the GNU General Public License (GPL) versions 3.

Type '3' to view the GNU General Public License version 3.
Type 'L' to view the Lesser GNU General Public License version 2.1.
Type 'yes' to accept this license offer.
Type 'no' to decline this license offer.

Do you accept the terms of either license? 

makeコマンドを実行すると、ビルドを開始します。

Qtライブラリのビルド

[PC ~/]$ make

makeにはとても時間がかかります。。気長に待ってください。

makeが正常に完了したら、インストールします。

Qtライブラリのインストール

[PC ~/]$ sudo make install

ファイルは、/usr/local/Trolltech/QtEmbedded-4.7.1-generic/ にインストールされます。

環境設定

インストールしたクロス用のライブラリにパスを通します。シェルにbashを使っている場合、~/.bashrcに以下を追記すればよいでしょう。

.bashrcにQtライブラリへのパスを追加

export PATH="/usr/local/Trolltech/QtEmbedded-4.7.1-generic/bin/:$PATH"

続いて、IDEの設定を行います。デスクトップの「アプリケーション - プログラミング - Qt Creater」メニューを選択して、Qt Creater(QtのIDE)を起動してください。



続いて、Qt Createrウィンドウの「ツール - オプションメニュー」メニューを選択して、オプション画面を開いてください。オプション画面の「Qt 4」を選択すると、使用するQtのバージョンを選択する画面が現れます。



最初は2つの選択肢しかないと思いますので、右上の「+」アイコンをクリックしてもう一行追加してください。バージョン名は「Qt 4.7.1 Embedded」(これは何でも良いです)、qmakeのパスは「/usr/local/Trolltech/QtEmbedded-4.7.1-generic/bin/qmake」を指定します。「デバッグヘルパが見つかりません」と表示されている場合は、一度「リビルド」ボタンをクリックしてください。

以上の設定をおこない、「適用」ボタンをクリックして修正を反映すれば、Qt Createrをクロス開発用にも使うことができるようになります。

一度、Qt Createrを終了してください。

アプリの作成

デスクトップの「アプリケーション - プログラミング - Qt Creater」メニューを選択して、Qt Creater(QtのIDE)を起動します。

Qt Createrウィンドウの「ファイル - ファイル/プロジェクトの新規作成」メニューを選択して、新規プロジェクトを作成します。「モバイル Qt アプリケーション」を選択して、「選択」ボタンをクリックします。



プロジェクトの名前は、「HelloArm」とでもしておきます。パスに指定したディレクトリの下に、プロジェクトの名前と同じディレクトリが作成されます。


「Qt バージョン」には「Qt 4.7.1 Embedded」を選択します。手順3で設定した名前です。


続いて、クラス情報を設定します。クラス名は「HelloArm」とします。(これも、何でも良いです。)ソース名やヘッダ名などは、クラス名に応じて自動で設定されます。


「完了」ボタンをクリックして、プロジェクトの設定を終わります。



後は、通常のQt Createrを使用したアプリの作成と同じです。


「ビルド - 全てビルド」メニューを選択すると、「HelloArm-build-desktop」ディレクトリに、「HelloArm」という名前で実行ファイルが生成されます。

アプリを動作させる

いよいよ、生成された実行ファイルを実機(Armadillo-440)に持っていって動作させます。が、これが色々と面倒です。

まず、HelloArmが使用するライブラリを調べます。通常、ある実行可能バイナリがどの共有ライブラリを使用するか調べるには、lddコマンドを使います。ところが、arm-linux-gnueabi-lddというコマンドは存在しません。そこで、readelf -dコマンドで代用します。

Qtアプリが使用する共有ライブラリを調べる

[PC ~/]$ arm-linux-gnueabi-readelf -d HelloArm | grep NEEDED
 0x00000001 (NEEDED)                     Shared library: [libQtGui.so.4]
 0x00000001 (NEEDED)                     Shared library: [libQtNetwork.so.4]
 0x00000001 (NEEDED)                     Shared library: [libQtCore.so.4]
 0x00000001 (NEEDED)                     Shared library: [libpthread.so.0]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]

libm.soは大抵の環境に入っていそうなので、libstdc++.so、libQtCore.so、libQtNetwork.so、libQtGui.soあたりを持っていってあげれば良さそうです。実際には、以下のファイルをコピーしました。

 ホストPC上のパス 実機上のパス
 /usr/arm-linux-gnueabi/lib/libstdc++.so.6.0.10 /lib/libstdc++.so.6.0.10
 /usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/libQtCore.so.4.7.1 /lib/libQtCore.so.4.7.1
 /usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/libQtNetwork.so.4.7.1 /lib/libQtNetwork.so.4.7.1
 /usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/libQtGui.so.4.7.1 /lib/libQtGui.so.4.7.1

そして、以下のようにシンボリックリンクを張ります。
  • /lib/libstdc++.so.6 -> /lib/libstdc++.so.6.0.10
  • /usr/lib/libstdc++.so.6.0.10 -> /lib/libstdc++.so.6.0.10
  • /lib/libQtCore.so.4 -> /lib/libQtCore.so.4.7.1
  • /usr/lib/libQtCore.so.4 -> /lib/libQtCore.so.4.7.1
  • /lib/libQtNetwork.so.4 -> /lib/libQtNetwork.so.4.7.1
  • /usr/lib/libQtNetwork.so.4 -> /lib/libQtNetwork.so.4.7.1
  • /lib/libQtGui.so.4 -> /lib/libQtGui.so.4.7.1
  • /usr/lib/libQtGui.so.4 -> /lib/libQtGui.so.4.7.1
HelloArm自体は、/usb/bin にでも置いて、chmod +xで実行権限を付けておきます。

単純にHelloArmを実行すると、以下のように表示されて終了してしまいます。

Qtアプリの実行1

[armadillo ~/]#  HelloArm
QWSSocket::connectToLocalFile could not connect:: Connection refused
QWSSocket::connectToLocalFile could not connect:: Connection refused
QWSSocket::connectToLocalFile could not connect:: Connection refused
QWSSocket::connectToLocalFile could not connect:: Connection refused
QWSSocket::connectToLocalFile could not connect:: Connection refused
QWSSocket::connectToLocalFile could not connect:: Connection refused
No Qt for Embedded Linux server appears to be running.
If you want to run this program as a server,
add the "-qws" command-line option.

「-qws」オプションをつけて実行しろと言われている気がするので、それを付けて実行してみます。

Qtアプリの実行2

[armadillo ~/]# HelloArm -qws
QFontDatabase: Cannot find font directory /usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/fonts - is Qt installed correctly?
Aborted

次は、/usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/fonts ディレクトリが無いと言われたので、ディレクトリを作成してから再度実行してみます。

Qtアプリの実行3

[armadillo ~/]# mkdir -p /usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/fonts
[armadillo ~/]# HelloArm -qws

今度は、見事LCDに画面が表示されました!



が、タイトルバーのところが何かおかしいです。やはりフォントディレクトリを作成しただけで、フォント自体を入れていないのが問題でしょうか。。色々試してみたところ、以下の二つのファイルを実機にコピーすることで、文字が正しく表示されるようになりました。ホスト上のパスと、実機上のパスは同じです。
  • /usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/fonts/helvetica_120_50.qpf
  • /usr/local/Trolltech/QtEmbedded-4.7.1-generic/lib/fonts/helvetica_120_75.qpf
続いての問題は、カーソルが動かない点です。。Armadillo-440では、libtsを用いてタッチスクリーンの制御をしていたので、Qtでもこれを使いたいと思います。これまた色々調べてみたところ、ライブラリと環境変数を適切に設定してあげれば良いようです。

まず、ライブラリですが以下のファイルをコピーします。
 ホストPC上のパス 実機上のパス
 /usr/arm-linux-gnueabi/lib/libts-0.0.so.0.1.1 /lib/libts-0.0.so.0.1.1

これも、シンボリックリンクを張っておきます。
  • /lib/libts-0.0.so.0 -> /lib/libts-0.0.so.0.1.1
  • /usr/lib/libts-0.0.so.0 -> /lib/libts-0.0.so.0.1.1
そして、環境変数QWS_MOUSE_PROTOをexportしておきます。

環境変数QWS_MOUSE_PROTOのexport

export QWS_MOUSE_PROTO=tslib:/dev/input/event1

これで、タッチスクリーンが動くかな、と思いきや。。

Qtアプリの実行4

[armadillo ~/]# HelloArm -qws
Couldnt load module input
No raw modules loaded.
QWSTslibMouseHandlerPrivate: ts_config() failed with error: 'No such file or directory'
Please check your tslib installation!

「input」モジュールが無いと言われてしまいました。残念なことに、このモジュールはホストPCには存在しません。(libtsの共有オブジェクトはあるのに。。)これは、どうもクロス開発用ライブラリパッケージを作成するdpkg-crossの問題みたいです。この問題を解決するアプローチは二つあります。一つは、tslibのソースを持ってきて自前でビルドする方法、もう一つは、変換前のtslibのarmel用パッケージを持ってきてその中身をそのまま使う方法です。今回は、横着して後者の方法でやることにしました。

Debian packagesのページから、libtsを検索して、armelアーキテクチャのダウンロードページに移動します。いくつかあるミラーサイトのうち、適当なところからDebianパッケージをダウンロードします。

libtsのダウンロード

[PC ~/]$ wget http://ftp.jp.debian.org/debian/pool/main/t/tslib/libts-0.0-0_1.0-4_armel.deb

dpkg -xコマンドで、Debianパッケージの中身を取り出します。

dpkg -xでlibtsの中身を取り出す

[PC ~/]$ mkdir tmp
[PC ~/]$ dpkg -x libts-0.0-0_1.0-4_armel.deb ./tmp/

その中の、以下のファイルを実機にコピーしてください。
 ホストPC上のパス 実機上のパス
 ./tmp/usr/lib/ts/dejitter.so /usr/lib/ts/dejitter.so
 ./tmp/usr/lib/ts/input.so /usr/lib/ts/input.so
 ./tmp/usr/lib/ts/linear.so /usr/lib/ts/linear.so
 ./tmp/usr/lib/ts/pthres.so /usr/lib/ts/pthres.so
 ./tmp/usr/lib/ts/variance.so /usr/lib/ts/variance.so

以上の設定をすると、ようやくタッチスクリーンでカーソルを動かすことができるようになります。



以上で、Qt4を使ったアプリをARMボードで一通り動作させることができるようになりました。アプリ実行直後はウィンドウが全画面になっていない(右上の四角ボタンをクリックすれば全画面になります)とか、右上の×ボタンをクリックするとSegmentation Faultで終了するとか、色々と問題はありますが、そこは突っ込まないでください :-) Qt CreaterというIDEを使って組み込み向けのGUIを作成できるようになると、色々と捗りそうです。

コメント

「ARMボードでQt4を動かす」へのコメント



「ARMボードでQt4を動かす」へのコメント


Comments