Xcode's Plugin Interface

Abstract : this document explains how to write a plugin for integrating an unsupported compilers into Xcode (versions 3.0), to provide a fully integrated development platform for your preferred programming language. Plugins are currently available for : OCaml language, ADA language, Fortran language and targeting Symbian OS.

Jan. 2008 : updated for Xcode 3.0
Sept. 2006 : add a fortran plugin and a link to a plugin to develop for Symbian OS
Sept. 2006 : add documentation for GUI build settings and build rules
May 2006 : updated for Xcode 2.3

You may download theses pages as a ZIP archive for offline reading.

Sourceforge page for Xcode Plugins

Table of Contents

1. Background
2. When is a plugin unnecessary ? (TODO)
3. Specification Files
3.1. Generic Informations about Specification Files
3.2. File Type Definition (.pbfilespec)
3.3. Language Definition (.pblangspec)
3.4. Build Rules (.xcbuildrules)
3.5. Installing Your Own Specification File
4. Dependency Graph Creation
4.1. Xcode's Build System
4.2. Graph Creation API
4.3. Compiler Sample Code (.pbcompspec)
4.4. Linker Sample Code (.pblinkspec)
4.5. Parsing the ouput of command line tools (TODO)
4.6. Product Type Sample Code (.pbprodspec)
5. Build Settings and Environment Variables
5.1. Adding Build Settings in the GUI (.pbbsetspec)
5.2. Environment API
5.3. Useful Environment Variables
6. Building an Xcode Plugin
7. A Word about Templates (TODO)

1. Background

Apple's free IDE, Xcode, only provides support for C(++), Objective-C(++), Java, Applescript and Makefile. Although it's possible to use a Makefile for other languages, I think it's more practical to fully integrate them through dedicated plugins.

At the time I wrote this page, Xcode already has a working plugin interface (it's even used by CoreData compiler/editor, CVS/Subversion/Perforce integration, GDB debugging…). However this interface is not yet public, because not really finished. According to Apple, it'll be public in future release but no real date is provided : developers just have to wait :-(.

With a lot of reverse engineering, I've successfully understood parts of this plugin interface and started to wrote a plugin for the Objective Caml language. Because many developers would like to write Xcode plugins for various programming languages, I've decided to publish the result of my reverse engineering work.

There's actually only informations about compilers, linkers and syntax highlighting plugins.

2. When is a plugin unnecessary ?

TODO

3. Specification Files

3.1. Generic Informations about Specification Files
3.2. File Type Definition (.pbfilespec)
3.3. Language Definition (.pblangspec)
3.4. Build Rules (.xcbuildrules)
3.5. Installing Your Own Specification File

Xcode maintains internal arrays of many kind of objects used for every basic task. Each object (or a list of object of the same kind) is defined by a NSDictionary stored in a property list file. Xcode uses the key Class to let you specify which Objective-C class will be used to instantiate your object. Xcode also provide generic/default classes for each object types.

These object specifications are defined hierarchically (an object may be "BasedOn" another one, and then inherits all its properties) inside each specification kind :

You will find Xcode's built-in definitions here :

/Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/

The plugin code entry points are only custom classes specified by Class keys in every specifications stored in it's Contents/Resources. If you don't use any Class keys, you don't need to write any code. In this case, you may just put the specification files in folder :

~/Library/Application Support/Developer/Shared/Xcode/Specifications/

4. Dependency Graph Creation

4.1. Xcode's Build System
4.2. Graph Creation API
4.3. Compiler Sample Code (.pbcompspec)
4.4. Linker Sample Code (.pblinkspec)
4.5. Parsing the ouput of command line tools (TODO)
4.6. Product Type Sample Code (.pbprodspec)

A compiler (or linker) object is not used during the build task, but before it, when computing the dependency graph between source files, headers, compiled object files and the final product. This task is done when you open a project, add/remove a file from a target or save a edited file.

A compiler object is responsible of dependencies between source file (.c, .m…), header files (.h…) and compiled object file (.o). It also creates the command to generate the compiled object file.

A linker object is responsible of dependencies between compiled object files and the final product (an executable or library). It also generates the command used to link all object files.

When you request your project to build, Xcode just read the dependency graph and run your defined commands in the best order.

The file & command dependency graph of my OCaml Plugin created with Graphviz (click to enlarge).

5. Build Settings and Environment Variables

5.1. Adding Build Settings in the GUI (.pbbsetspec)
5.2. Environment API
5.3. Useful Environment Variables

Like the make build system, Xcode use many environment variables. Theses variables are divided into three big classes :

All variables are of type string. However, string lists may be simulated with space separated lists, as for command line tool arguments, and bool variables are simulated by using the two values NO and YES.

All Xcode strings (in build settings window, specification files, arguments of your plugin methods), may contain variable substitution ("$(TARGET_PRODUCT_DIR)/$(PRODUCT_NAME)") and even recursive substitution ("$(GCC_VERSION_$(arch))").

When expanding, you may apply some filters on the value of a variable : :quote ($(MYVAR:quote)) to quote the value, :base to extract the basename of a file (= delete the extension), :identifier to convert the value to a string suitable for use as a C variable/identifier name.

6. Building an Xcode Plugin

To create an Xcode Plugin :

A Xcode plugin must be put in the following folder to be used (do not forget to restart Xcode after) :

~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/

Feel free to have a look at my Objective-Caml plugin and Ada plugin source code and specification files.

7. A Word about Templates

TODO