~2012

Hacking the Xcode templates

I never work with OSX but my colleagues do. So sometimes I need to help them out. This time we wanted to create an Xcode template for OpenFrameworks with the application project outside of the openFrameworks root. As this templating thing in Xcode is quite undocumented this is kind of a reminder...

Some example templates are shipped with OF. We found the ones in the GIT repository weren't good. We fixed them by adding the Cairo header paths.

The thing is we want to keep OF in a seperate repository while working on applications. This way we can manage a central OF repository and the applications can just use that central repository. Much easier in a team workflow! However as Apple users are used to GUI's LOL they need a way to set the path to their OF root easily.

I hacked the template project.pbxproj to use a custom variable (or macro if you prefer). However the macros are encoded in a different encoding inside the utf encoded file. This is a bit tricky. I ended up using find and replace with an hexeditor in order te set the variable.

I use the OF_ROOT variable to replace all "../../.." entries. Like this snippet from the .pbxproj file:

                GCC_WARN_UNUSED_VARIABLE = NO;
                HEADER_SEARCH_PATHS = (
                    "«OF_ROOT»/libs/openFrameworks/**",
                    «OF_ROOT»/libs/freetype/include/,
                    «OF_ROOT»/libs/freetype/include/freetype2,
                    «OF_ROOT»/libs/poco/include,
                    «OF_ROOT»/libs/glew/include,
                    «OF_ROOT»/libs/tess2/include,
                );
                OTHER_CPLUSPLUSFLAGS = (
                    "-D**MACOSX_CORE**",

In a terminal on OSX you can set this variable with a this command:

defaults write com.apple.Xcode PBXCustomTemplateMacroDefinitions '{ "OF_ROOT" = "../openFrameworks";}'

You can read these vars with this command.

defaults read com.apple.Xcode PBXCustomTemplateMacroDefinitions

Hey this is very similar to the old STEP environment .... ;-)

I've found this old thread very usefull. It says this:

Somebody pointed you to a method to modify the Xcode project templates, but with inadequate introduction that is a delicate proposition.

An Xcode project template is a specially modified Xcode project. It has an additional plist file that contains lists of files that should get renamed when the project is created from the template, and a list of files whose contents need to be macro-expanded when the project is created from the template

Basically, the way Xcode project template instantiation works is as follows:

1) Xcode reads the TemplateInfo.plist in the template bundle's .xcodeproject wrapper. 2) All files that aren't listed in the FilesToRename or FilesToMacroExpand arrays in the plist are copied unaltered to the designated project directory. 3) All files in the FilesToRename list are copied to the designated project directory and renamed accordingly. Each item in the list is a pair of (original file name) = (replacement file name). The replacement file name usually has a macro like «PROJECTNAME», which is replaced with the project name given by the user. 4) All files in the FilesToMacroExpand list are then run through a grep-like process that replaces macros enclosed in « » characters with expanded equivalents. Below is the list of candidate macros. The ASIDENTIFIER macros are munged to start with alpha characters and not include spaces. The ASXML versions are escaped as XML, so they can be used in the plist file, for example. The UUID is unique for each file expanded, so you can uniquify file names if needed.

DATE
 TIME
 USERNAME
 FULLUSERNAME
 ORGANIZATIONNAME
 YEAR
 UUID
 UUIDASIDENTIFIER
 FILENAME
 FILEBASENAME
 FILEBASENAMEASIDENTIFIER
 FILEBASENAMEASXML
 FILEEXTENSION
 PROJECTNAME
 PROJECTNAMEASIDENTIFIER
 PROJECTNAMEASXML
 PRODUCTNAME
 PRODUCTNAMEASIDENTIFIER
 PRODUCTNAMEASXML
 TARGETNAME
 TARGETNAMEASIDENTIFIER
 TARGETNAMEASXML

Here's the really important part. The project files are encoded as UTF-8, but the macro delimiter« and » are encoded in MacRoman. This is guaranteed to confuse you and most text editors. This is done to eliminate the possibility that real content in the project files or sources will be mistaken for template macros. Allowing your text editor (Xcode or TextMate) to set the file encoding to UTF-8 will cause the macro expansion to fail, and the templates will create corrupted products that don't work.

Better, more complete instructions can be found at

http://briksoftware.com/blog/?p=28