Xcode, file references & build locations
Sunday, December 5th, 2004Within Xcode projects, every file or resource has a reference that instructs Xcode how to find the file. This includes files, resources, build products, dynamic libraries and everything else in the project.
These references are both extremely powerful and quite easy to configure incorrectly. Any resource reference can be either via a relative or absolute path. If relative, it can be relative to one of several locations including the project, the enclosing group, or the build directory.
Now, Xcode also has a very useful feature that allows you to specify a location into which all build products and intermediate products will be written. First and foremost, this will eliminate the noise of the build directory from your workarea. No more “? build” noise from CVS or Subversion. If you point it to the fastest hard drive on your system, you will also gain the advantage of all the intermediate and final products being written to and read from that fast device. If you have a boatload of RAM, create a RAM drive and eliminate a huge chunk of disk I/O from the build process. If using FileVault, moving the build directories will eliminate the overhead of encrypting the files created during the build of the project (with the obvious security sacrifice).
Just make sure you get the resource references correct. In particular, If you have multiple targets and then have a copy files build phase that copies those targets’ products into the product of some other target, make sure you use a build directory relative reference.
A project relative reference will work, but only on your system and only if your build directory never moves relative to your project directory.
And that is the real challenge to resource references. Misconfigured references will work on your machine the first time you set them, but will fail if used in an environment without exactly the same set of paths.
To help minimize the problem:
- Use Xcode’s preferences to set the intermediate and final build product directories to some place other than the project. Don’t use the same path. I have often set the path to /tmp/build-bbum/intermediate and /tmp/build-bbum/products respectively. This also guarantees that the projects will be rebuilt after any reboot. Occasional clean rebuilds often seem to clean up weird issues.
- Create a second user account on your system and use Fast User Switching to occasionally bop over, update a workarea and build the project. This will also rapidly pick up revision control problems, such as forgetting to add a resource to the repository.
- Better yet, keep a workarea on a second machine or have a friend do an update and make sure things still build.
This came up because I had been playing with Growl and had checked out the source because I wanted to fix a few bugs. The CopyFiles build phase in the GrowlHelperApp were project relative, but referred to build products, thus assuming that the build directory is always in the same place relative to the project.

