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 or source 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? (Theres 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 especially 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 fragments 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 files type and creator. (This type and creator indicates to SimpleApp that this is disk-based code.)
The other important setting specifies the codes 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 youre building disk-based code, thats 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 doesnt 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";