If your project uses PowerPlant, importing the project should include all the PowerPlant source files. To build successfully with GCC 4.0, however, you’ll have to make a few changes to the code.
To build PowerPlant in your Xcode project, you perform these steps, described in the following sections:
Add PowerPlant’s headers to the project and target.
Create a prefix file in Xcode that includes the PowerPlant headers and the necessary definitions.
Make minor changes to the PowerPlant code to build with the GCC 4.0 compiler.
For related information in other sections, see “The GCC Compiler,” “Framework-Style Headers,” and “Precompiled Headers and Prefix Files.”
Add PowerPlant Headers to the Project and Target
Create a Prefix File for PowerPlant
Make Minor Changes to the PowerPlant Code
This requirement should be taken care of automatically when you use the Xcode project importer to import a project that uses PowerPlant. If you find that any files are missing when you attempt to build the project, you can drag them into the project from the Finder, or use Project > Add to Project in Xcode.
After adding the PowerPlant header files, you need to disentangle the header files from the CodeWarrior precompiled header mechanism. To do this, you need to create a prefix header for PowerPlant in Xcode that includes information from the following PowerPlant files: CommonMach-OPrefix.h, DebugMach-OPrefix.pch++, PP_ClassHeaders.cp, PP_DebugHeaders.cp, and PP_MacHeadersMach-O.c.
Listing 4-6 shows a header file that contains the needed definitions and include statements from these CodeWarrior header files. You can use this header file for a debug or a final target. See “Creating Debug and Non-Debug Products” for more information.
Listing 4-6 An Xcode prefix header file for PowerPlant
/* |
* PP_Xcode.h |
* |
* Created on Wed Jan 29 2003. |
* Copyright (c) 2003 __MyCompanyName__. All rights reserved. |
* |
*/ |
#define _STD std |
#define _CSTD std |
#define __dest_os __mac_os_x |
#define PP_Target_Carbon 1 |
#define PP_Target_Classic (!PP_Target_Carbon) |
// ------------------------------------------------------------------ |
// Options |
#define PP_Uses_PowerPlant_Namespace 0 |
#define PP_Supports_Pascal_Strings 1 |
#define PP_StdDialogs_Option PP_StdDialogs_NavServicesOnly |
#define PP_Uses_Old_Integer_Types 0 |
#define PP_Obsolete_AllowTargetSwitch 0 |
#define PP_Obsolete_ThrowExceptionCode 0 |
#define PP_Warn_Obsolete_Classes 1 |
#define PP_Suppress_Notes_2 211 |
// |
// Carbon headers |
#include <Carbon/Carbon.h> |
// |
// PowerPlantheaders |
// Action Classes |
#include <LAction.h> |
#include <LUndoer.h> |
#include <UTETextAction.h> |
#include <UTEViewTextAction.h> |
// AppleEvent Classes |
#include <LModelDirector.h> |
#include <LModelObject.h> |
#include <LModelProperty.h> |
#include <UAppleEventsMgr.h> |
#include <UExtractFromAEDesc.h> |
// Array Classes |
#include <LArray.h> |
#include <LArrayIterator.h> |
#include <LComparator.h> |
#include <LRunArray.h> |
#include <LVariableArray.h> |
#include <TArray.h> |
#include <TArrayIterator.h> |
// Commander Classes |
#include <LApplication.h> |
#include <LCommander.h> |
#include <LDocApplication.h> |
#include <LDocument.h> |
#include <LSingleDoc.h> |
// Feature Classes |
#include <LAttachable.h> |
#include <LAttachment.h> |
#include <LBroadcaster.h> |
#include <LDragAndDrop.h> |
#include <LDragTask.h> |
#include <LEventDispatcher.h> |
#include <LListener.h> |
#include <LPeriodical.h> |
#include <LSharable.h> |
// File & Stream Classes |
#include <LDataStream.h> |
#include <LFile.h> |
#include <LFileStream.h> |
#include <LHandleStream.h> |
#include <LStream.h> |
// Pane Classes |
#include <LButton.h> |
#include <LCaption.h> |
#include <LCicnButton.h> |
#include <LControl.h> |
#include <LDialogBox.h> |
#include <LEditField.h> |
#include <LFocusBox.h> |
#include <LGrafPortView.h> |
#include <LListBox.h> |
#include <LOffscreenView.h> |
#include <LPane.h> |
#include <LPicture.h> |
#include <LPlaceHolder.h> |
#include <LPrintout.h> |
#include <LRadioGroupView.h> |
#include <LScroller.h> |
#include <LStdControl.h> |
#include <LTabGroupView.h> |
#include <LTableView.h> |
#include <LTextEditView.h> |
#include <LView.h> |
#include <LWindow.h> |
#include <UGWorld.h> |
#include <UQuickTime.h> |
// PowerPlant Headers |
#include <PP_Constants.h> |
#include <PP_KeyCodes.h> |
#include <PP_Macros.h> |
#include <PP_Messages.h> |
#include <PP_Prefix.h> |
#include <PP_Resources.h> |
#include <PP_Types.h> |
// Support Classes |
#include <LClipboard.h> |
#include <LFileTypeList.h> |
#include <LGrowZone.h> |
#include <LMenu.h> |
#include <LMenuBar.h> |
#include <LRadioGroup.h> |
#include <LString.h> |
#include <LTabGroup.h> |
#include <UDesktop.h> |
// Utility Classes |
#include <UAttachments.h> |
#include <UCursor.h> |
#include <UDebugging.h> |
#include <UDrawingState.h> |
#include <UDrawingUtils.h> |
#include <UEnvironment.h> |
#include <UException.h> |
#include <UKeyFilters.h> |
#include <UMemoryMgr.h> |
#include <UModalDialogs.h> |
#include <UPrinting.h> |
#include <UReanimator.h> |
#include <URegions.h> |
#include <URegistrar.h> |
#include <UScrap.h> |
#include <UScreenPort.h> |
#include <UTextEdit.h> |
#include <UTextTraits.h> |
#include <UWindows.h> |
To build PowerPlant in Xcode with GCC 4.0, you need to make a relatively small number of changes to the source code. These changes are described here, with accompanying code listings. The line numbers are based on source files from CodeWarrior Pro version 8.3.
To avoid a GCC error, in the file LGATabsControlImp.cp, starting at line 964, move the declaration of tabButton outside the kControlTabEnabledFlagTab case, as shown in Listing 4-7.
Listing 4-7 Modified switch statement in LGATabsControlImp.cp
switch (inTag) { |
// case kControlTabContentRectTag: { |
// Rect contentRect = *(Rect *)inDataPtr; |
// ••• Now what do we do with this? Do we resize the |
// control to fit the content rect? |
// break; |
// } |
LGATabsButton*tabButton; |
case kControlTabEnabledFlagTag: { |
Boolean enableIt = *(Boolean *)inDataPtr; |
tabButton = GetTabButtonByIndex(inPartCode); |
if (tabButton != nil) { |
if (enableIt) { |
tabButton->Enable(); |
} else { |
tabButton->Disable(); |
} |
} |
break; |
} |
case kControlTabInfoTag: { |
tabButton = GetTabButtonByIndex(inPartCode); |
if (tabButton != nil) { |
ControlTabInfoRec*info = (ControlTabInfoRec*) inDataPtr; |
tabButton->SetDescriptor(info->name); |
tabButton->SetIconResourceID(info->iconSuiteID); |
} |
break; |
default: |
LGAControlImp::SetDataTag(inPartCode, |
inTag, inDataSize, inDataPtr); |
break; |
} |
} |
In LStream.h, you’ll need to enclose several method definitions in conditional directives to avoid redefinition with GCC. Listing 4-8 shows the first change, at line 152.
Note: Commenting out these methods makes them unavailable to client code. Usage of these methods is rare, but if they are used in your application, you may need to make additional source changes.
Listing 4-8 LStream.h modifications at line 152
#ifndef __GNUC__ |
LStream&operator << (long double inNum) |
{ |
(*this) << (double) inNum; |
return (*this); |
} |
LStream&operator << (short double inNum) |
{ |
(*this) << (double) inNum; |
return (*this); |
} |
#endif |
Listing 4-9 shows the second change to LStream.h, at line 172.
Listing 4-9 LStream.h modifications at line 172
#ifndef __GNUC__ |
LStream&operator >> (long double &outNum) |
{ |
doublenum; |
(*this) >> num; |
outNum = num; |
return (*this); |
} |
LStream&operator >> (short double &outNum) |
{ |
double num; |
(*this) >> num; |
outNum = (short double) num; |
return (*this); |
} |
#endif |
You’ll also have to make a change to LException.h for GCC. Change the definition of the class destructor to agree with the standard C++ library exception definition, as shown in Listing 4-10. The class listing begins at line 23, while the changes begin at line 33.
Listing 4-10 LException.h modifications at line 33
class LException : public PP_STD::exception { |
public: |
LException( |
SInt32 inErrorCode, |
ConstStringPtrinErrorString = nil); |
LException( const LException& inException ); |
LException& operator = ( const LException& inException ); |
#ifndef __GNUC__ |
virtual ~LException(); |
#else |
virtual ~LException() throw(); |
#endif |
virtual const char*what() const throw(); |
You’ll also have to change the implementation of the class destructor to agree with standard C++ library exception definition, as shown in Listing 4-11. The class listing begins at line 90, while the changes begin at line 94.
Listing 4-11 LException.cp modifications at line 94
// ------------------------------------------------------------------ |
// • ~LException Destructor [public] |
// ------------------------------------------------------------------ |
#ifdef __GNUC__ |
LException::~LException() throw() |
#else |
LException::~LException() |
#endif |
{ |
} |
The following changes are required after importing a CodeWarrior PowerPlant project with a Debug target.
In LDebugStream.cp, you’ll have to modify the following (occurring at line 1150):
UInt8* theFirstByte = static_cast<UInt8*>(const_cast<UInt8*>(inPtr)); |
You can instead use the line shown in Listing 4-12:
Listing 4-12 LDebugStream.cp modification at line 1150
const UInt8* theFirstByte = ((const UInt8*) inPtr); |
In LCommanderTree.cp (at line 87) and in LPaneTree.cp (at line 81), you’ll have to modify the following lines (which have a slightly different error message in LPaneTree.cp):
#if __option(RTTI) |
#include <typeinfo> |
#else |
#error "RTTI option disabled -- Must be enabled for LCommanderTree to function" |
#endif |
You can instead use the lines shown in Listing 4-13:
Listing 4-13 Modification to LCommanderTree.cp at line 87 (and to LPaneTree.cp at line 81)
#ifdef __GNUC__ |
#include <typeinfo> |
#else |
#if __option(RTTI) |
#include <typeinfo> |
#else |
#error "RTTI option disabled -- Must be enabled for LCommanderTree |
to function" |
#endif |
#endif |
Last updated: 2006-10-26