October 2002

A tutorial for Palm Programmers who want to use both OnBoardC and PRC-Tools

(Supplemental to, and mostly in the style of the excellent David Beers tutorial for doing the same between
CodeWarrior and OnBoardC, located here .


Overview:

This tutorial will focus on the steps from the viewpoint of a Mac OS X user who has a relatively "mature" OBC project, some Linux experience, and very little PRC-Tools experience. As such, I will only brush topics like how to secure copy over a network, and put other topics like the warning levels of gcc under a microscope. I built gcc on a Linux box, and these steps detail the process using both machines for various parts of the task.

There are obviously a million other ways to do this. The following seemed the most natural to me at the time, and has worked well so far. Also, as you will see, I cheated a bit and smuggled a Wintel machine in to convert the resources to an rcp script readable by PilRC.

The only victim so far has been Mandala Kaleidoscope, which I originally developed in HotPaw Basic and then ported to OnBoardC. All the development is now done with OBC on a Palm III. My newest release build was done with the gcc toolchain. My Mac runs Jaguar. The Linux box in question runs Slackware 8.1. I used the Palm SDK 4.0 with PRC-Tools 2.2 and PilRC v2.9.

I mention the versions used above because you may run into certain situations if you are using different ones. In particular, PRC Tools 0.5.0 suffers from the "CALLBACK" bug. Apparently, this is fixed in PRC-Tools 2.0+, and since I have no experience with the matter I have left it out of this discussion.

(The terms "PRC-Tools", "gcc", "GCC", and "gcc toolchain" are used interchangeably in this document and are used here to mean all the components of GCC for generating prcs, as well as PilRC.) whew.

No doubt the following could all be done with Putty (or whatever your favorite terminal app is) via a Wintel machine, or completely on a Wintel machine using Cygwin with gcc. There is also probably a way to do all this on Linux. Of course, none of these options would look as nice. ;)

This is your Linux box on Jaguar. Any questions?


Carsick mode: A transparent terminal shell over the iTunes visualizer.

General notes about project portability between OnBoardC and PRC-Tools.

Data types: As David notes, even if you've been really responsible with your variable declarations in OBC, you'll be in for a few headaches. Your first task should be replacing all those Word, Int, int, bool, and such data types with the ones that Palm introduced in OS 3.5, such as UInt32, Int16, etc.

Also at issue is the lack of large portions of the Palm OS headers in OnBoardC. David does a way better job of explaining this than I would be able to, so I would encourage you to read his document.

I would add that the biggest pain in the process is making the rcp file and keeping it current.

Here's what you need to compile in gcc:


The software tools you need are:

Mac OS X:
  • PorDiBle: a GPL'd DOC to text and text to DOC translator.
    http://pordible.ethelthefrog.net/


    Wintel:
  • Prc2rcp: makes an .rcp script from a prc.
    http://de.mobile.yahoo.com/010301/3/kpc.html


    OnBoardC to PRC-Tools

    1. Build your project in OnBoardC so you can use prc2rcp on the resulting prc.
    2. Use prc2rcp on the prc file to extract a rcp script for use with PilRC. I used a sneakernet to move these files around.
    3. Sync with your Mac, and find your DOC source files in your backup folder. Check the file dates and times on these to make sure you have the newest versions. Copy them into a new folder, and convert them to text files using PorDiBle (this is drag and drop.) If you don't have PorDiBle set to delete the source files after conversion, remove the DOC files. Remove any ".txt" file extensions from the filenames of the translated files.
    4. Tar the folder with your favorite tar-building utility. Using the Terminal in OS X, scp the tarball into your home area on your Linux box. Ssh into the box and untar.
    5. Find a really nice, but basic as possible Makefile you can twist to your needs. I have included the one I use at the bottom of this document.
    6. Create a build folder and copy your source files, rcp file, Makefile and any bmp files into it. Cd into that folder. If you're using a copy of the Makefile that I included below, create a directory in the folder named "Pilrc". Check to make sure the name of your c file and the name of your rcp file match. (Case sensitive. For example: filename.c filename.rcp)
    7. Open your main c file with your favorite text editor. I use my own separate header file for systraps and parts of Palm's headers that didn't make it into OnBoardHeader.h. If you #include one of those, or put any items like these in your c file, you should comment those lines out. The point is, you're about to use Palm's headers and don't want duplicate definitions.
    8. At the top of the file, put in a line that reads:
       #include <PalmOS.h> 
    9. Save your changes and exit.
    10. Open the Makefile and change it to be specific to your project. Save and Exit.
    11. Type "make".
    12. Cross your fingers and hit the Enter key.

    PRC-Tools to OnBoardC

    1. Go to your project folder and "make clean". This uses instructions in the Makefile to remove any intermediary files the toolchain builds during the make.
    2. Tar your project folder. Scp it back to your Mac. Untar.
    3. Use PorDiBle on the source files (Obviously, exclude the PilRC folder)
    4. Open the Palm Installer. Drag your translated sources and prc file into it.
    5. Sync.
    6. Using RsrcEdit on your Palm, copy any changes you made to your resources from the newly compiled application into your existing .rsrc file (or use the method David details.)
    7. Do the opposite of steps 7 and 8, above.

    Using #ifdef and #ifndef to Fix Steps 7 & 8 Permanently.

    As mentioned in steps 7 and 8, in the OBC to gcc section above, I use a separate header file to add new SYSTRAPS and defines that the OnBoardHeader.h file lacks. I have no idea why I do this in a seperate file. Either way, if you have items in your .c file which are not needed when compiling with gcc, add the following at the top:
     // Preprocessor: Use the following if not in gcc
     #ifndef __GNUC__
     #include "myHeader.h"
     // anything else to add?
     #endif
    
    In all cases, follow that up with:
      // Preprocessor: Use PalmOS.h only in gcc
      #ifdef __GNUC__
      #include <PalmOS.h>
      #endif
    
    You'll notice that I didn't use #ifdef __ONBOARDC__ in the first entry. As of this writing, it looks like the OBC preprocessor is not self-aware. Thus the item as it is only checks to make sure it isn't in gcc. This will need modification if you wish to use CodeWarrior on the same files.

    Problems Encountered:

    I doubt I could record all the problems involved in doing this. As always, common sense will be your best guide, and as they say, "If it never works the first time, you're a programmer."

    First up, I gotta say prc2rcp is an amazing tool. I had three problems with it, tho.

    In the resulting rcp, instead of listing my application icon as an ICON, it listed it as a BITMAP. Also, although it named the resulting bitmap file "bm1000.bmp" it listed this file as "BM1000.bmp" in the script. This will work fine in Windoze but not Linux. You will need to change these in the script.

    It could very well be my fault, but prc2rcp doesn't seem to translate linefeeds in string resources. Also maybe PilRC doesn't like overly long lines? PilRC will choke on these, and complain about "Unterminated Strings." Open your rcp file, go to the line listed in the complaint, hard wrap any overly long strings with "\" and insert linefeeds where appropriate. Here is a sample. Note that "\n" = linefeed according to PilRC.

    "This is such a great program that you should" \
    " forget your dinner and send me all your cash.\n" \
    "Or feed me."
    
    Just to clarify the linefeed thing, the above will have the following results in the finished resource: 1) The first two lines will be put together. 2) A linefeed will be placed separating "Or feed me" from the line above it.

    Also, prc2rcp failed to identify the "i" info character in the Symbol font, and put a junk character there, or something. Maybe this is also something that works in Windoze but not Linux. This can be fixed by substituting with the octal value for "i" in the symbol font that PilRC expects in the script, which is \012.

    If you're like me, you probably missed a couple variable declarations when updating your project to use SDK 3.5+ data types. PRC-Tools will complain about "parse errors" and later label the variables as "undeclared."

    Both OnBoardC and gcc are pretty laid back about type agreement. For example, both will let you do something like the following:
    void Foo (Coord *heck, UInt16 dang, Coord darn) {
    if (*heck + dang > darn)
          *heck = darn - dang;
    }
    
    Obviously this kind of construction is irresponsible, but that didn't stop me! If you don't specify any warnings in gcc, then neither compiler will complain. OnBoardC will happily compile to code that seems to work in all cases. PRC-Tools will happily compile to code that probably won't.

    I don't know for sure, but I would bet there a few other gotchas like this. As such, I tested my app on POSE before installing it on my Palm.

    Tips:

    Life got a 100% easier when it really sunk in that every complaint I got from gcc included the name of the offending file and the line number. Before then I was searching my Makefile for problems that were actually in my rcp file, and vice-versa.

    You'll notice I used the -Wall flag in my makefile. Although -Wall translates to "Warnings: all" it really isn't all of them, just a collection of the ones generally recommended. Thus, this is only the "medium strength" warning level with gcc! Even with source that is reasonably clean and runs fine, the -Wall option will generate a ton of warnings. The rule of thumb with warnings is: If you know why gcc complained about it, and know it won't cause problems in the future, then it is safe to ignore. For example, with -Wall set, gcc will complain about every possible case in a switch that you don't explicitly handle. You can be pretty confident in ignoring these warnings.

    Linux is Interesting:

    I'm including this not as a complaint, or because I want anything done about it. More like I find it disturbing and funny. Since the hard drive on my Linux box was kind of small, I didn't install any of the GUI stuff. And you know what I miss the most? Scroll bars. It's weird. I would have expected something else, like maybe the ability to click and drag to select. Or say, a file system I can visualize without thinking about trees. But no. Here it is: Linux. I got jump-to-line functionality. I got a listing of what lines out of what total are being displayed, and all that. But still I miss scroll bars.

    (maybe you had to be there.)

    Compiling with PRC-Tools took 30% off the size of my app.

    Wow. Most of that came off the top of my "code 1" segment. It also made the parts I hadn't paid much attention to optimizing a lot faster. Doing this in Linux is phat, and copying files between networked machines doesn't add much trouble at all to the process.

    That's it! Thanks and good luck with your project!

    The Makefile:

    Note: This was based on a Makefile example from the excellent "Palm OS Programming Bible" by Lonnon R. Foster. The author of this page claims no copyright on its contents, and in addition recommends that you buy this book.
    # -------------------- CUT HERE ----------------------
    # $ simple makefile $
    
    ### app config
    # Change the first three values here to match your own project. 
    # As you can see it will take these and add proper filename extensions 
    # to them, so don't put "filename.c" for APP, just "filename".
    # ICONTEXT is the name which will appear below your icon
    # in the Palm launcher when your app is installed. APPID is the
    # unique ID of your app that you registered with Palm.
    
    APP	 	= filename
    ICONTEXT	= "Filename"
    APPID 		= XXXX
    RCP		= $(APP).rcp
    PRC		= $(APP).prc
    SRC		= $(APP).c
    
    ### tool definitions
    # These are specific to which version of gcc you use. If you are
    # using 0.5.0, you will need to change them
    
    CC = m68k-palmos-gcc
    PILRC = pilrc
    OBJRES = m68k-palmos-obj-res
    BUILDPRC = build-prc
    
    ### flags
    
    BINDIR = Pilrc
    
    ### build optimization level and Warnings
    # Here I have specified -O2 for optimization. This is a good
    # level for Palms as it tries to optimize speed without
    # bloating the finished app size.
    # The -Wall option is discussed thoroughly, above.
    
    CFLAGS = -Wall -O2
    
    
    all: $(PRC)
    
    $(PRC): grc.stamp bin.stamp;
    	$(BUILDPRC) $(PRC) $(ICONTEXT) $(APPID) *.grc $(BINDIR)/*.bin
    	ls -l *.prc
    
    grc.stamp: $(APP)
    	$(OBJRES) $(APP)
    	touch $@
    
    $(APP): $(SRC:.c=.o)
    	$(CC) $(CFLAGS) $^ -o $@
    
    bin.stamp: $(RCP)
    	$(PILRC) $^ $(BINDIR)
    	touch $@
    
    %.o: %.c
    	$(CC) $(CFLAGS) -c $< -o $@
    #	touch $<
    # to rebuild every time, uncomment above line
    
    depend dep:
    	$(CC) -M $(SRC) > .dependencies
    
    clean:
    	rm -rf *.o $(APP) $(BINDIR)/*.bin *.grc *.stamp *~
    
    veryclean: clean
    	rm -rf *.prc *.bak
    
    
    ### end
    # ----------------- CUT HERE --------------------