用了一天多時間,終於一步步建立起了qtopia的交叉編譯環境,過程之繁瑣,以前還沒有遇見過。
平台:ubuntu 10.10 arm-linux-gcc-4.3.2
參考資料:《嵌入式linux應用開發完全手冊》 韋東山
下面開始arm版本Qtopia2.2.0版本的編譯
如果您還沒有安裝arm-linux-gcc-4.4.1 交叉編譯器,請先安裝該交叉編譯器到/usr/local/arm 下面,把arm-linux-gcc-4.4.1壓縮包解壓到該目錄即可完成安裝。
需要注意的是:
1 編譯Qtopia時確保您的Ubantu9.10環境中安裝了GNU g++編譯器,Qtopia編譯過程中用這個編譯器用來編譯一些工具在PC上運行.
2 注意您的Ubantu中要安裝X11的SDK庫,Qtopia編譯過程中需要使用X11SDK裡面的一些標頭檔,使用以下命令即可安裝需要的檔案
#apt-get install libx11-dev libxext-dev libxtst-dev
另外需要安裝工具uuid(Universally Unique Identifier,)和 xmu庫檔案, 編譯Qtopia2.2.0時需要這些在PC上啟動並執行工具和第三方庫檔案
apt-get install uuid-dev
apt-get install libxmu-dev libxmu6
如果不安裝 uuid和xmu將會出現下面的錯誤:
沒有安裝xmu時,編譯提示:
/usr/bin/ld:cannot find -lXmu
沒有安裝uuid時,編譯提示:
Creating pngscale...make[1]: Entering directory `/root/yizhi/qtopia-free-2.2.0/qtopia/util/pngscale'
..make[1]: *** [../../bin/pngscale] Error 1
make[1]: Leaving directory `/root/yizhi/qtopia-free-2.2.0/qtopia/util/pngscale'
Failed to make pngscale
3 編譯時間 虛擬機器中的ARM-qtopia-free-src-2.2.0.tar.gz 檔案不能放在與Windows共用的目錄中,否則會編譯出錯.
說明:以下的錯誤資訊是按照 先後順序 發現和處理的,使用者可以根據自己的錯誤類型資訊,自己進行修改.
這些錯誤是自己經曆並解決的,也參考了其他網友的一些辦法,總結一下,與大家分享
1 編譯錯誤:open函數參數不夠
/usr/include/bits/fcntl2.h:51: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT in second argument needs 3 arguments
解決辦法:
在Ubuntu 9.10上, gcc會嚴格檢查open()的參數傳遞,如果第二個參數為O_CREAT的話(就像qtopia-2.2.0- FriendlyARM/qt2/src /tools/qmemoryfile_unix.cpp的143行這樣),必須傳入第三個參數mode。因此,手動修改x86-qtopia- 2.2.0/qt2/src/tools/qmemoryfile_unix.cpp 143行將
if (!f)
f = open(tmpFile.latin1(), O_CREAT | O_WRONLY);
修改為
if (!f)
f = open(tmpFile.latin1(), O_CREAT | O_WRONLY, 0666);
2 使用未定義的類
error: ‘QWSInputMethod’ has not been declared
修正方法:
cd $QTDIR/src/kernel
gedit qwindowsystem_qws.h
在前面增加以下兩行
class QWSInputMethod;
class QWSGestureMethod;
該檔案中使用了這兩個類,C++允許在檔案中這樣聲明其他地方定義的類,減少標頭檔的相互內含項目關聯性,加快編譯速度
3 缺少標頭檔
錯誤資訊:
kernel/qpixmapcache.cpp:125:57: error: asm/page.h: No such file or directory
kernel/qpixmapcache.cpp: In constructor ‘QSharedMemoryManager::QSharedMemoryManager()’:
kernel/qpixmapcache.cpp:539: error: ‘PAGE_SIZE’ was not declared in this scope
kernel/qpixmapcache.cpp:539: error: ‘PAGE_MASK’ was not declared in this scope
kernel/qpixmapcache.cpp: In member function ‘void QSharedMemoryManager::internal_free(QSMemPtr)’:
kernel/qpixmapcache.cpp:773: error: ‘PAGE_SIZE’ was not declared in this scope
kernel/qpixmapcache.cpp:773: error: ‘PAGE_MASK’ was not declared in this scope
make[1]: *** [tmp/release-shared-linux-generic-g++-no-keypad/kernel/qpixmapcache.o] Error 1
make[1]: Leaving directory `/root/yizhi/host/qtopFolder[
解決辦法:2.6核心中不再含有asm-i386的page.h 修改qt2/src/kernel/qpixmapcache.cpp 檔案
#ifdef THROW_AWAY_UNUSED_PAGES
# include <sys/mman.h> // madvise
#define PAGE_SHIFT 12 //new add 2010-12-10
#define PAGE_SIZE (1UL << PAGE_SHIFT) //new add 2010-12-10
#define PAGE_MASK (~(PAGE_SIZE-1)) //new add 2010-12-10
//# include <asm/page.h> // PAGE_SIZE,PAGE_MASK,PAGE_ALIGN //注釋掉,不需要此行 2010-12-10
還有其他地方也用到了該標頭檔,同樣需要去掉。
轉至 ./qtopia-free-2.2.0/qt2/tools/qvfb/qvfbview.cpp
第39行,#include<asm/page.h> 這行注釋掉就行了。
4 類型轉換錯誤
/home/work/armqt/qtlibsource/qt-x11/include/qvalue stack.h: In member function 'T QValueStack<T>::pop() [with T = QMap<QString, QString>]':
xml/qxml.cpp:513: instantiated from here
/home/work/armqt/qtlibsource/qt-x11/include/qvalue stack.h:57: 錯誤:不能從'QValueListIterator<QMap<QString, QString> >'轉換到'const char*',為實參'1'(屬於'int remove(const char*)')
/home/work/armqt/qtlibsource/qt-x11/include/qvalue stack.h: In member function 'T QValueStack<T>::pop() [with T = QString]':
xml/qxml.cpp:2502: instantiated from here
/home/work/armqt/qtlibsource/qt-x11/include/qvalue stack.h:57: 錯誤:不能從'QValueListIterator<QString>'轉換到'const char*',為實參'1'(屬於'int remove(const char*)') 解決辦法:vi include/qvaluestack.h
解決辦法:
template<class T>
class Q_EXPORT QValueStack : public QValueList<T>
{
public:
QValueStack() {}
~QValueStack() {}
void push( const T& d ) { append(d); }
T pop()
{
T elem( this->last() );
if ( !this->isEmpty() )
this->remove( this->fromLast() );// add "this->" 2010-12-10
return elem;
}
5 沒有找到uic工具 錯誤提示:
make[5]: /root/yizhi/host/qtopia-free-2.2.0/qt2/bin/uic: Command not found
make[5]: *** [../../../include/qtopia/private/passwordbase_p.h] Error 127
解決辦法:
cd到你的qtopia-free-2.2.0目錄下, find ./ -name uic 會看到其他的目錄下已經有了uic,我把qt3/bin
目錄下的uic拷貝到 qt2/bin下面,即可
6 多餘的符號錯誤,即類的成員函數在標頭檔中不需要加類名
qdawg.cpp:294: error: extra qualification ‘QDawgPrivate::’ on member ‘QDawgPrivate’
make[5]: *** [.obj/release-shared/qdawg.o]o o
解決辦法:
qtopia-free-2.2.0/qtopia/src/libraries/qtopia/qdawg.cpp 裡面的
QDawgPrivate::~QDawgPrivate()
{
delete memoryFile;
}
修改為:
~QDawgPrivate() // delete "QDawgPrivate::~" 2010-12-10
{
delete memoryFile;
}
7
指標類型轉換出錯:
backend/vobject.cpp: In function ‘VObject* addGroup(VObject*, const char*)’:
backend/vobject.cpp:419: error: invalid conversion from ‘const char*’ to ‘char*’
backend/vobject.cpp: In function ‘void writeEncString(OFi
解決辦法:
修改 qtopia-free-2.2.0/qtopia/src/libraries/qtopia/backend/vobject.cpp 檔案149行
char *dot = strrchr(g,'.'); 修改為 char *dot = (char *)strrchr(g,'.');
8
錯誤:編譯器找不到QSizePolicy類的五個參數的建構函式
ui/release-shared/passwordbase_p.cpp:35: error: no matching function for call to ‘QSizePolicy::QSizePolicy(QSizePolicy::SizeType, QSizePolicy::SizeType, int, int, bool)’
/root/yizhi/host/qtopia-free-2.2.0/qt2/include/qsizepolicy.h:93: note: candidates are: QSizePolicy::QSizePolicy(int)
/root/yizhi/host/qtopia-free-2.2.0/qt2/include/qsizepolicy.h:99: note: QSizePolicy::QSizePolicy(QSizePolicy::SizeType, QSizePolicy::SizeType, bool)
/root/yizhi/host/qtopia-free-2.2.0/qt2/include/qsizepolicy.h:63: note: QSizePolicy::QSizePolicy()
/root/yizhi/host/qtopia-free-2.2.0/qt2/include/qsizepolicy.h:46: note: QSizePolicy::QSizePolicy(const QSizePolicy & )
解決辦法:
qtopia-free-2.2.0/qtopia/src/libraries/qtopia/.ui/release-shared/passwordbase_p.cpp 檔案中的38行位置
prompt = new QLabel( this, "prompt" );
prompt->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)1, 0, 0, prompt->sizePolicy().hasHeightForWidth() ) );
修改為:
prompt = new QLabel( this, "prompt" );
prompt->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)1, prompt->sizePolicy ().hasHeightForWidth() ) );
即去掉0,0 兩個參數
9 g++編譯器提示 有多餘的符號在成員函數前 ,有些編譯器規定C++成員函數前不需要再加這個類的名字,與第6處錯誤雷同
thumbnailview_p.h: At global scope:
thumbnailview_p.h:81: error: extra qualification ‘ThumbnailItem::’ on member ‘paintItem’
make[5]: *** [.obj/release-shared/imageselector.o] Eopia/src
解決辦法 :
qtopia-free-2.2.0/qtopia/src/libraries/qtopia2/thumbnailview_p.h檔案中第81行:
修改 void ThumbnailItem::paintItem( QPainter*, const QColorGroup& );
修改後 void paintItem( QPainter*, const QColorGroup& );
繼續編譯後會出現類似的錯誤
abtable_p.h:276: error: extra qualification ‘PhoneTypeSelector::’ on member ‘addType’
make[5]: *** [.obj/release-shared/abtable.o] Error 1
make[5]: Leaving directory `/root/yizhi/host/qtopia-free-2.2.0/qtopia/src/libraries/qtopiapim'
make[4]: *** [all] Error 2
解決辦法:
修改 qtopia-free-2.2.0/qtopia/src/libraries/qtopiapim/abtable_p.h 檔案中276行
QListViewItem* PhoneTypeSelector::addType(QListViewItem* prevItem,
QString number, const char* pixmapName, PimContact::ContactFields phoneType);
修改為:
QListViewItem* addType(QListViewItem* prevItem,QString number, const char* pixmapName, PimContact::ContactFields phoneType);
也就是去掉 PhoneTypeSelector::
繼續編譯:
../../../include/qtopia/pim/private/../../../../src/libraries/qtopiapim/numberentry_p.h: At global scope:
../../../include/qtopia/pim/private/../../../../src/libraries/qtopiapim/numberentry_p.h:106: error: extra qualification ‘NumberEntryDialog::’ on member ‘eventFilter’
make[5]: *** [.obj/release-shared/numberentry.o] Error 1
make[5]: Leaving directory `/root/yizhi/host/qtopia-free-2.2.0/qtopia/src/libraries/qtopiapim'
make[4]: *** [all] Error 2
解決辦法:
修改 qtopia-free-2.2.0/qtopia/src/libraries/qtopiapim/numberentry_p.h 第106行
bool NumberEntryDialog::eventFilter(QObject *o, QEvent *e);
修改為 bool eventFilter(QObject *o, QEvent *e);
繼續:
make[5]: Leaving directory `/root/yizhi/host/qtopia-free-2.2.0/qtopia/src/libraries/mediaplayer'
make[4]: *** [all] Error 2
make[4]: Leaving directory `/root/yizhi/host/qtopia-free-2.2.0/qtopia/src/libraries/mediaplayer'
修改 qtopia-free-2.2.0/qtopia/src/libraries/mediaplayer/videoviewer.cpp 檔案 52行
SimpleVideoWidget::SimpleVideoWidget(QWidget *parent);
修改後:
SimpleVideoWidget(QWidget *parent); //建構函式
繼續編譯
In file included from addressbook.cpp:40:
ablabel.h: At global scope:
ablabel.h:78: error: extra qualification ‘AbLabel::’ on member ‘decodeHref"
解決辦法:
修改 qtopia-free-2.2.0/qtopia/src/applications/addressbook/ablabel.h 78行
bool AbLabel::decodeHref(const QString& href, ServiceRequest* req, QString* pm) const;
修改為 bool decodeHref(const QString& href, ServiceRequest* req, QString* pm) const;
10 又一處未經定義的建構函式錯誤提示:
.ui/release-shared/emaildlg.cpp: In constructor ‘EmailDialogBase::EmailDialogBase(QWidget*, const char*, bool, uint)’:
.ui/release-shared/emaildlg.cpp:65: error: no matching function for call to ‘QSizePolicy::QSizePolicy(QSizePolicy::SizeType, QSizePolicy::SizeType, int, int, bool)’
/root/yizhi/host/qtopia-free-2.2.0/qt2/include/qsizepolicy.h:93: note: candidates are: QSizePolicy::QSizePolizePolicj 4
修改 qtopia-free-2.2.0/qtopia/src/applications/addressbook/.ui/release-shared/emaildlg.cpp 檔案第65行
okButton = new QPushButton( this, "okButton" );
okButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, 0, 0, okButton->sizePolicy().hasHeightForWidth() ) );
Layout2->addWidget( okButton );
cancelButton = new QPushButton( this, "cancelButton" );
cancelButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, 0, 0, cancelButton->sizePolicy().hasHeightForWidth() ) );
Layout2->addWidget( cancelButton );
修改為
okButton = new QPushButton( this, "okButton" );
okButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0,okButton->sizePolicy().hasHeightForWidth() ) );
Layout2->addWidget( okButton );
cancelButton = new QPushButton( this, "cancelButton" );
cancelButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0,cancelButton->sizePolicy().hasHeightForWidth() ) );
Layout2->addWidget( cancelButton );
繼續編譯:
錯誤提示:.ui/release-shared/camerabase.cpp:41: error: no matching function for call to ‘QSizePolicy::QSizePolicy(QSizePolicy::SizeType, QSizePolicy::SizeType, int, int, bool)’
/root/yizhi/host/qtopia-free-2.2.0/qt2/include/qsizepolicy.h:93: note: candidates are: QSizePolicy::QSizePolicy(int)
解決辦法:
編輯 qtopia-free-2.2.0/qtopia/src/applications/camera/.ui/release-shared/camerabase.cpp 檔案的第41行
videocaptureview->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, 0, 0, videocaptureview->sizePolicy().hasHeightForWidth() ) );
修改為:
videocaptureview->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, videocaptureview->sizePolicy().hasHeightForWidth() ) );
繼續編譯。同樣是這個類型的錯誤,這裡就不再列出了,使用者可以仿照上面的方法,根據錯誤提示資訊,自己進行修改,修改後儲存,繼續編譯。
這裡的情況是每次只能修改一個檔案,改完後編譯,才能進行下一個檔案。所以,很費時間,不知道有沒有好的方法?
11
/usr/local/arm/4.1.2/bin/../lib/gcc/arm-angstrom-linux-gnueabi/4.1.2/../../../../arm-angstrom-linux-gnueabi/bin/ld: warning: libts-0.0.so.0, needed by /home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/lib/libQtGui.so, not found (try using -rpath
or -rpath-link)
/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/lib/libQtGui.so: undefined reference to `ts_read_raw'
/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/lib/libQtGui.so: undefined reference to `ts_open'
/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/lib/libQtGui.so: undefined reference to `ts_fd'
/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/lib/libQtGui.so: undefined reference to `ts_config'
/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/lib/libQtGui.so: undefined reference to `ts_close'
/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/lib/libQtGui.so: undefined reference to `ts_read'
collect2: ld returned 1 exit status
make[2]: *** [deform] Error 1
make[2]: Leaving directory `/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/demos/deform'
make[1]: *** [sub-deform-make_default] Error 2
make[1]: Leaving directory `/home/stillwater/4.1.2/qt-everywhere-opensource-src-4.6.0/demos'
make: *** [sub-demos-make_default-ordered] Error 2
解決辦法:
修改qt-everywhere-opensource-src-4.6.0/mkspecs/qws/linux-arm-g++/qmake.conf 檔案(添加lts參數):
QMAKE_CC = arm-linux-gcc -lts
QMAKE_CXX = arm-linux-g++ -lts
QMAKE_LINK = arm-linux-g++ -lts
QMAKE_LINK_SHLIB = arm-linux-g++ -lts