Knowing something is coming doesn’t make it any easier when it does.


Rest in peace, Mom. I love you. You fought the good fight against MS for three decades. I will miss you terribly, but at last you are free from that disease’s relentless advance.

Well, it is now 2013, and I last posted about Xcode project files in October 2010. I have finally gotten around to publishing my ruby library for reading/creating Xcode project files. It does not currently have any support for related files (such as schemes and workspaces), though that seems like an obvious future improvement.

This project is not 100% polished; it needs examples, documentation, and unit tests, but what is there should be a good starting point for your own projects. bsxtools are published with an MIT license, which means you can freely use it for just about anything.

Patches and enhancements will be considered/absorbed as I have time!

Xcode build configurations

Most developers who have used Xcode for any length of time, especially in a team setting, are familiar with .xcconfig files. These are text files that contain project and/or target configuration settings. The idea is to remove all use settings from the project file itself, and move them into standalone text files. It is considerably easier to manage settings in source control when they are in xcconfig files than when they are specified in the Xcode project file itself (project.pbxproj), which is a sea of sometimes bewildering XML.

Suffice it to say, if you aren’t currently keeping all of your build settings in xcconfig files, you’re doing it wrong. While this advice is critically important to team development, it also applies to solo/indie development as well.

Pro Tip #1

You can choose to view your settings in Xcode in human-readable form, or in the form used in xcconfig files. The menu items are not in the same place or have the same names in every version of Xcode, unfortunately, but in Xcode 4.5 they can be found at the bottom of the Editor menu: “Show Setting Titles” vs. “Show Setting Names”, and “Show Definitions” vs. “Show Values”. You will need to be viewing build settings for these menu items to appear in the Editor menu!

But let’s focus on just one interesting aspect of xcconfig-based configuration: conditional configuration. You may want different settings depending on the SDK, or the configuration. For example, you will normally want debugging symbols in your Debug build; for your Release build, you want symbols removed from your shipping application, but still want the symbols available to help you interpret customer crash reports (“symbolication”). To achieve the former, you want to specify:

 … and for the latter, you want:

So how do you specify both? There are no fewer than three different ways to do this. In the chronological order in which they were supported in Xcode:

  1. Specify a different xcconfig file for each configuration; have each of these specify settings unique to that configuration, then #include a common file for settings that are the same for all configurations.
  2. Use variable expansion to specify different settings per configuration.
  3. New and shiny in 2012: Xcode now supports a standard multi-line/comment format.
Let’s look at examples of each of these.

Specify a different xcconfig file for each configuration

Here you will have:
myTarget.xcconfig, containing settings common to all configurations
myTargetDebug.xcconfig, containing:

#include "myTarget.xcconfig"
and myTargetRelease.xcconfig, containing:

#include "myTarget.xcconfig"
Finally, in Xcode, specify “myTargetDebug.xcconfig” as the xcconfig for the Debug configuration of myTarget, and myTargetRelease.xcconfig for the Release configuration.

Use variable expansion

Here you will have just one xcconfig for your target. To specify the debug information format, you will have something like this:

DEBUG_INFORMATION_FORMAT_Release = dwarf-with-dsym

Remember that xcconfig files are case-sensitive: You need to write “Debug” and “Release”, because those are the normal values for $(CONFIGURATION). The first line just sets DEBUG_INFORMATION_FORMAT to the value of DEBUG_INFORMATION_FORMAT_Debug or DEBUG_INFORMATION_FORMAT_Release, according to the value of CONFIGURATION.

This version is much nicer than the previous solution, because all of your settings are now in one place, rather than scattered across three different xcconfig files. The downside? You have to provide that first definition each time. Also it’s a little tricky to specify a default setting here, in case the CONFIGURATION should ever be neither Debug nor Release.

New multi-line/comment form

Now, in Xcode 4.5, you can do this:

//:configuration = Debug
//:configuration = Release
DEAD_CODE_STRIPPING = dwarf-with-dsym
//:completeSettings = some

The comment “scopes” the next line to just the specified configuration. The final “:completeSettings = some” handles the case where the configuration is something you didn’t handle (say, “distribution”). It is a convenient way to specify the default setting.

Advantages over variable expansion? It’s easier to understand, and easier to write. Disadvantages? It’s still not easy to write from scratch, and it takes up quite a bit more space in your xcconfig file.

Pro Tip #2

In Xcode 4.5, if you select a build setting in your project, and do Edit > Copy, Xcode will copy the setting(s) in the multi-line/comment form. This is very helpful if this is your preferred format (if not, you can edit the text, of course).

So, which style is best? Well, ultimately it is up to personal preference. My initial reaction to the latest option in Xcode 4.5 is that it feels too verbose for most settings, however it does avoid creating lots of “extra” settings (FOO, FOO_Debug, FOO_Release). For now, I’m still using variable-expansion, but I will experiment with the new format in new projects.


The new multi-line form appears to be broken in Xcode 4.5.2. Please file a bug if you want to use this method.

2 December 2012

Photoluna 1.5

Version 1.5 of Photoluna has been submitted to the App Store! If all goes well, it should be available sometime in the next 1-3 weeks. This version includes support for iOS 6, the iPhone 5 and the newest iPod Touches. There are new graphics, and maps are now integrated (into the “Where” tab).

Code Loupe 1.1.1

Code Loupe 1.1.1 contains bug fixes to the auto-update feature. This is probably the last release of Code Loupe that will support OS X 10.8.0, which has an unfortunate keychain bug. To support 10.8.0, I’ve had to build releases on 10.7; going forward, I’ll be moving release builds to Mountain Lion, which means that 10.8.1 will be the minimum version of Mountain Lion supported. Lion (10.7) will continue to be supported for at least a few more months.

« Older entries