星期四, 1月 26, 2006

ViewML : Open source web browser for embedded linux system

就是寫Microwindow的作者,的另一個計畫(?)。

他發現雖然opensource 的internet browser雖然已經有20幾種,但是大多很大,或是需要其他package。要不然就是功能太陽春,無法parse複雜的HTML tag。
所以他決定要作一套新的,可以用在embedded system,而且功能又OK的internet browser。
他決定要:
  1. 一套完整的internet browser,但是又很小,可以在很多embedd device中執行(像 pda, set-top-box。
  2. 使用現成的open source html parse engine,以免像其自行撰寫prase engine的browser一樣,prase能力很差。
  3. 使用Fast Light Toolkit(FLTK) framework 作為user interface。
  4. 可以在microwindow和X windows下執行。
所以他選了 KDE 的KFM使用的KDE1.0 HTML widget。因為他小,而且提供的功能已經購完整。至於Qt library這一點,將會由FLK 重新implement一次。

ViewML 分為以下module :

ViewML Browser Application Layer
用FLTK寫的application user interface。包裝起整個ViewML程式。處理user interface和network/local file access 介面。

W3C WWWLib
負責asychronous network i/o 和HTTP get function。這是WWW 協會的標準WWWLib。有點大,將來可能會自己重寫。

KHTML View/Widget
就是KDE 1.0 HTML Widget code。KHTML Widget 負責parse HTML,繪圖,但是scroll 則交由View去作。

Qt Compatiblity Layer
用FTLK 將所有KHTML用到的Qt function call寫出來,讓KHTML能夠不修改code,正常的執行。不直接拿Qt來用的原因是size問題。

IMLIB image library
gnome的image library。包含自動偵測image file format,decodeC 和show image。

FLTK Application Framework
有兩種版本: 給Win32, X 用的標準版FLTK,和給microwindow的nano-X用的重新寫過的FLTK。

因為利用了open source,完成的ViewML browser的code size只有800k,run time memory requirement也只有2M。整體,加上mircrowindow,只需要2.5M。
整個project是open source的。

project page在 www.viewml.com (但是已經變成pilix了)

freshmeat的ViewML也只有到0.21版。
真正的ViewML位置在PILIX ftp download site上 (ftp://ftp.pixil.org/pub/pixil)< >看來原作者很不爽繼續支援這個計畫,ViewML目前附屬在PIXIL 計畫(產品)下。在PIXIL 的developer mailing list上可以看到作者已經無意free support這個計畫。-- 甚至port 到new compiler version也不願意。對於一大堆大陸人的(Is anyone help me cross compile viewML for arm) 問題也不願回應。



build ViewML :

需要的library有
一般:
  • STL (這個好像是用STLport)
  • PThread (uclibc 有libpthread)
  • libwww - 去ftp download,同時需要libmd5
for nano-X
  • FLTK for Nano-X , flnx-current.tar.gz
  • Microwindows , with nano-X
準備好以上的package後...
解開viewml,在目錄中run .confiure,並且加入參數
./configure  --with-microwin=[Microwindows dir]  --with-fltk=[FLTK dir] --host=[prefix]
Microwindows dir 是microwindws 所在目錄
FLTK 也是一樣
prefix是toolchain的prefix,像arm-elf



libwww

不知道要怎樣在uclinux 下build。

紀錄一下cross build的一些option.
ARMTOOLSPREFIX = arm-linux-

libwww的installation 下有說明
Specifying the System Type

There may be some features configure can not figure out automatically, but needs to determine by the type of host the package will run on. Usually configure can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields:

CPU-COMPANY-SYSTEM

See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type.

If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package.
config.sub 是...,看了後,好像要設arm-linux :
./configure --target=arm-linux
build 出來後,看看Makefile,好像沒又設對gcc。所以用:<>CC=arm-elf-gcc ./configure --target=arm-linux卻看到 cannot find host,所以host也要指定。因為不知道要指定那一種所以用./configure看看...host system type... i686-pc-linux-gnu。
這次用
CC=arm-elf-gcc ./configure --target=arm-linux --host=i686-pc-linux-gnu
試試..但是output中checking for gcc 還是gcc,不是arm-elf-gcc,所以check cross-compiler 還是no.
$ echo ${CC-cc}
arm-elf-gcc
這個是正確的。
是config.cache的關係嗎?
把w3c-libwww整個delete掉,untar,再configure一次,OK !!正確detect出cross compile了。
接著作
$ make
Error :
Making all in xmltok
arm-elf-gcc -shared -Wl,-soname -Wl,libxmltok.so.0 -o .libs/libxmltok.so.0.1.0 xmlrole.lo xmltok.lo -lc
/home/charles/sigma/armutils_2.5.91.0/toolchain/lib/gcc-lib/arm-elf/2.95.3/libc.a(__uClibc_main.o): In function `__uClibc_start_main':
__uClibc_main.o(.text+0xf8): undefined reference to `main'
collect2: ld returned 1 exit status
是share library的問題?
改configure, disable share :
./configure --host=i686-pc-linux-gnu --prefix=~/libwww --disable-shared 2>&1 | tee output
OK!! 所以應該是shared library的問題。
因為ViewML沒有說一定要用shared library,所以先用static linking試試。

... make是過了,但是還沒install.
這樣的configure option 不能install 吧,因為沒設prefix,所以會裝在default folder裏(/usr/lib)。

...其實前一次會過是因為沒有設CXX=arm-elf-g++ 變數,所以checking variable size時都會OK。
使用:
 CC=arm-elf-gcc CXX=arm-elf-g++ ./configure  --host=i686-pc-linux-gnu --target=arm-linux --prefix=/home/charles/magsi/libwww --disable-shared 2>&1 | tee output
就會發生...
configure: error: can not run test program while cross compiling
Google的結果,這一篇似乎有一個解決的方法...
這是因為autoconfig沒有辦法知道target platform的char size,所以發出error(autoconfig利用run test program來偵測machine的var size)。
解覺的方法就是手動囉,因為只有build的人才會知道taget system的char size。
改configure...找到 echo "configure: error: can not run test program while cross compiling" 這一行,參考一下這一段是要 設定那一個變數,自己寫進去,改為:
ac_cv_sizeof_char=1
找一下所有這個message出現的地方,修改對應參數到正確的值...
因為資質弩鈍,所以有些type不知道,像arm的long type size是....?
所以只好真的build一個test program在taget board 上跑來試試..
使用的command是
arm-elf-gcc trysize.c -o trysize -Wl,-elf2flt="-s32768"
分別印出
char 1
char* 4
int 4
long 4
還要check time_t 是不是long : 就是time_t 的size和long 一不一樣
double 和long double是不是一樣: 寫給target board test的code是:

#include <stdio.h>
#include <time.h>
#include <stddef.h>

int isbigendian(void)
{
union
{
long l;
char c[sizeof(long)];
} u;
u.l=1;

return u.c[sizeof(long) -1] == 1;
}

int charisunsigned(void)
{
volatile char c= 255;
return c <0;
}
main()
{
printf("char:%d\n",sizeof(char));
printf("char*:%d\n",sizeof(char*));
printf("int:%d\n",sizeof(int));
printf("long:%d\n",sizeof(long));
printf("time_t:%d\n",sizeof(time_t));
printf("size_t:%d\n",sizeof(size_t));
printf("bigendian:%d\n",isbigendian());
printf("charisunsigned:%d\n",charisunsigned());
printf("double:%d\n",sizeof(double));
printf("long double:%d\n",sizeof(long double));

}

輸出的結果是:
char:1
char*:4
int:4
long:4
time_t:4
size_t:4
bigendian:0
charisunsigned:0
double:8
long double:8
實際上還是不知道long_double這一個選項是要設成yes還是no...







FTLK

一樣,解開。 README中說明INSTALL process:有說明configure時如果不是用g++,要指定CXX variable。gcc要指定CC variable。
$ CXX=arm-elf-g++
$ CC=arm-elf-gcc
$ ./configure --host=i686-pc-linux-gnu --preifx=/home/charles/libflnx
OK。正確check出cross compile。
$ make 
Error !!!
=== making fluid ===
make[1]: Entering directory `/home/charles/sigma/flnx/fluid'
.....
make[1]: *** No rule to make target `../lib/libfltk.a', needed by `fluid'. Stop.
make[1]: Leaving directory `/home/charles/sigma/flnx/fluid'
=== making test ===
make[1]: Entering directory `/home/charles/sigma/flnx/test'
make[1]: *** No rule to make target `../lib/libfltk.a', needed by `valuators'. Stop.
make[1]: Leaving directory `/home/charles/sigma/flnx/test'
make: *** [all] Error 2
這個....
應該要看一下flnx的INSTALL..

和libwww的方式不一樣,fltk 下的Makefile包含了config,所以直接在Makefile裏修改,加入configure的option。

./configure --host=i686-pc-linux-gnu --with-microwin=/home/charles/magsi/armutils_2.5.91.0/build_arm/src/microwin/src
但是還是一樣的錯。

真奇怪,不就是要build libfltk嗎?為什麼不知道要如何build libfltk ?
這是因為libfltk.a 是由src 目錄build出來,src目錄有錯。所以libfltk沒有build出來。

所以要先查src目錄make的錯誤...
....是找不到iostream.h...
設定-I option 到makeinclude 中
-I/home/charles/magsi/armutils_2.5.91.0/build_arm/STLport-4.5.3/stlport 
OK。但是出現putenv( ) undeclare!!!。
這 是因為stdlib.h include不正確,一樣,在剛剛的-I option 之前,要指定uclibc 的include 路徑,讓arm-elf-g++先去include uclibc的stdlib.h,所以makeinclude的-I option 要加上另一項(在STLport option 之前...
-I/home/charles/sigma/armutils_2.5.91.0/build_arm/uClibc -0.9.26/include
再build.. 還是有錯,說是filename_list.cxx中有一個cast不正確。到 source file中去看。是platform dependent code。在uclinux下應該要用linux 的code吧,需要define "linux",所以再到makeinclude中加入..
-Dlinux
OK!! src folder build OK.

然後是fluid folder的問題了....
internal error--unrecognizable insn:
Google 一下...
Hit the WALL !!!
原來是cross-compile 太複雜的C++ code時,會出現的error,mailinglist上有所謂的"unrecognuzabgle-insn.path",但是都是失效的link !

有兩個解決方法:
1.upgrade gcc
2.修改code

修改code好了@_@...
所以把出現error的function找出來,mark 掉一些section,找找看是那一個instruction發生問題..
發現...竟然是local variable array 的size太大!!!
把 MAXSIZE 改小就可以,--- 改到256後,pixmap_image::pixmap_image 沒錯。
--- 也試過用new 也可以過,但是要注意 return 時要free。

改為gif.cxx出錯!!
gif.cxx 裡面只有一個function : gif2xpm,因為error message的內容和上一個有一點類似,所以猜是不是local array size too large,果然找到-- 有兩個4096 的array,改成100後OK。

fluid 都build過了,link時出現"cannot find -ljpeg". 猜測是沒有jpeg library,在viewml的ftp裏好像有看到...jpegsrc.v6b.tar.gz,google一下發現這是有名的jpeg-6b 版本library。
有關cross-compile的也只有... ./configure ,修改compile to sh8-linux-gcc (是sh8的說明)。
解開source 後,裡面有install.doc,

...好像uClibc也有port libjpeg... not sure-- 結果沒有
將libjpeg cross build好 - ref http://checko.blogspot.com/2006/02/cross-compile-libjpeg.html
繼續build flnx...

compile 都過了,剩下link error : 找不到rint( ) - 屬於libm。
雖然uClibc中有libm(否則link會complain: 找不到libm),但是卻找不到rint( ),
自己寫一個測試程式用cross-compile build試試,結果真的找不到。
到lib,用
$ arm-elf-ar t libm
列出libm中所有module,沒有s_rint.o <-這是rint()所在module。
所以查一下uClibc的Makefile為何沒有把s_rint( )納入...
在uClibc-0.9.26/libm/Makefile中看到 因為定義 DO_C99_MATH沒定義,所以沒將s_rint.c加入source list。
所以手動將s_rint.c加入source list中,重新build uClibc (因為make 下有uClibc.mk,所以打 make uclibc 就可以只build uclibc)
完成後再用" arm-elf-ar t libm" 看,s_rint.o 已經在libm中。

回到flnx, make --- fluid 已經OK,
出現test folder 的error : 一樣是 " keyboard_ui.cxx:559: internal error--unrecognizable insn: "

看了一下,大概是button太多了,所以刪掉所有的button.
build OK!!
應該可以測試一下...
在target上.... 不會跑 : bad magic/rec,
這個是沒有作elf2flt的原因,
修改 Makefile,在 linker, loader rule加上 :
-Wl,-elf2flt="-s32768"
.rebuild,注意exe file要chmod a+x 才能執行。

1 則留言:

小饅 提到...

您好,突然發現您的網誌有提及collect2: ld returned 1 exit status相關的問題。
因為,有個問題想請教您。
就是,我在使用一個叫"Glomosim" 的模擬器,是架在debian機器上。
我在dsr.pc檔案中寫入
void RoutingDsrInitStats(GlomoNode *node)
pthread_t thread1;
struct arg *arg1;

arg1 = (struct arg*)malloc(sizeof(struct arg));
arg1->node = node->nodeAddr;
arg1->destAddr = ANY_DEST ;

pthread_create( &thread1, NULL, RoutingDsrInitiateRREQ, (void*) arg1);

另外,在dsr.h檔案中寫入。
struct arg{
NODE_ADDR node;
NODE_ADDR destAddr;
};

當我編譯它時
/home/public/glomosim/main >make clean
/home/public/glomosim/main >make
它出現一些錯誤訊息
../network/dsr.o: In function `RoutingDsrInitStats':
../network/dsr.pc:1296: undefined reference to `pthread_create'
collect2: ld returned 1 exit status
Failed linking '../bin/glomosim'

我試著鍵入
/home/public/glomosim/main >make -pthread

但它仍然無法運作。
可以請教先進是否能指教我是否有任何不對的地方呢?
謝謝您,非常感謝。

網誌存檔