如何用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 debugger 做 一些必要的修改,好让我们可以在 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=pilrc&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/stdbool.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