1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
|
GLib shared libraries for the Pilot
This document describes how to use gcc to create and use GLib shared
libraries on the Pilot. It is divided into six sections:
What is a GLib shared library?
Upgrading gcc
Creating GLib shared libraries
Creating applications that use GLib shared libraries
Using applications that use GLib shared libraries
Conclusions
Comments are welcome; see the Conclusions section.
What is a GLib shared library?
Shared libraries enable many applications to share common code, without
having to have a copy of the code in each application's code resource. For
example, there can be one copy of encryption routines, or a version of the
standard C library, and many applications can be using it.
Shared libraries can also help you get around the 32K code size limit; you
can break up your code into a main portion (of at most 32K), and a number
of libraries (each of at most 32K).
GLib (pronounced ``gee-lib'') shared libraries are a way to implement
shared libraries on the Pilot that differs from the ``standard'' (SysLib)
mechanism for the Palm Pilot.
Some features of GLib:
GLib libraries work on the old Pilots as well as the Palm Pilots.
It is extremely easy to convert a static library into a GLib shared
library, as well as to link an application to the GLib library.
GLib libraries can have static and global data (though they cannot, at
this time, export global data to the calling application).
The common case is fast: no systraps are done to call a GLib shared
library function after the library has been loaded, when globals are
available.
The uncommon case is correct: GLib shared libraries work even
when the application globals have not been loaded.
GLib libraries are implemented as resource databases, with a database type
of GLib, and a library-specific creator ID. The GLib library will usually
contain three resources: GLib 0 (the code), data 0 (the library globals), and
rloc 0 (the data relocation table). By contrast, an application if a resource
database with (usually) five resources: code 0, code 1, data 0, rloc 0, and
pref 0. The GLib 0 resource in a shared library corresponds exactly to the
code 1 resource in an application.
Upgrading gcc
Before going any further, you need to make sure that you have a recent
version of gcc. m68k-palmos-coff-gcc -v should report its version number
to be (at time of writing) 2.7.2.2-krab-051897.
If you have version 2.7.2.2-krab-030597, you can upgrade to
2.7.2.2-krab-051897 by replacing the following five files and recompiling:
c-common.c (get new version)
config/m68k/m68k.c (get new version)
config/m68k/m68kpalmos.h (get new version)
config/m68k/palmos_crt0.c (get new version) (this is not the
version that comes with 2.7.2.2-krab-051897; it is the same as the
version in the instructions below)
version.c (get new version)
After you have gcc version 2.7.2.2-krab-051897 successfully installed,
you will need to upgrade some of its support files. (Note to Kresten: it would
be good if these changes were merged into the next release.) This upgrade
adds some new features (such as support for GLib shared libraries) as well
as fixing some bugs. You may want to do this even if you don't plan to use
shared libraries.
Find the directory that contains the specs file for the compiler (you can find
this by running m68k-palmos-coff-gcc -v). This directory should contain
crt0.o, pilot.ld, specs, and some other files.
Replace the following two files in that directory:
specs (get new version)
pilot.ld (get new version)
You will also need to create a new version of crt0.o, and you will need to
install the new files scrt0.o, libGLib.a, and libgGLib.a. For your
convenience, I have precompiled versions available of all four of these files:
crt0.o, scrt0.o, libGLib.a, libgGLib.a. These should all go in the same
directory as specs.
If you want to create these files yourself, follow these instructions:
Download the following files into an empty directory:
GLib.h, GLib.c, palmos_crt0.c, palmos_crt0_shared.c
Create crt0.o:
m68k-palmos-coff-gcc -O5 -c palmos_crt0.c -o crt0.o
Create scrt0.o:
m68k-palmos-coff-gcc -O5 -c palmos_crt0_shared.c -o
scrt0.o
Create libGLib.a:
m68k-palmos-coff-gcc -O5 -c GLib.c -o GLib.o
m68k-palmos-coff-ar rcs libGLib.a GLib.o
Create libgGLib.a:
m68k-palmos-coff-gcc -O5 -g -c GLib.c -o gGLib.o
m68k-palmos-coff-ar rcs libgGLib.a gGLib.o
Install crt0.o, scrt0.o, libGLib.a, and libgGLib.a in the same directory
as specs.
Your copy of gcc should now be ready to create GLib shared libraries and
apps that link to them.
Creating GLib shared libraries
Turning a static library into a GLib shared library is quite simple. First, make
sure your static library was compiled with the upgraded version of gcc
(above). Let's call this static library libfoo.a. We are going to create
FooLib.prc (the GLib shared library), as well as libfoo_s.a, a ``stub''
library that will be linked to the application.
You need to generate a list of the functions exported by your library. One
way to do this is the following:
m68k-palmos-coff-nm libfoo.a | grep ' T ' | cut -c12- | sort -u
Save the output of the above command in the file foo.exp. This will contain
the list of exported functions, one per line. Note: the order of the functions
listed in foo.exp is important if you create a new version of the GLib library.
Existing functions should not change their positions in the list, and new
functions should be added to the end.
Get the stubgen perl script (download), and run the following:
stubgen "Foo Library" FooL foostub.c FooLib.S < foo.exp
Here, "Foo Library" is the (human-readable) name for your library. FooL
is the four-character creator ID (you pick this yourself, but it's supposed to
be globally unique). foostub.c and FooLib.S are files that will be generated
by stubgen.
Now create FooLib.prc as follows:
m68k-palmos-coff-gcc -shared -o FooLib FooLib.S -lfoo
This creates FooLib by linking FooLib.S to libfoo.a using the
-shared flag. You may need to specify -Ldir before -lfoo if
libfoo.a is not in your library path.
m68k-palmos-coff-obj-res -rloc FooLib
This extracts the code 0, code 1, data 0, rloc 0, and pref 0 resources
from FooLib. The -rloc flag will probably become unnecessary in
future versions of obj-res.
rm code0000.FooLib.grc pref0000.FooLib.grc
mv code0001.FooLib.grc GLib0000.FooLib.grc
GLib libraries don't need the code 0 and pref 0 resources, and the
code 1 resource is renamed to GLib 0.
build-prc FooLib.prc "Foo Library" FooL GLib0000.FooLib.grc
data0000.FooLib.grc rloc0000.FooLib.grc
This command creates the FooLib.prc file by combining the GLib 0,
data 0, and rloc 0 resources. The library name ("Foo Library") and
the creator ID (FooL) need to be the same as were specified to the
stubgen command.
appl2GLib FooLib.prc
The current version of build-prc has no way to specify that the
resulting prc file is anything other than an application (type appl), so
we need to run this to change the type from appl to GLib. Download
appl2GLib.c and compile it yourself. (Remember to use your
machine's native compiler, not the PalmOS cross-compiler.)
Finally, create the stub library libfoo_s.a from foostub.c:
m68k-palmos-coff-gcc -O5 -c foostub.c
m68k-palmos-coff-ar rcs libfoo_s.a foostub.o
That's it. FooLib.prc is the library users must install in order to use
programs that are linked to libfoo_s.a. Distribute FooLib.prc to end users
and distribute libfoo_s.a and the header files for libfoo.a to developers
of applications that could use the library.
Creating applications that use GLib shared libraries
Now that you have a GLib shared library and a stub library, how do you
change your application (that was previously linked to libfoo.a) to use the
shared library instead of the static one?
It's surprisingly simple; the application need not change at all. Just change
the link line in your Makefile, so that instead of linking with -lfoo, you now
link with -lfoo_s.
Note the current restriction on GLib libraries: library globals are not
exported to the application. If your application needs to read or write
variables in the library's global space, you should consider modifying the
library to have access functions for them.
Using applications that use GLib shared libraries
To use an application that requires a GLib shared library, just make sure
both the application and the library are installed on your Pilot before running
the application. GLib shared libraries are just prc files; they are installed in
exactly the same way as applications (HotSync or pilot-xfer, for
example).
If a GLib shared library is not installed, an application that uses it will still run
properly, until it tries to call a function provided by the library (at which point
you will get a Fatal Error informing you which library you're missing).
Conclusions
Success and failure reports, comments, and questions are welcome.
Depending on the content, appropriate fora are the pilot.programmer and
pilot.programmer.gcc newsgroups hosted on news.massena.com, and
the pilot-unix mailing list at <pilot-unix@lists.best.com>. If necessary,
I can be reached directly at the address below (be warned that my email
queue sometimes gets quite backlogged).
Back to the ISAAC Group's Pilot page
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
Ian Goldberg, iang@cs.berkeley.edu
|