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
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.
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 :
*.pbfilespec) : a list of files and wrappers types defined by their extension, MIME type or magic code. You may see current available type in Xcode's preference window (section Files). Generic types are : file, text, source code, compiled code, archive, audio, image, video, folder, wrapper.
*.pblangspec) : a language description, used to define syntax highlighting rules, auto-indentation rules, indexation and perhaps function name extraction (for the function popup menu), auto-completion and other editor specific tasks.
*.pbcompspec) : a compiler description, used to describe a command line compiler (like
javac…), available build setting for this compiler and how to parse its output.
*.pblinkspec) : a linker description, same as compiler specifications, but for command line linkers (like
*.pbprodspec) : a product is the final file created by your project (a library, an application…).
*.pbpackspec) : describes the structure of a product.
*.pbsetspec) : defines generic (i.e. non attached to a compiler or linker) build settings accessible from the Xcode GUI.
*.pbarchspec) : defines architectures (ppc, m68k, i386…).
*.pbplatspec) : Xcode may be used to compile code to different platforms, these specifications describe allowed architectures for each platform and where to search header files and libraries.
*.pbRTSspec) : available runtime system (native, java, applescript…)
*.xcbuildrules) : tell which source code file types may be compiled by a given compiler.
You will find Xcode's built-in definitions here :
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
keys, you don't need to write any code. In this case, you may just put the specification files in
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).
make build system, Xcode use many environment variables. Theses variables
are divided into three big classes :
$(SYSTEM_LIBRARY_DIR)… Theses variables are defined by Xcode.
$(HEADER_SEARCH_PATHS)… The names are available in the description of each setting. Theses variables are defined in the build setting window, according to compiler and linker specifications.
$(object_files)… Theses variables are defined by your own code, or Xcode internal one's.
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 (
and even recursive substitution (
When expanding, you may apply some filters on the value of a variable :
$(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.
To create an Xcode Plugin :
pbpluginin the build settings window of the target.
LoadAtLaunch = YES,
XCPluginHasUI = NOand
XCGCReady = YESkeys to the
*.pb*spec) to the resources build phase.
/Developer/Library/PrivateFrameworks/DevToolCore.frameworkframework to your project.
headersto your project.
XCODE_VERSIONmacro to 30 (or 21 / 22 / 23, if you target Xcode 2.1 / 2.2 / 2.3).
Xcode plugin.pbfilespecfile (you've downloaded it with the headers) to
A Xcode plugin must be put in the following folder to be used (do not forget to restart Xcode after) :
Feel free to have a look at my Objective-Caml plugin and Ada plugin source code and specification files.