This section provides tips on maintaining parallel projects in Xcode and CodeWarrior that operate on the same code base.
Executable Format
Framework and System Headers
Using Precompiled Headers and Prefix Files
Property Lists
Code Differences
Linking
The more similar the CodeWarrior and Xcode projects are, the easier the task will be, so unless you absolutely need a Mac OS 9 product, convert your CodeWarrior project to use the Mach-O executable format (as all Xcode projects must do).
When you use Mach-O with CodeWarrior, you can choose either the Metrowerks linker or the Apple linker, and choose to use either MSL or the standard Mac OS X libraries. Again, it's simplest to have consistency between your products, so unless you're using specific features of the Metrowerks linker or MSL, it’s recommended that you use the Apple linker and Mac OS X standard libraries.
Most CodeWarrior projects are still built against Universal Interfaces. These headers have not been updated for current versions of Mac OS X, so projects that use them don't have access to all the functions and constants that are available in the latest headers.
If you convert your project to Mach-O, you'll most likely also move it to using framework-style headers. This means that your source files should include just the Carbon framework header (or any other framework headers you need), rather than the raft of individual header files traditionally used in CarbonLib or Classic development. To include the Carbon framework header, you use a statement like this:
#include <Carbon/Carbon.h> |
Note: When you include the Carbon framework header, it in turn includes a number of other framework headers.
If you haven't converted to framework-style headers (or are building for CFM in CodeWarrior, which doesn't allow you to use framework includes), you can use the Xcode SDK Support feature to get access to the headers of the current system (or a past or future version, if you wish). Just change your system access path from {Compiler}MacOS support to /Developer/SDKs/MacOSX10.2.8.sdk/Developer/Headers/CFMSupport (to get the Jaguar headers) and add an access path to /Developer/SDKs/MacOSX10.2.8.sdk/System/Library/CFMSupport (to get the Carbon CFM link libraries). Of course, you can use different SDKs depending on which OS you wish to target, and you can use weak linking as usual to run on older systems.
You can find additional information on weak linking in Technote 2064, “Ensuring Backwards Binary Compatibility—Weak Linking and Availability Macros on Mac OS X”.
See “Cross-Development” for information on using SDK support in Xcode.
Because CodeWarrior compiler and Xcode use different precompiled header mechanisms, you'll have to have separate precomps for each environment. You can manage this by using the automatic-precompilation features of both environments; Metrowerks will automatically precompile a header file that ends in .pch, and Xcode automatically precompiles any prefix file. So the recommended way to set this up is as follows. For Xcode:
Create a .pch file that #includes all the headers you want to precompile (framework, project, and utility).
Use that .pch file as the prefix file in the appropriate targets of your project by entering the name in the “Prefix Header” Language setting in the Build pane for each target.
Enable the “Precompile Prefix Header” Language setting in the Build pane for each target.
For CodeWarrior:
In the .pch file, add the following directive:
#ifdef __MWERKS_ |
#pragma precompile_target "Precomps.mch" |
#endif |
Use the filename defined in the previous step (Precomps.mch) as your prefix file in appropriate targets of your project.
Create a CodeWarrior target that contains just the .pch file; when built, this will generate the .mch file.
Make other targets depend on the target that generates the .mch file.
For related information, see “Precompiled Headers and Prefix Files.”
CodeWarrior uses a property list compiler and special property list source files (.plc files) to generate Info.plist files for packages. Xcode uses GUI settings in the target inspector window to set those values, and generates the Info.plist file automatically. If you change property list settings, you'll have to change them in both places; it's worth inserting a comment into your .plc file to remind other people that if they make changes there, they should change the Xcode project file as well.
For more information on working with property lists, see “The Information Property List and .plc Files.”
While both CodeWarrior and GCC compilers do a good job of implementing standard C and C++ features, they differ on which compiler-specific extensions are supported. You should isolate compiler-specific code using the following preprocessor directives:
Listing 1-2 Preprocessor directives for isolating compiler specific code
#ifdef __MWERKS__ |
// CodeWarrior-only code should go here |
#endif |
#ifdef __GNUC__ |
// GCC-only code should go here |
#endif |
The following are some examples of CodeWarrior-only code you should isolate. You’ll find more details on these items in “Make Code Changes for GCC Compatibility”:
Most CodeWarrior-defined #pragma directives. Though GCC ignores them, it's good discipline to remind yourself that they're compiler-specific.
Metrowerks-specific extensions to BSD functionality, such as FSp_fopen(), SIOUX, console.h, and so on.
C-style cases and functional casts in an argument list (standards-compliant but not supported in GCC).
Instantiating a struct with a member template within a template definition (standards-compliant but not supported in GCC).
#if true (CodeWarrior-specific extension).
Anonymous unused arguments in C function definitions (legal in C99 but unsupported in GCC).
Structs in vararg lists (Metrowerks extension).
Using a const global variable in the definition of another const global (Metrowerks extension).
A class declared as a friend of template specialization that accesses private members.
Some examples of GCC-only code:
GCC inline assembler. GCC 3.3 and 4.0 can assemble CodeWarrior-style inline assembler, but CodeWarrior cannot handle the GCC syntax for inline assembly.
CodeWarrior offers a choice of using in-code #pragma statements or an .exp file to control which symbols are exported from your end-product libraries; GCC uses only the .exp file.
For more information on exporting symbols, see “Exporting Symbols.”
Last updated: 2006-10-26