Nutty Namesakes

When Apple introduced the Mac App Store, it was clear that I would need to produce two distinct versions of my apps: one custom-built so suit the specific requirements of the App Store, and one built the way it always ever was, to be distributed directly to customers.

The approach I took was to simply duplicate the application target in all of my Xcode projects, such that for every final app target, there is a counterpart for the App Store:

Xcode build settings showing MarsEdit App Store having the same product name as MarsEdit.

Because the vast majority of build settings for all of my products are specified in Xcode configuration files, there isn’t much duplication here. True, each of the targets has to list its dependencies, resources, linked libraries, etc., but for the most part I go about editing source files on a day-to-day basis and when I ship an app update it just comes down to building and archiving each target in turn.

If you look carefully at the screenshot above, you will see that the MarsEdit App Store target has “MarsEdit” set as its product name. This is good, because I want each of the resulting apps to be named “MarsEdit.app.” As far as I know, there is no getting around it: the two targets have to share the same product name in order for them to build differing products that nonetheless have the same name.

This mostly works fine, in spite of a few Xcode glitches. One example is the auto-generated “Products” group in the project navigator shows two entries called “MarsEdit.app,” and doesn’t give any indication of which one is which. This can make it slightly annoying to easily e.g. right-click on a product and reveal it in the Finder.

Now as it happens I also define multiple targets that share the same product name in some of my supporting framework projects. Particularly since Apple started supporting the use of frameworks for iOS code, I’ve changed my iOS static library bundles over to frameworks. So where I used to have RSFoundation.framework and RSFoundation.o, I now have two targets, each producing a framework for the desired platform. Here’s an example where Xcode actually handles the doppelgängers with some aplomb. If you go to add a framework to a target and there are duplicates with the same name, it takes care to differentiate them:

Screenshot showing Xcode finding multiple libraries with the same name

Recently I ran into a troubling behavior with Xcode’s testing schemes, that I’ve correlated with the scenario of having a testing bundle target in a project that specifies as its test host a specific one of two targets whose product names match. The bug, in a nutshell, is Xcode can end up deciding that both targets should be built as forced dependencies of the test bundle, leading to annoying, hard to explain behaviors. I wrote this up as Radar 19924983 if you’re interested in reading more. And here’s the sample project I included with the bug, if that is something you’re interested in checking out.

On the whole I’m pretty happy with the approach of using separate targets with the same name. I am pretty sure I could work around whatever bugs I come across by resorting to splitting the two targets up into independent Xcode projects, but that feels a lot less elegant to me. The fact that Xcode supports duplicate names as well as it does in e.g. the “add libraries” panel I showed above gives me hope that support for namesake product targets will continue to improve in the future.