2008/01/29

Porting linphone to PXA270

前言
最近在幫別人做embeded system design的期末作業,這作業主要是要讓板子pxa270能有網路電話的功能voip。

我嘗試了兩套softphone,分別為pjsip及linphone,就這兩套來講那一套比較適合拿來開發我會推薦使用pjsip,主要是因它是提供了一套library來讓開發者使用,所以對於往後的ui開發,需要增加自己的額外功能時,pjsip一定是首選。

然而,我們這次作業並沒有使用pjsip,是因pjsip我們cross-compiler完後,使用它的voip功能,電話播通後卻無法成功將聲音播出或送出去,但直接使用其library放音卻可以。

最後我們放棄使用pjsip,改換成linphone來porting,linphone有為需要cross-compile的人寫了一份參考文件,但該文件略嫌簡略,又有些地方有誤,故我將compile經過重新記錄一次,以供大家參考。

Porting過程
在porting前必需先將需要幾個dependency package抓好(依編譯順序排列):
  • readline-5.2
  • ncurses-5.6
  • libosip2-3.0.3
  • libeXosip2-3.0.3
  • libogg-1.1.3
  • speex-1.2beta3
  • linphone-2.0.1
首先,先設定一些環境變數
export ARM_INSTALL_TREE=/home/timy/armbuild
export PATH=$PATH:/opt/microtime/pro/devkit/arm/pxa270/gcc-4.0.2-glibc-2.3.3/arm-unknown-linux-gnu/bin
開始編譯:
Cross compiling ncurses for ARM:
********************************
./configure --prefix=/usr --host=arm-linux --with-gnu-ld --with-shared
make
make install DESTDIR=$ARM_INSTALL_TREE
make install DESTDIR=`pwd`/armbuild
Cross compiling readline for ARM:
*********************************
./configure --prefix=/usr --host=arm-unknown-linux-gnu --with-gnu-ld --disable-static
make
make install DESTDIR=$ARM_INSTALL_TREE
make install DESTDIR=`pwd`/armbuild
Cross compiling libosip for ARM:
********************************
./configure --prefix=/usr --host=arm-unknown-linux-gnu --with-gnu-ld --disable-static
make
make install DESTDIR=$ARM_INSTALL_TREE
make install DESTDIR=`pwd`/armbuild
Cross compiling libeOsip for ARM:
********************************
./configure --prefix=/usr --host=arm-unknown-linux-gnu --with-gnu-ld --disable-static CFLAGS=-I$ARM_INSTALL_TREE/usr/include LDFLAGS=-L$ARM_INSTALL_TREE/usr/lib
make
make install DESTDIR=$ARM_INSTALL_TREE
make install DESTDIR=`pwd`/armbuild
Cross compiling libogg for ARM:
********************************
./configure --prefix=/usr --host=arm-unknown-linux-gnu --with-gnu-ld --disable-static
make
make install DESTDIR=$ARM_INSTALL_TREE
make install DESTDIR=`pwd`/armbuild

Cross compiling speex for ARM:
********************************
First you need to remove ogg headers from your build system to avoid a dirty conflict between your build machine binaries and the arm binaries. They are usually in a libogg-dev package (rpm or deb).
Then:
./configure --prefix=/usr --host=arm-unknown-linux-gnu --with-gnu-ld --disable-static --enable-arm-asm CFLAGS=-I$ARM_INSTALL_TREE/usr/include LDFLAGS=-L$ARM_INSTALL_TREE/usr/lib
make
make install DESTDIR=$ARM_INSTALL_TREE
make install DESTDIR=`pwd`/armbuild
Cross compiling linphone for ARM
********************************
First you need to remove all .la files from the ARM_INSTALL_TREE because it confuses libtool and makes
the linker use your build machine binaries instead of the arm-crosscompiled ones.
rm -f $ARM_INSTALL_TREE/usr/lib/*.la
#for some reason pkg-config doesn't like cross-compiling...
export PKG_CONFIG=/usr/bin/pkg-config./configure --prefix=/usr \
--host=arm-unknown-linux-gnu \
--with-osip=$ARM_INSTALL_TREE/usr \
--with-readline=$ARM_INSTALL_TREE/usr \
--includedir=$ARM_INSTALL_TREE/usr/include \
--enable-gtk_ui=no \
--enable-console_ui=yes \
--includedir=$ARM_INSTALL_TREE/usr/include \
--disable-video \
SPEEX_CFLAGS="-I$ARM_INSTALL_TREE/usr/include" \
SPEEX_LIBS="-L$ARM_INSTALL_TREE/usr/lib -lspeex -lspeexdsp" \
LDFLAGS="-L$ARM_INSTALL_TREE/usr/lib" \
LIBS="-leXosip2 -losip2 -losipparser2" \
CFLAGS="-I$ARM_INSTALL_TREE/usr/include"
make
make install DESTDIR='pwd'/armbuild


問題與討論
configure或compile時出現錯誤 T_T
遇到錯誤時,我的處理方法大都是:
  1. 判斷錯誤發生原因,藉由:
    • 螢幕上的輸出
    • log檔(for example, config.log)
  2. 重製錯誤(configure錯誤可以跳過此步)
    • 稍後會有詳細解說
  3. 解決問題
    • 大部分的問題皆是修改CFLAGS, LIBS, LDFALGS這幾個參數,至於這幾個參數的用處,請自己google一下gcc的compile教學,或是問人會比較快。
底下我將舉一個make時發生的錯誤,這是在編linphone時發生的錯誤:
gcc -shared .libs/linphonecore.o .libs/exevents.o .libs/misc.o .libs/enum.o .libs/sdphandler.o .libs/presence.o .libs/proxy.o .libs/friend.o .libs/authentication.o .libs/lpconfig.o .libs/chat.o .libs/general_state.o -Wl,--rpath -Wl,/home/fcwu/arm/src/linphone-2.0.1/mediastreamer2/src/.libs -Wl,--rpath -Wl,/home/fcwu/arm/usr/lib -leXosip2 -losipparser2 -losip2 ../mediastreamer2/src/.libs/libmediastreamer.so -Wl,-soname -Wl,liblinphone.so.2 -o .libs/liblinphone.so.2.0.1
/usr/bin/ld: cannot find -leXosip2
collect2: ld returned 1 exit status
make[2]: *** [liblinphone.la] Error 1
make[2]: Leaving directory `/home/fcwu/arm/src/linphone-2.0.1/coreapi'
從倒數第4行可以看到ld(linker)找不到libeXosip2.so,我第一個假設會是"尋找library的路徑"設定有錯,換句話說就是LDFLAGS有問題,為了證實確實是發生這問題,我們可以到/home/fcwu/arm/src/linphone-2.0.1/coreapi目錄下輸入arm-linux那行(第一行)看看會不會產生這個錯誤,若確實產生這個錯誤再append "-L/home/fcwu/arm/usr/lib",看看問題是否解決。等確定無誤後,重新./configure一次,並加入LDFALGS="-L/home/fcwu/arm/usr/lib"即可。

../coreapi/.libs/liblinphone.so: undefined reference to `ms_alsa_card_new_custom'
參考這個討論串裡的diff檔,修改即可。

出現asm...的錯誤
這是由於arm-linux-gcc不支援inline assembly的某些寫法(?)造成了。解法我是移植Linux kernel source code裡的include/asm-arm/裡的__FD_ZERO等4個micro到compiling的機器上的/usr/include/sys/select.h(應該是這個位置)。
這個問題應該有更好的解法,但是我很懶。

參考資料
  • Linphone的porting,可以參考以下幾個文件:
  • 在linphone資料匣內的README.arm(最重要)
  • 在linphone資料匣內的README.arm
  • 在linphone資料匣內的INSTALL
  • ./configure --help

2 comments:

Xman said...

hello,
I have a question that why need "make install DESTDIR=`pwd`/armbuild"?
Is that mean that install to another pwd/armbuild directory?

Rickey said...

@Xman

Yes, I installed all the files to `pwd`/armbuild, and the objective is to distinguish between x86 and arm version.