Building X-Plane Plugins on Macintosh

This document describes the steps necessary to build plugins on the Macintosh.

If we have a version of CodeWarrior compatible with CodeWarrior 8, we can start with the sample projects in the SDK.

We do not need the latest version of CodeWarrior to build X-Plane plugins.  Any version of CodeWarrior that can generate PowerPC code and CFM shared-libraries can be used to build plugins.

If we have ProjectBuilder/GCC we currently cannot build plugins for X-Plane on Macintosh.  ProjectBuilder and GCC cannot build CFM-format shared libraries; they can only build Mach-O dynamic libraries.  A future version of the SDK may support Mach-O natively.

Compiling C/C++ Plugins

To compile plugin source code on Macintosh we must do two things: set up the IBM/APL macros and set up the include paths.

Setting up the APL/IBM macros

The macros APL and IBM are used to differentiate what platform a plugin is being compiled for.  They must be defined before any XPLM_____.h header is included.  There are three ways to define these macros: we can simply define them in each .c file before including any headers, or we can use a prefix file, or we can use a command-line option if the compiler supports that.

To define the macros in each .c file, make sure each plugin file starts something like this:
/* First define the platform */
#define APL 1
#define IBM 0

/* Now include the plugin headers
#include "XPLMDisplay.h"
#include "XPLMGraphics.h"

/* My plugin code then continues */

PLUGIN_API int XPluginStart(...
This technique is simple, the only problem is that if we want to compile this plugin for IBM, we have to edit the header and change each definition of APL and IBM.  What a pain!

A better solution is to define a prefix file .  A prefix file is a header that the compiler automatically includes before every file in the project.  In CodeWarrior (most versions), we can enter the name of the prefix file in the project settings, typically in the C/C++ language options pane.  The header would simply contain
#define APL 1
#define IBM 0
The advantage of this technique is that we can make a separate prefix file for Windows that contains the opposite definitions and compile the same code on two platforms.

If the compiler supports command-line options we can often use them to define macros.  For example, we can use these command-line flags for GCC:
-DAPL=1 -DIBM=0

Setting Up the Include Paths

We must tell the compiler where to find the XPLM headers.  In CodeWarrior, use the access paths panel (part of the project settings) to specify that CodeWarrior should search for headers in the "headers" directory of the X-Plane SDK.  The exact location of the SDK will depend on where we unzipped it on the hard drive.

If we are using a command-line compiler like GCC, we can use the -I compiler flag to tell the compiler where to find headers, for example:
-I/Volumes/Alpha/dev/SDKS/XPSDK/Headers/XPLM
With the include paths and #defines we should be all set to compile plugin code.

Dealing With Old Compilers

If the compiler is old it may not support the __declspec(export) syntax for specifying exported plugin functions.  If this a problem simply delete the PLUGIN_API macro from before the plugin's required callback function names.  If we are using C++ we must declare the function extern "C" like this:
extern "C" void XPluginStop(void) { .... }
Also, note that we had to do this as it will affect the linking settings later!!

Linking Plugins

To link the code into a plugin, we'll have to add some files to the project and set up the proper project settings.

Additional Files to Add to the Project

We must add the following files to the project:
In addition, if we are using OpenGL code in the plugin we will need to link against the OpenGL stub libraries.  We must download the OpenGL SDK from Apple.  It can be found at http://developer.apple.com/opengl/downloads.html.  From the SDK include the following libraries:
Finally, we will need some kind of shared library C runtime.  The names of these files vary from version to version and compiler to compiler.  The most recent one for Metrowerks is called MSL_All_Carbon_D.Lib.  The best way to find this file is to find a sample CFM shared library project that comes from or works with the development environment and use the runtime files that it comes with.  Runtime files sometimes have names like "MSL", "Runtime", etc...

Other Project Settings

This next section lists project settings.  They are listed generically so we can hopefully spot the version of these settings for the environment.
Make sure the project type is set to CFM shared library.  If the compiler supports __declspec (if not, we haven't gotten this far!) then make sure to use the PLUGIN_API macro in front of the required functions (XPluginStart, etc.).  

If we had to delete the PLUGIN_API macro to compile, set the project to export all globals to the shared library.