如何用Linux开发Palm程序
发表于:2007-07-04来源:作者:点击数:
标签:
Palm 是么是 Palm 大家一定知道.现在越来越多的人投入到 Palm 程序开发的行列中来.今天,就让我们自己也来体会一下如和在 Linux 上开发 Palm 的程序吧. 为什么是 Linux 原因很简单,因为 Linux 是免费的.因为 Linux 下的很多工具也都是免费的. 同时, Linux 本
Palm
是么是 Palm 大家一定知道.现在越来越多的人投入到 Palm 程序开发的行列中来.今天,就让我们自己也来体会一下如和在 Linux 上开发 Palm 的程序吧.
为什么是 Linux
原因很简单,因为 Linux 是免费的.因为 Linux 下的很多工具也都是免费的. 同时, Linux 本身就是一个最好的程序开发平台.
在 Linux 中写 Palm 程序,除了需要一个可以正常工作的 Linux 环境以外,我们还需要以下的东西:
·1. 我们需要 Palm OS 的 SDK 来开发 Palm 的程序. Palm 的 SDK 可以在 Palm 的网站中免费下载: http://www.palmos.com/dev/
·2. Palm Emulator - Palm 的仿真器,用来仿真 Palm 执行我们 写出的 Palm 程序. Palm Emulator 也可以子爱 Palm 的网 站中免费下载: http://www.palmos.com/dev/
·3. RPC-Tools 如果想在 Linux 中开发 Palm 的程序. 就需要用到 RPC-Tools 了. RPC-Tools 实际上是通过对 the GNU Compiler Collection, Assembler, linker, 跟 symbolic de
bugger 做 一些必要的修改,好让我们可以在 Linux 上面用 C/C++ 来开发 Palm 的程序. RPC-Tools 可以在 http://prc-tools.sourceforge.net/ 中免费下载.
·4. gcc-2.95.3 我们需要打造出一个 cross compiler, 按照 RPC-Tools 的建议,这里我们选择了下载 gcc-2.95.3: http://www.gnu.org/software/gcc/gcc-2.95/
·5. GDB - 用来建立 cross debuger (除错), 同样的,按照 RPC-Tools 中的建议,我们选择 gdb-5.0 : ftp://sources.redhat.com/pub/gdb/old-releases/gdb-5.0.tar.bz2
·6. Binutils - 我们所需要的一些工具,包含了: ld, as, ar, nm, objcopy, objdump, ranlib, size, strings, strip, c++filt, addr2line 和 nlmconv 这里我们选择 binutils-2.9.1 ftp://ftp.gnu.org/gnu/binutils/binutils-2.9.1.tar.gz
·7. make-3.77 - 我们选择 make-3.77 ftp://ftp.gnu.org/pub/gnu/make/make-3.77.tar.gz
·8. PilRC - PilRC 是 Palm 的 resource compiler. 也就是说把 m68k 的可执行程序代码编译成 palm 的 .prc 文件. PilRC 可以 在下面的连结中免费取得: http://www.ardiri.com/index.php?redir=palm&cat=pi
lrc&subcat=download
这里用于
测试的系统是 RedHat 7.3
安装 Palm SDK
首先 tar vxfz sdk50.tar.gz 这时侯会出现一个 palmos-sdk 的 rpm 文件. 用 rpm -ivh 给安装上去就好. SDK 会被安装在 /opt/palmdev/sdk-5 中. 我们现在需要做一个 symbolic link, 把 sdk-5 link 到 sdk 上面去.
cd /opt/palmdev
ln -s sdk-5 sdk
现在我们已经安装好了 Palm SDK 了. 接下来就该安装开发所需要的环境了.
安装 PRC-Tools 以及 cross compile 所需要的工具
收先我们建立一个新的目录
mkdir /tmp/prc
然后把 prc-tools-2.0.92.tar.gz binutils-2.9.1.tar.bz2 gcc-2.95.3.tar.bz2 gdb-5.0.tar.bz2 make-3.77.tar.gz 都 copy 过去.
cp prc-tools-2.0.92.tar.gz /tmp/prc
cp binutils-2.9.1.tar.bz2 /tmp/prc
cp gcc-2.95.3.tar.bz2 /tmp/prc
cp gdb-5.0.tar.bz2 /tmp/prc
cp make-3.77.tar.gz /tmp/prc
然后 cd 到 /tmp/prc 目录下. 执行解压缩的动作:
收先把所有 .gz 的解压缩
for i in *.gz; do tar vxfz $i; done
接下来是一些用 bzip2 压缩的 .bz2 文件
for i in *.bz2; do tar vxfj $i; done
prc-tools 为以上的这些程序,有做一些改动,所以我们需要把上面的程序代码 patch 一下:
cat prc-tools-2.0.92/*.palmos.diff | patch -p0
现在我们进入 prc-tools-2.0.92 的目录,首先我们需要做的是把 binutils-2.91, gdb-5.0, gcc-2.95.3 跟 make-3.77 这几个目录用 symbolic link 分别 link 到 prc-tools-2.0.92 这个目录中.
cd prc-tools-2.0.92
ln -s ../binutils-2.9.1 binutils
ln -s ../gcc-2.95.3 gcc
ln -s ../gdb-5.0 gdb
ln -s ../make-3.77 make
为了保持我们程序源码目录的整洁与完整性,所以我们在编译的时侯, 单另建立一个目录 build:
cd ..
mkdir build
现在我们只要跑 prc-tools-2.0.92 中的那个 configure 就好了
../prc-tools-2.0.92/configure --target=m68k-palmos --enable-languages=c,c++
这里面我们分别传给 configure 两个参数, 一个是告诉我们的 target 为 m68k-palmos 另一个是 enable C/C++ 这两种语言. prc-tools 中的这只 configure script 会帮我们把 binutils, gcc, gdb, make 这四个程序所需要的 Makefile 也同时帮我们建立好. 现在在我们的 build 目录中,就有了以下这些东西:
binutils config.log crt gcc include libm Makefile
config.cache config.status doc gdb libc make tools
现在我们只要用 make all-install 就好了. (如果您不是用 root 帐号, 不要忘记 su 成 root)
make all-install
因为需要 compile 的时间满长的.如果您的系统中有超过一颗的 CPU 记得在 make 后面加上 -j number 的选项,其中 number 的 value 就是您 CPU 的数量加一. 例如您有两颗 CPU 就可以用 make -j3 all-install, 如果有三颗就用 make -j4 all-install. 如果您的机器又很大的 RAM (好几 GB)然后也有个十几颗的 CPU, 那么也可以用 make -j all-install 来编译.如果 -j 后面没有跟任何数字,那么 make 就不会对 jobs 做任何的限制. 详细的情况请自行 man make 看一下.
在我们编译的过程中,还有己个小小的问题需要解决一下(至少这个问题存在于 RedHat 版本的系统中)首先遇到的问题是, 在 gdb 的编译中有一个错误:
In file included from /usr/include/curses.h:111,
from ../../../prc-tools-2.0.92/gdb/gdb/utils.c:28:
/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/s
tdbool.h:39: conflicting types for `false'
../bfd/bfd.h:101: previous declaration of `false'
/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdbool.h:41: conflicting types for `true'
../bfd/bfd.h:101: previous declaration of `true'
我们这里看到在 gdb/gdb.utils.c 中的第 28 行有 include curses.h 这个文件.而 curses.h 中的第 111 行又 include 了 stdbool.h, stdbool.h 中定义了 false, 而 bfd/bfd.h 中同时也定义了 false, 这样两个 false 就冲突了.所以造成编译失败.这里用最简单也是最偷懒的作法,打开
/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdbool.h
把:
typedef enum
{
false = 0,
true = 1
} _Bool;
这己行给暂时 mark 起来
/*
typedef enum
{
false = 0,
true = 1
} _Bool;
*/
然后再重新
make all-install
现在我们会遇到第二个问题:
gcc -DEXEC_PREFIX=\"/usr/local\" -I. -I../../prc-tools-2.0.92/tools/../binutils/include -I../binutils/bfd -g -O2 -o def.yy.o -c def.yy.c
../../prc-tools-2.0.92/tools/def.l:35:19: utils.h: 没有此一档案或目录
../../prc-tools-2.0.92/tools/def.l:37:23: pfdheader.h: 没有此一档案或目录
找不到 utils.h 跟 pfdheader.h 这个很容易解决,把 prc-tools-2.0.92/tools 下面这两个文件复制到 build/tools 下面就好了,这里我们把全部的东西都给复制过去, 不然等会还会继续说找不到 utils.h 的文件
cp ../prc-tools-2.0.92/tools/* tools/
然后继续 make all-install
接下来又会有一个错误中断编译:
gcc -DEXEC_PREFIX=\"/usr/local\" -I. -I../../prc-tools-2.0.92/tools/../binutils/include -I../binutils/bfd -g -O2 -o def.yy.o -c def.yy.c
../../prc-tools-2.0.92/tools/def.l:39: conflicting types for `dup'
/usr/include/unistd.h:441: previous declaration of `dup'
这里是说,在 def.l 中第 39 行定义的 dup 已经在 /usr/include/unistd.h 中的第 441 行定义过了.所以产生了冲突.
还是用最简单的方法来解决:
首先要做的是
vim tools/def.yy.c
把第十二行的 #include 改成 #include "unistd.h" 这样编译 def.yy.c 的时侯,就不会去找 /usr/include/unistd.h 这个文件,而是找 tools 下面的 unistd.h
接下来
cp /usr/include/unistd.h tools/
把 unistd.h 复制到 tools 下面,再把 unistd.h 改动一下
最后
vim tools/unistd.h
把第 441 行的 extern int dup (int __fd) __THROW;
给 mark 起来
// extern int dup (int __fd) __THROW;
存盘后重新 make all-install 就再没有问题了. 这时侯,在您的 /usr/local/bin 下面就已经有了我们做 cross compile 所需要的全部工具了.
PS. 不要忘记把了把 /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdbool.h 改回原貌喔.
安装 pilrc
现在到了最后一步,安装 pilrc
首先把 pilrc-2.9.tar.gz 复制到 /tmp 中
cp pilrc-2.9.tar.gz /tmp
然后解压缩:
tar vxfz pilrc-2.9.tar.gz
pilrc-2.9 这个版本,有一点小问题. 如果直接编译,那么 pilrcui ( resource viewr )则没有办法正常工作.遗憾的是, pilrc 的官方网站并没有放出 patch 文件.所以就需要自己动手改一下了.这里我们需要改两个文件. 一个是 main.c 另外一个是 pilrc.c
收先打开 main.c 在倒数第三行会看到
ParseFile(szInputFile, szOutputPath, szResFile, szIncFile, fontType);
把这行删除不要,改成下面的这行, 我们要用 FreeRcpfile 来叫 ParseFile
FreeRcpfile(ParseFile(szInputFile, szOutputPath, szResFile, szIncFile, fontType));
然后存盘离开.再打开 pilrc.c 把倒数第五行的
FreeRcpfile(prcpfile);
给 mark 起来
//FreeRcpfile(prcpfile);
这行我们不要.
现在就可以执行 ./configure 程序了, 然后执行
make
make install
现在我们就已经在 linux 下安装好了一个 palm 的开发环境了.
最后的测试
现在为了测试我们的 palm 开发环境是否一切都真的工作了, 就让我们写一个最简单的 hello word 来测试一下吧我从计算机中找了个 hello 的 palm 程序出来.忘记是哪里的一个范例了,借来用用.
hello.rpc:
#include "hello.h"
VERSION ID 1 "1.00"
MENU ID MainMenu
BEGIN
PULLDOWN "Help"
BEGIN
MENUITEM "About..." ID HelpMenuAbout
END
END
FORM HelloForm AT (0 0 160 160)
MENUID MainMenu
USABLE
BEGIN
LABEL "Hello, world!" AUTOID AT (CENTER 50)
END
ALERT ID AboutAlert
BEGIN
TITLE "About..."
MESSAGE "Hello, world! demo app\nVersion 1.00\n\nCopyright \251 2003\nStudy-Area.\n"
BUTTONS "OK"
END
hello.h:
#define MainMenu 1000
#define HelpMenuAbout 1010
#define HelloForm 1100
#define AboutAlert 2000
hello.c:
#include
#include
#include "hello.h"
static FormPtr gpForm;
static Err StartApplication()
{
FrmGotoForm(HelloForm);
return 0;
}
static void StopApplication()
{
FrmCloseAllForms();
}
Boolean HelloFormEventHandler(EventPtr event)
{
Boolean handled = false;
switch (event->eType) {
case frmOpenEvent: {
gpForm = FrmGetActiveForm();
FrmDrawForm(gpForm);
handled = true;
break;
}
case frmCloseEvent:
FrmEraseForm(gpForm);
FrmDeleteForm(gpForm);
gpForm = 0;
handled = true;
break;
default:
break;
}
return handled;
}
static Boolean ApplicationEventHandler(EventPtr event)
{
Boolean handled = false;
switch (event->eType) {
case frmLoadEvent: {
FormPtr pForm = FrmInitForm(event->data.frmLoad.formID);
FrmSetActiveForm(pForm);
FrmSetEventHandler(pForm, HelloFormEventHandler);
handled = true;
break;
}
case menuEvent:
switch (event->data.menu.itemID) {
case HelpMenuAbout:
FrmAlert(AboutAlert);
break;
}
handled = true;
break;
default:
break;
}
return handled;
}
static void EventLoop()
{
EventType event;
UInt16 error;
do {
EvtGetEvent(&event, evtWaitForever);
if (!SysHandleEvent(&event)) {
if (!MenuHandleEvent(0, &event, &error)) {
if (!ApplicationEventHandler(&event)) {
FrmDispatchEvent(&event);
}
}
}
}
while (event.eType != appStopEvent);
}
UInt32 PilotMain(UInt16 launchCode, MemPtr cmdPBP, UInt16 launchFlags)
{
Err err = 0;
if (launchCode == sysAppLaunchCmdNormalLaunch) {
if ((err = StartApplication()) == 0) {
EventLoop();
StopApplication();
}
}
return err;
}
最后写一个 Makefile:
PROGRAM=hello
CC=m68k-palmos-gcc
PILRC=pilrc
OBJRES=m68k-palmos-obj-res
ICONTEXT='hello'
BUILDPRC=build-prc
APID=TEST
CFLAGS=-palmos -Wall -g
LFLAGS=-g
SOURCES=hello.c
OBJS=hello.o
PRC=$(PROGRAM).prc
RESOURCES=$(PROGRAM).rcp
all: $(PRC)
$(PRC): $(PROGRAM) bin.res
$(BUILDPRC) $(PRC) $(ICONTEXT) $(APID) *.bin *.grc
$(PROGRAM): $(OBJS)
$(CC) -o $(PROGRAM) $(OBJS) $(LFLAGS)
$(OBJRES) $(PROGRAM)
bin.res: $(RESOURCES) hello.h icon.bmp
$(PILRC) $(RESOURCES)
touch bin.res
ctags:
ctags $(SOURCES)
clean:
rm -f *.bak *.bin *.grc *.o bin.res tags $(PRC) $(PROGRAM)
hello.o: hello.c hello.h
然后我们打 make 最后看到成功了:
m68k-palmos-gcc -palmos -Wall -g -c -o hello.o hello.c
m68k-palmos-gcc -o hello hello.o -g
m68k-palmos-obj-res hello
pilrc hello.rcp
PilRC v2.9 patch release 2
Copyright 1997-1999 Wes Cherry (wesc@ricochet.net)
Copyright 2000-2001 Aaron Ardiri (aaron@ardiri.com)
Generating 68K resources from 'hello.rcp'.
Writing tver0001.bin
5 bytes
Writing MBAR03e8.bin
86 bytes
Writing tFRM044c.bin
102 bytes
Writing Talt07d0.bin
90 bytes
touch bin.res
build-prc hello.prc 'hello' TEST *.bin *.grc
好啦,现在一切都 ok 了.如果您也同样的 make 成功.那么恭喜您,您的 linux 中已经有了一个可以写 palm 程序的环境了.
原文转自:http://www.ltesting.net