According to Hoyle...
Moving From CodeWarrior to Xcode (Part III)
by Jonathan Hoyle
June 2007 email@example.com
Over the past two months, we have been reviewing the steps needed for porting CodeWarrior projects to Xcode. In Part I, we outlined recommended preflighting adjustments to your CodeWarrior project and source code. In Part II, we continued by reviewing Xcode settings and using the Project Importer to convert the PowerPlant sample project Appearance.mcp.
Metrowerks' PowerPlant had been the dominant C++ application framework on the Macintosh for over a decade. When Metrowerks' short-sighted parent company Freescale mindlessly ran CodeWarrior into the ground, it took PowerPlant to the grave with it. Fortunately, as Metrowerks was transitioning out of the Macintosh development market, the PowerPlant framework was released into the public domain to allow developers to continue using and evolving it to remain viable on Xcode. This includes both the PowerPlant and PowerPlant X frameworks as well as Constructor. PowerPlant is held in SourceForge, with Metrowerks alumni Isaac Wankerl and Ron Leichty as Project Administrators, with a dozen developers currently active on the project. Download Open PowerPlant.
For over a year now, Open PowerPlant has been fully GCC 4.0 compliant, and can be compiled into Universal Binaries. For those of you with projects which rely on heavy use of the PowerPlant framework, I strongly recommended simply converting to Open PowerPlant.
However, for those projects which have minor PowerPlant interactivity, such a brain transplant may be unnecessary. Minor modifications to the PowerPlant source files you are using may be sufficient. If this is the route you opt to go, you should familiarize yourself with Apple's recommendations for PowerPlant change.
We will continue now with this latter approach.
Modifying Our Project Settings
As we last left our Appearance project, compiling Appearance.xcodeproj left us with 17 errors:
Upon examination of this, we see that many of these errors are due to missing macro definitions. For example, the final error indicates that we have the PP_Target_Classic macro enabled when we should have PP_Target_Carbon enabled instead.
To fix this problem, go to Xcode's Project menu and select Edit Project Settings. When the Settings dialog is presented, scroll down and select the Preprocessor Macros field and then press the Edit button:
A sheet window will then appear. Click on the + button to create an new field and enter the text PP_Target_Carbon=1, as so:
Press OK to save, and recompile. Now we are down to 8 errors left, which include the undefined macros _STD and _CSTD. As we did with PP_Target_Carbon, we add these other two macros, defining them to be std. When you are finished, your preprocessor macros should look like this:
Recompiling now should yield you these five errors:
Modifying Our Project Source Files
At this point, we will need to actually modify CodeWarrior files. You may wish to make copies of these files so that the changes we make will not affect other CodeWarrior projects.
The first error is simply Xcode not finding the header file <ansi_prefix.mach.h>. Clicking on this error will display the location in PP_Macros.h where this file is #included. The simplest fix here is to comment out the #if, #include, #else and #endif lines, as so:
// #if __MACH__
// #include <ansi_prefix.mach.h>
#define __dest_os __mac_os
This leaves us with four displayed errors, which are actually only two errors: both occurring inside the LException class. Its base class std::exception has throw() specifiers for its virtual destructor and its what() method, whereas LException does not. This is remedied by modifying the LException.h header and LException.cp source file so that these two method prototypes appear as:
virtual ~LException() throw();
virtual const char* what() const throw();
As we next compile, Xcode generates an error in LCommander.cp not understanding the old style header file HIToolbox.h. Comment out this #include and replace with <Carbon.h>:
// #include <HIToolbox/HIToolbox.h>
Further on, we get an error in the LStream class in overloads of the << and >> operators. In particular, Xcode does not accept the type short double. Here we merely comment these lines out as so:
// LStream& operator << (short double inNum)
// (*this) << (double) inNum;
// return (*this);
// LStream& operator >> (short double &outNum)
// double num;
// (*this) >> num;
// outNum = (short double) num;
// return (*this);
Finally we pass the headers and begin compiling the source files. You'll note how much slower Xcode is relative to CodeWarrior. The first source file we run into trouble with is In UDebugging.cp, with a complaint locating the file !PP_Notes_222.doc. As this is not a critical file, we may simply comment this one out as well:
// #include "!PP_Notes_222.doc"å
Compilation succeeds, but we are left with a plethora of link errors! This is due to the fact that our Xcode project is lacking the Carbon framework. We need to add Carbon.framework, CoreServices.framework and ApplicationServices.framework to our project. This is perhaps most easily done by drag-copying them from another Xcode project. From Xcode's File menu, select the New Project... menu item. Within the New Project Assistant dialog, select Carbon C++ Application and press Next. Select a location for this temporary project, such as the Desktop. Once done, drag the External Frameworks and Libraries folder onto your Appearance project. It should then appear as such:
You can now dispose of the temporary Carbon project.
Coming Up: In an upcoming article we will continue with Part IV of our CodeWarrior project conversion, but next month: A recap of Apple's Worldwide Developer's Conference 2007. See you in 30!