SimpleAPP
Volume Number: 10
Issue Number: 4
Column Tag: Demonstration
Building The SimpleAPP Demonstration Application
By Richard Clark
Note: Source code files accompanying article are located on MacTech CD-ROM orsource code disks.
Even though a program written for a Power Macintosh can use the same source
code as a 68K Macintosh, the build process is different. Power Macintosh development
uses a new set of compilers and linkers, and introduces the first fundamentally new
Macintosh development system in several years - Metrowerks’ “Code Warrior.”
Not only are the tools different, but “native” Power Macintosh executables use a
different format than 68K executables. “Native” application code is stored in the data
fork of a file, and requires a ‘cfrg’ resource to notify the system that PowerPC code is
present. The ‘cfrg’ resource describes several major things about the fragment or
fragments in the current file:
• Code type (only PowerPC is supported at present)
• Whether this is a stand-alone fragment, or an overpatch to another fragment
• Version information for this fragment
• Is this a library or an application? (There’s also a value for “is a drop-in”, but
the system only looks for ‘cfrg’ resources in applications and shared libraries.
The third value is supplied for applications which include cfrg resources in
their extensions and parse these resources directly. The “ModApp” sample
included with both the MetroWerks and Apple development environments includes
a cfrg parser.)
• Is this on disk, or in memory? (An additional value, “on disk segmented” is
reserved for future use.)
• If this is on disk, what is the offset to the start of the container? This allows
applications to reserve the first part of the data fork for application-specific
information (though Apple is discouraging developers from writing to the data
fork of a running application.) Also, what is the length of the container.
These two fields serve another purpose besides allowing an application to store
information in the data fork - the data fork may contain multiple containers, and the
associated ‘cfrg’ resource may have an entry for each container.
• The name of this fragment. This is e specially important for shared libraries as it
allows the name of a shared library to be independent from the name of its file. If
the user renames a shared library, nothing will break. This also supports
packing multiple fragments into the same file as described above.
• If this is an application, the stack size (or 0 for the default.) Also, the
“appSubFolderID” field can be used if an application maintains a folder full of
shared libraries. The application can include an ‘alis’ folder alias resource in its
resource fork, and place the ID number of that resource into the cfrg.
This resource has to be added as part of the build process.
Building with Code Warrior
SimpleApp is easy to build with code warrior, though you have to set the
appropriate ‘cfrg’ and ‘SIZE’ resource values in the Preferences Dialog. Code Warrior
accepts only a subset of the ‘cfrg’ information at present (whether this is an
application or a Shared Library, the fragment’s name, and the default stack size), but
these are adequate for our purposes.
Building the SimpleApp code resources is a bit more interesting. You have to
specify that you are building a stand-alone module and set the file’s type and creator.
(This type and creator indicates to SimpleApp that this is disk-based code.)
The other important setting specifies the code’s main entry point, initialization,
and termination routines. In an application, these routines (typically called __start,
__initialize, and __terminate) are supplied by the runtime library. Since our code
resource has its own special routines, those names must be supplied to the “Linker”
part of the Preferences Dialog.
If you’re building disk-based code, that’s all you have to do. If you want to create
resource-based code, SimpleApp comes with an auxiliary application (DataToRes)
which will take a SimpleApp ‘DPEF’ file (with code in the data fork) and turn it into a
‘RPEF’ file with code in a ‘RPEF’ resource.
Building with MPW
SimpleApp also comes with a MPW makefile. Building the application and the
external code is a simple matter of compiling and linking, with one complication. The
compiler and linker emit code in the XCOFF (Extended Common Object File Format)
used by IBM, but the Power Macintosh prefers PEF. The Macintosh on RISC SDK
supplies a “MakePEF” tool to convert XCOFF to PEF. When you run this tool, you must
supply not only the file to be converted, but also a set of “library name mapping”
rules that remove the “.xcoff” extension from the shared library names:
/* 1 */
SimpleApp SimpleApp.xcoff
MakePEF SimpleApp.xcoff -o {targ} ∂
-l InterfaceLib.xcoff=InterfaceLib
Another option to MakePEF lists the Main, Initialization, and Termination
routines. (If the “main” routine was specified to the linker, it doesn’t have to be
supplied to MakePEF.)
/* 2 */
'PICT Viewer' PICTViewer.xcoff
MakePEF {deps} -o {targ} ∂
-i OurInitRoutine -t OurTerminationRoutine ∂
-l InterfaceLib.xcoff=InterfaceLib
The PowerPC linker performs dead code stripping, so you have to tell the linker
to retain the Initialization and Termination routines. You can do this with the “-dead
off” option, or by exporting the Initialization and Termination routines:
/* 3 */
PICTViewer.xcoff PICTViewer.c.o {XCOFFLibs}
PPCLink {deps} -o {targ} -main OurMainRoutine -sym {SYM} ∂
-export OurInitRoutine,OurTerminationRoutine
Finally, just as Code Warrior creates code in the data fork, so does MakePEF. This
could create a problem if you wanted to create resource-based code, but MPW users
can use a “Rez” script to read a PEF file into a resource:
/* 4 */
// File: Chaos.r
//
// This file includes the resources from a resource file
// (Unlike SimpleApp, an external don't need a 'cfrg' or
// 'SIZE' resource)
read 'RPEF' (128) "Chaos.PEF";