First issue - achieving a build.
Sublime can invoke command line programs to do a build. Xcodebuild is a command line tool that comes with Xcode that does it. To do a build, sublime needs a sublime-project file with a recipe in it.
It's a json file that you put in the root folder of your project, and it should look something like this, assuming that the xcodeproj file is in the same folder, and is named MyProject.xcodeproj.
You'll notice that I am overriding SYMROOT and OBJROOT because I am doing an out-of-source build into ~/build. You can omit that if you are fine with xcode putting build products in the usual spots. I greatly prefer an out of source build for reasons, which include being able to make a build utterly clean by simply deleting the build folder.
Command-B will invoke a build, and Control-C will stop it instantly, which is awesome.
MyProject.sublime-project
{
"folders": [
{
"follow_symlinks": true,
"path": "."
}
],
"build_systems": [
{
"name": "Xcode Build",
"cmd": [ "xcodebuild",
"-project", "$project_path/$project_base_name.xcodeproj",
"-configuration", "Debug",
"-scheme", "MyProject",
"SYMROOT=~/build/Products/Debug", "OBJROOT=~/build" ],
"variants": [
{
"name": "Xcode Run Debug",
"cmd": [ "~/build/Products/Debug/$project_base_name.app/Contents/MacOS/$project_base_name" ],
},
{
"name": "Xcode Build Release",
"cmd": [ "~/local/bin/xctool",
"-project", "$project_path/$project_base_name.xcodeproj",
"-configuration", "Release",
"SYMROOT=~/build/Products/Release", "OBJROOT=~/build" ],
},
{
"name": "Xcode Run Release",
"cmd": [ "$~/build/Products/Release/$project_base_name.app/Contents/MacOS/$project_base_name" ],
}
]
}
]
}
Second Issue - Optional - excess verbiage
The next issue you will notice is that when you do a build, there is an excess of verbiage that appears in the build window, making it exceedingly difficult to find real problems. You might be fine with that, or have magical regexs to find warnings and errors, and if so you can skip this step.
I used git to clone Facebook's xctool, and built it following the instructions on their page.
https://github.com/facebook/xctool
After building, a build folder appeared. A couple of layers deep there is a Products/Release directory. I have a particular place I store /bin and /lib files, and I copied xctool out of Products/Release/bin to my bin, I copied the dylibs from Release/lib to /lib, and I copied the Release/reporters folder to a /reporters folder that I created as a sibling to my /bin and /lib. (To be clear, the result was /reporters/stuff, not reporters/reporters/stuff.)
I changed the cmd in the project from xcodebuild to xctool.
Finally, I entered this
os.environ["PATH"] = os.environ["PATH"]+":/my/local/bin"
to point to my local bin from within Sublime's python console. This is necessary in my case because I haven't yet figured out how to communicate my shell path to launchctl so that the path Sublime knows about is the same as my shell path.
Inconveniently I have to redo that every time I start Sublime, but I'll work out the right answer eventually.
Now, builds are much tidier to read (my eyes are much happier), and the results include timings, which is nifty.
Third Issue - Sublime's Build Window is Pretty Much Useless
This issue could be PEBCAK (Problem Exists Between Computer and Keyboard), but some searching around places like Stack Overflow make me think otherwise.
In a nutshell the build window vanishes if you do pretty much anything interesting, like touching the mouse or keyboard. Also, the only operation it supports during its brief existence is scrolling. Heaven forbid you want to search for the word warning, or error, or something like that.
Also I was not for the life of me able to make the Sublime "go to next error" regex stuff work. It was mostly a world of hang, so I looked for an alternative.
I installed sublime-text-2-buildview, which despite it's name, works fine in Sublime Text 3. It captures the output from the ephemeral build window and redirects it to a normal text editing window, once again, a small bit of awesome. (I used Package Control to install it.)
Bonus Round - xcconfigs
For the bonus round, I moved all of my project settings out of the xcodeproj and into an xcconfig file so that I could control things like search paths, preprocessor settings, and warning levels from the comfort of my text editor.
I followed this tutorial - http://www.jontolof.com/cocoa/using-xcconfig-files-for-you-xcode-project/, setting my files up exactly as he suggests. Note that if you are copying and pasting a setting and it doesn't show up properly in the text editor (ie, if they paste as only the name of the setting without a value), it's because Debug and Release are different. You need to select them individually and paste them into the appropriate xcconfig file.
I didn't rest until all my settings showed up as coming from the xcconfigs.
Conclusion
Once you've got all this set up, a command line build is equally easy to achieve. I put together a little sh script for myself that contains roughly the contents of the cmd field above, and it worked a treat.
Especially when I need my laptop's battery to last a long time, building in Sublime is a huge win.
There's obviously some rough edges in this set up, particularly the environment setting if you use xctool, and it's hard to believe that the build window is as terrible as it seems - have I missed something obvious? Nonetheless, I hope you find this helpful, and would welcome suggestions or improvements from anyone.