2009年1月29日 星期四

在PXA270成功編譯Qt-embedded程式

Host操作系統:Ubuntu 8.04
GCC版本:4.2.4
Target:XScale-PXA270
Cross-compiler:Cross-2.95.3
Qt/E版本:Qt-embedded-free-3.3.8、Qt-x11-free-3.3.8

1、安裝cross-compiler
1.1、Download cross-2.95.3.tar.bz2
1.2解壓縮到/usr/local/arm

[ren@host ~]$ sudo tar -jxvf cross-2.95.3.tar.bz2 -C /usr/local/arm


2、使用Qt測試GUI
2.1、Build uic & moc From QT-X11
2.1.1、Download qt-x11-free-3.3.8.tar.bz2
2.1.2、為了避免權限的問題,先把/opt的權限改為目前的使用都可以存取的權限(目前我的使用者是ren),以下指令的意思是把/opt的owner與group均改為ren

[ren@host ~]$ sudo chown ren:ren /opt

2.1.3、將下載的檔案解壓縮到/opt底下,並更名為qtx

[ren@host ~]$ sudo tar -jxvf qt-x11-free-3.3.8.tar.bz2 -C /opt
[ren@host ~]$ cd /opt
[ren@host /opt]$ mv qt-x11-free-3.3.8 qtx


2.1.4、安裝xorg-dev套件,否則會產生以下錯誤!!!!!

[ren@host ~]$ sudo apt-get install xorg-dev

2.1.5、設定參數產生Makefile

[ren@host /opt/qtx]$ ./configure

2.1.6、編譯原始碼

[ren@host /opt/qtx]$ make

在/opt/qtx/bin下會產生uic與moc這兩個等一下我們會使用到的檔案

2.2、Build QT-Embedded
2.2.1、Download qt-embedded-free-3.3.8.tar.bz2
2.2.2、將下載的檔案解壓縮到/opt底下,並更名為qte

[ren@host ~]$ sudo tar -jxvf qt-embedded-free-3.3.8.tar.bz2 -C /opt
[ren@host ~]$ cd /opt
[ren@host /opt]$ mv qt-embedded-free-3.3.8 qte

2.2.3、將剛剛編譯好的uic及moc複製到/opt/qte/bin底下

[ren@host /opt]$ cp qtx/bin/moc /qte/bin
[ren@host /opt]$ cp qtx/bin/uic /qte/bin

2.2.4、設定cross-compiler到路徑中

[ren@host ~]$ export PATH=/usr/local/arm/2.95.3/bin:$PATH

2.2.5、設定參數產生Makefile

[ren@host /opt/qte]$ ./configure -no-cups -no-stl -no-ipv6 -thread -no-gfx-qvfb -no-freetype -disable-opengl -disable-xml -disable-canvas -embedded arm -shared -xplatform qws/linux-arm-g++

2.3、在主機端編譯source code讓執行程式
2.3.1、設定PATH

[ren@host ~]$ export QTDIR=/opt/qte
[ren@host ~]$ export QTEDIR=$QTDIR
[ren@host ~]$ export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
[ren@host ~]$ export PATH=$QTDIR/bin:/usr/local/arm/2.95.3/bin:$PATH

2.3.2、Compile Xscale版本的hello
hello的程式碼

#include <qapplication.h>
#include <qpushbutton.h>
int main(int argc,char **argv)
{
  QApplication app(argc,argv);
  QPushButton hello(“Hello World!!”,0);
  hello.resize(100,30);
  QObject::connect(&hello,SIGNAL(clicked()),qApp,SLOT(quit()));
  app.setMainWidget(&hello);
  hello.show();
  return app.exec();
}

2.3.3、編譯出.pro檔

[ren@host ~]$ qmake -project

2.3.4、依.pro檔編譯出Makefile

[ren@host ~]$ qmake

2.3.5、修改Makefile,把內容為
g++改成arm-linux-g++
gcc改成arm-linux-gcc
2.3.6、編譯出執行檔

[ren@host ~]$ make (或make sub-src表示不編譯範例)


假設隨身碟掛載點是/media/usb
2.3.7、把執行檔複製到隨身碟中

[ren@host ~]$ cp -rv hello /media/usb

2.3.8、把函式庫放與字型到隨身碟中

[ren@host ~]$ cp -rv /opt/qte/lib/fonts /media/usb
[ren@host ~]$ cp -v /opt/qte/lib/libqte-mt.so.3.3.8


2.4、把隨身碟插入XScale-PXA270中
2.4.1、掛載隨身碟

[root@host ~]$ mount /dev/sda1 /mnt

2.4.2、建立QTE目錄

[ren@host ~]$ mkdir -p /opt/qte/lib

2.4.3、建立軟連結

[ren@host ~]$ ln -s /mnt/fonts/fonts /opt/qte/lib/fonts
[ren@host ~]$ ln -s /mnt/libqte-mt.so.3.3.8 libqte-mt.so
[ren@host ~]$ ln -s /mnt/libqte-mt.so.3.3.8 libqte-mt.so.3
[ren@host ~]$ ln -s /mnt/libqte-mt.so.3.3.8 libqte-mt.so.3.3
[ren@host ~]$ ln -s /mnt/libqte-mt.so.3.3.8 libqte-mt.so.3.3.8

2.4.4、設定PATH

[ren@host ~]$ export QTDIR=/opt/qte
[ren@host ~]$ export QTEDIR=/opt/qte
[ren@host ~]$ export LD_LIBRARY_PATH=$QTDIR/lib
[ren@host ~]$ export PATH=$QTDIR/bin:$PATH

2.4.5、設定滑鼠

[ren@host ~]$ cd /dev
[ren@host /dev]$ mknod psaux c 10 1
[ren@host /dev]$ ln -s psaux mouse


2.4.6、執行程式

[ren@host ~]$ /mnt/hello -qws









錯誤訊息:
1. 若有出現以下錯誤,請重新執行Build QT-Embedded步驟=>(把qte刪掉,再重編一次!!)

出現的錯誤:
../include/qstring.h: In member function 'ushort& QChar::unicode()':
../include/qstring.h:199: error: cannot bind packed field
'((QChar*)this)->QChar::ucs' to 'ushort&'

2. 注意:make的時候由於對於qt3的交叉編譯工具的gcc版本問題而導致提示如下錯誤:

../include/qstring.h: In member function 'ushort& QChar::unicode()':
../include/qstring.h:199: error: cannot bind packed field
'((QChar*)this)->QChar::ucs' to 'ushort&'

解決辦法:
打開src/tools/qglobal.h查看318-326行:
# if (defined(__arm__) || defined(__ARMEL__)) && !defined(QT_MOC_CPP)
# define Q_PACKED __attribute__ ((packed))
# if __GNUC__ == 3 && __GNUC_MINOR__ >= 4
# define Q_NO_PACKED_REFERENCE
# endif
# endif
# if !defined(__EXCEPTIONS)
# define Q_NO_EXCEPTIONS
# endif

修改如下:
# if (defined(__arm__) || defined(__ARMEL__)) && !defined(QT_MOC_CPP)
# define Q_PACKED __attribute__ ((packed))
# if __GNUC__ == 3 && __GNUC_MINOR__ >= 4
# define Q_NO_PACKED_REFERENCE
# endif
+# if __GNUC__ == 4 && __GNUC_MINOR__ >= 0
+# define Q_NO_PACKED_POINTERS
+# endif
# endif
# if !defined(__EXCEPTIONS)
# define Q_NO_EXCEPTIONS
# endif

打開src/include/qstring.h查看195-199行
ushort unicode() const { return ucs; }
#ifdef Q_NO_PACKED_REFERENCE
ushort &unicode() { return *(&ucs); }
#else
ushort &unicode() { return ucs; }
#endif

修改如下:
ushort unicode() const { return ucs; }
#ifdef Q_NO_PACKED_REFERENCE
ushort &unicode() { return *(&ucs); }
+#elif defined Q_NO_PACKED_POINTERS
+ ushort &unicode() { ushort& tmp = ucs; return tmp; }
#else
ushort &unicode() { return ucs; }
#endif

ps:+號表示修改的地方


參考資料:
QT/Embedded-3.3.8初步交叉編譯的完全整理
Qt/Embedded 2.3.10 到PXA270上的移植
Qt-embedded-3.2.3到PXA270上的移植
Porting QT/Embedded-3.3.6 on PXA270

沒有留言: