s3c6410 arm移植實驗四:qte4.8.5移植,其中AWK和sed的應用!

ARM 378瀏覽

文章主要內容有:先介紹下QtE,再說說我的QtE4.8.5移植。


Qtopia和QtE:

Qtopia和QtE是不同的!
慚愧,剛開始著手移植工作的時候,沒有搞清楚Qtopia和QtE的區別,再加上我用的是從一個離職很久的同事機器上翻出來的source code。弄得是各種混亂。

網友彬ye介紹:

值得特別注意的是在版本4之前,Qt/E和Qtopia是不同的兩套程序,Qt/E是基礎類庫,Qtopia是構建于Qt/E之上的一系列應用程序。但從版本4開始,Trolltech將Qt/E并入到了Qtopia產品線中去了,并推出了新的Qtopia4。但實際上原來的Qt/E仍然作為基礎類庫,只是改名為Qtopia
Core了,也許又感覺Qtopia Core跟Qtopia容易讓人搞混,所以又改名為qt-embedded-linux-opensource-linux/wince(QT也支持Wince
)。它
作為嵌入式版本的核心,既可以與Qtopia配合,也可以獨立使用。而原來的Qtopia則被分成幾層,核心的應用框架和插件系統被稱為 Qtopia Platform,上層的應用程序則按照不同的目標用戶分為不同的包,如Qtopai PDA,Qtopia Phone。

Qte的改名過程,Qte-->Qtopia Core-->Qt-embedded-linux-xxxx --> qt-everywhere-opensource-src-xxxxx(目前是這樣的,博主注

這幾個其實差不多是一個東西,名稱很容易搞混。

記住在QT4版本前要安裝Qtopia需要先裝Qt/E,但之后的就不需要了。4之后的Qtopia 已經帶有QT/E庫了。

所以總的來說,QT也就三種:面向桌面的x11、面向嵌入式的Qt/E、以及面向嵌入式帶各種應用程序的Qtopia桌面系統!!!

這下清楚了,我的需求是就只要移植QtE好了。


QtE4.8.5

下載源代碼:(很多介紹移植的blog都不給個下載鏈接的。。。)
wget http://mirrors.neusoft.edu.cn/qt/official_releases/qt/4.8/4.8.5/qt-everywhere-opensource-src-4.8.5.tar.gz

再根據網友Vincent_Song的介紹(很清楚的了,可以參照他的操作執行)。

我的configure配置如下:
我把它寫成了腳本autoconf_QtE_4_8_5.sh,方便后續執行了。

  1. #!/bin/sh
  2. ./configure -prefix /usr/local/QtE_Zhangsh_4_8_5
  3. -opensource -confirm-license
  4. -xplatform qws/linux-arm-g++
  5. -embedded arm
  6. -little-endian
  7. -depths 4,8,16,24,32
  8. -shared
  9. -nomake docs
  10. -no-largefile
  11. -no-3dnow
  12. -no-sse
  13. -no-sse2
  14. -no-mmx
  15. -no-cups
  16. -no-iconv
  17. -no-gfx-vnc
  18. -no-svg
  19. -qt-gfx-linuxfb
  20. -qt-gfx-qvfb
  21. -qt-kbd-linuxinput
  22. -qt-mouse-tslib
  23. -qt-zlib
  24. -qt-freetype
  25. -qt-libtiff
  26. -qt-libpng
  27. -qt-libmng
  28. -qt-sql-sqlite
  29. -qt-libjpeg
  30. -qt3support
  31. -I/usr/local/tslib/include -L/usr/local/tslib/lib

值得注意的兩點:
1,QtE4.8.5的configure與4.5.3的不同,多看下configure文件就會明白,或者報錯的時候再見招拆招
2,須要先編譯tslib,因為我們要用tslib來做輸入,需要使用到tslib的頭文件和庫,在configure時指定:-I/usr/local/tslib/include -L/usr/local/tslib/lib,(我的tslib編好后,放在/usr/local/下)。

配置完以后
make
make install

以上,網上有比較詳細的介紹了。



我主要記錄下我遇到的一個錯誤
在編譯3rdparty和examples時,提示找不到tslib的庫

  1. make[3]: 進入目錄“/usr/local/src/qt-everywhere-opensource-src-4.8.5/examples/network/broadcastreceiver”
  2. arm-linux-g++ -c -pipe -I/usr/local/tslib/include -fno-exceptions -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I../../../mkspecs/qws/linux-arm-g++ -I. -I../../../include/QtCore -I../../../include/QtNetwork -I../../../include/QtGui -I../../../include -I.moc/release-shared-emb-arm -o .obj/release-shared-emb-arm/receiver.o receiver.cpp
  3. arm-linux-g++ -c -pipe -I/usr/local/tslib/include -fno-exceptions -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I../../../mkspecs/qws/linux-arm-g++ -I. -I../../../include/QtCore -I../../../include/QtNetwork -I../../../include/QtGui -I../../../include -I.moc/release-shared-emb-arm -o .obj/release-shared-emb-arm/main.o main.cpp
  4. /usr/local/src/qt-everywhere-opensource-src-4.8.5/bin/moc -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I../../../mkspecs/qws/linux-arm-g++ -I. -I../../../include/QtCore -I../../../include/QtNetwork -I../../../include/QtGui -I../../../include -I.moc/release-shared-emb-arm receiver.h -o .moc/release-shared-emb-arm/moc_receiver.cpp
  5. arm-linux-g++ -c -pipe -I/usr/local/tslib/include -fno-exceptions -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I../../../mkspecs/qws/linux-arm-g++ -I. -I../../../include/QtCore -I../../../include/QtNetwork -I../../../include/QtGui -I../../../include -I.moc/release-shared-emb-arm -o .obj/release-shared-emb-arm/moc_receiver.o .moc/release-shared-emb-arm/moc_receiver.cpp
  6. arm-linux-g++ -Wl,-rpath-link,/usr/local/src/qt-everywhere-opensource-src-4.8.5/lib -fno-exceptions -Wl,-O1 -Wl,-rpath,/usr/local/QtE_Zhangsh_4_8_5/lib -Wl,-rpath,/usr/local/QtE_Zhangsh_4_8_5/lib -o broadcastreceiver .obj/release-shared-emb-arm/receiver.o .obj/release-shared-emb-arm/main.o .obj/release-shared-emb-arm/moc_receiver.o -L/usr/local/tslib/lib -L/usr/local/src/qt-everywhere-opensource-src-4.8.5/lib -lQtGui -L/usr/local/tslib/lib -L/usr/local/src/qt-everywhere-opensource-src-4.8.5/lib -lQtNetwork -lQtCore -lpthread
  7. /opt/FriendlyARM/toolschain/4.4.3/lib/gcc/arm-none-linux-gnueabi/4.4.3/../../../../arm-none-linux-gnueabi/bin/ld: warning: libts-1.0.so.0, needed by /usr/local/src/qt-everywhere-opensource-src-4.8.5/lib/libQtGui.so, not found (try using -rpath or -rpath-link)
  8. /usr/local/src/qt-everywhere-opensource-src-4.8.5/lib/libQtGui.so: undefined reference to `ts_read_raw'
  9. /usr/local/src/qt-everywhere-opensource-src-4.8.5/lib/libQtGui.so: undefined reference to `ts_open'
  10. /usr/local/src/qt-everywhere-opensource-src-4.8.5/lib/libQtGui.so: undefined reference to `ts_fd'
  11. /usr/local/src/qt-everywhere-opensource-src-4.8.5/lib/libQtGui.so: undefined reference to `ts_config'
  12. /usr/local/src/qt-everywhere-opensource-src-4.8.5/lib/libQtGui.so: undefined reference to `ts_close'
  13. /usr/local/src/qt-everywhere-opensource-src-4.8.5/lib/libQtGui.so: undefined reference to `ts_read'
  14. collect2: ld returned 1 exit status
  15. make[3]: *** [broadcastreceiver] 錯誤 1
  16. make[3]: 離開目錄“/usr/local/src/qt-everywhere-opensource-src-4.8.5/examples/network/broadcastreceiver”
  17. make[2]: *** [sub-broadcastreceiver-make_default] 錯誤 2
  18. make[2]: 離開目錄“/usr/local/src/qt-everywhere-opensource-src-4.8.5/examples/network”
  19. make[1]: *** [sub-network-make_default] 錯誤 2
  20. make[1]: 離開目錄“/usr/local/src/qt-everywhere-opensource-src-4.8.5/examples”
  21. make: *** [sub-examples-make_default-ordered] 錯誤 2

提示沒有tslib的庫,當然了,提示中也清楚的說了(try using -rpath or -rpath-link)
我們可以:
1,進入到編譯報錯的目錄,在這里是“examples/network/broadcastreceiver
2,修改這個目錄中的Makefile文件,找到LFLAGS一行,在最后面加上”-Wl,-rpath,/usr/local/tslib/lib“,也就是手動指定tslib的目錄。(這里還沒清楚為何configure時的參數沒起作用)
3,就地make
4,退回到主目錄
5,繼續make
對應下面的粗體字的操作。

  1. [[email protected] qt-everywhere-opensource-src-4.8.5]# cd examples/network/broadcastreceiver
  2. [[email protected] broadcastreceiver]# vim Makefile
  3. [[email protected] broadcastreceiver]# make
  4. arm-linux-g++ -Wl,-rpath-link,/usr/local/src/qt-everywhere-opensource-src-4.8.5/lib -fno-exceptions -Wl,-O1 -Wl,-rpath,/usr/local/QtE_Zhangsh_4_8_5/lib -Wl,-rpath,/usr/local/QtE_Zhangsh_4_8_5/lib -Wl,-rpath,/usr/local/tslib/lib -o broadcastreceiver .obj/release-shared-emb-arm/receiver.o .obj/release-shared-emb-arm/main.o .obj/release-shared-emb-arm/moc_receiver.o -L/usr/local/tslib/lib -L/usr/local/src/qt-everywhere-opensource-src-4.8.5/lib -lQtGui -L/usr/local/tslib/lib -L/usr/local/src/qt-everywhere-opensource-src-4.8.5/lib -lQtNetwork -lQtCore -lpthread
  5. [[email protected] broadcastreceiver]# cd -
  6. /usr/local/src/qt-everywhere-opensource-src-4.8.5
  7. [[email protected] qt-everywhere-opensource-src-4.8.5]# make

利用腳本快速完成以上操作!
上面的操作,如果每個Makefile都要編輯一遍的話,那就太麻煩了,我們偷偷懶。

針對Makefile的LFLAGS一行的特點,我們使用find、grep、awk、sed、xargs來完成這個操作,如下:
進入到出錯目錄的頂層,如上示例,我們進入到examples。

  1. cd examples

  2. find . -name Makefile | xargs grep rpath-link | grep -v tslib | awk -F: '{fname[NR]=$1} END {for (i=1;i<=NR;i++){print fname[i]}}' | xargs sed -i 's/LFLAGS.*/& -Wl,-rpath,/usr/local/tslib/lib/'

<注意,這個命令會直接修改目錄中最底層的每一個Makefile,請試驗成功后再使用。>

解釋一下以上命令:

1,我們找到各個Makefile。

  1. find . -name Makefile

2,在以上基礎上用grep過濾,找到符合我們需求的Makefile。(需要添加"-Wl,-rpath,/usr/local/tslib/lib"但沒有添加的Makefile)

  1. find . -name Makefile | xargs grep rpath-link | grep -v tslib

3,使用awk,實現依次操作find文件的功能。

  1. find . -name Makefile | xargs grep rpath-link | grep -v tslib | awk -F: '{fname[NR]=$1} END {for (i=1;i<=NR;i++){print fname[i]}

4,開始處理。

  1. find . -name Makefile | xargs grep rpath-link | grep -v tslib | awk -F: '{fname[NR]=$1} END {for (i=1;i<=NR;i++){print fname[i]}}' | xargs sed -i 's/LFLAGS.*/& -Wl,-rpath,/usr/local/tslib/lib/'


注:在Makefile的最后添加"-Wl,-rpath,/usr/localtslib/lib"的操作,參照sed的手冊。

  1. sed -i 's/LFLAGS.*/& -Wl,-rpath,/usr/local/tslib/lib/' Makefile


這個命令,下班前急忙花了半個小時寫成的,應可以再優化一下。

有時退到主目錄的話,還是不能編譯。同時為了避免每個底層目錄都操做一遍,也可以在主目錄的次一級進行操作,如上例子中應是examples,在examples中執行make,完成后,回到主目錄接著執行make。

后面就沒什么錯誤了,編譯完成(4.8.5時間太長了,我的破機器前前后后用了至少8小時,可以在配置的時候-no-make-examples -no-make-demos等等)。



后續操作:
我們把編譯出的bin、lib、examples、test目錄拷貝到nfs系統中。
我是將這四個目錄拷貝到里nfs系統的“/qte”之下(自己新建),這里拷貝到什么地方無所謂,因為需要在ENV中說明的,在后續export ENV的時候指過去就行。

我的export,寫在/etc/profile中(包括了tslib):

  1. # Ash profile
    # vim: syntax= sh
    # No core file by defaults
    # ulimit - S - c 0> / dev/ null 2> & 1

    USER="id -un"
    LOGNAME=$USER
    PS1="[[email protected] w]#"
    PATH=$PATH
    HOSTNAME= '/bin/hostname'
    alias cls="clear"
    export USER LOGNAME PS1 PATH

  2. # tslib path
  3. export TSLIB_TSDEVICE=/dev/event0
  4. export TSLIB_CALIBFILE=/etc/pointercal
  5. export TSLIB_CONFFILE=/etc/ts.conf
  6. export TSLIB_PLUGINDIR=/lib/ts
  7. export TSLIB_CONSOLEDEVICE=none
  8. export TSLIB_FBDEVICE=/dev/fb0
  9. # qt path
  10. export QTDIR=/qte
  11. export QTDIRLIB=/qte/lib
  12. export LD_LIBRARY_PATH=$QTDIRLIB:$LD_LIBRARY_PATH
  13. export PATH=$PATH:$QTDIR/bin
  14. export QWS_KEYBOARD=USB:/dev/event1
  15. export QWS_MOUSE_PROTO=tslib:/dev/event0
  16. export QWS_SIZE=480x272
  17. export QT_QWS_FONTDIR=/qte/lib/fonts

因為我還沒些qt程序,所以將examples、test拷過去,打算用來試驗。


在執行的時候出現幾個問題,以下兩個錯誤跟內核的配置有關,感謝網友Channels_net的經驗分享

錯誤1:
QWSServerSocket::init: Function not implemented                                
QWSServerSocket: unable to create socket.                                      
QWSServerPrivate::initServer: server socket not listening: Illegal seek        
Failed to bind to /tmp/qtembedded-0/QtEmbedded-0

解決方法:
重新配置內核:# make menuconfig
選中:Networking——>Networlding options——>Unix domain sockets
重新編譯,再次燒入內核。

錯誤2:
Cannot create semaphore /tmp/qtembedded-root/QtEmbedded-0

這是說明系統禁止了鎖,可以在內核配置的第一個 generated配置里面找到:
[*] System V IPC
選上它,重新編譯,再次燒入內核。



后記;

由于后面還有其他工作,這次移植工作告一段落了,其實搞清楚了交叉編譯,多在網上檢索,參照代碼,移植工作還是會比較順利的。在這次移植工作中,也學習到了不少東西。

七星彩走势图2元网官网