Build settings for Xcode projects

Here’s an iFAQ: Jeff, how do you choose the topics for your blog posts? Answer: I don’t. All of my topics are actually chosen by manatees. For some reason, those crazy manatees have indicated that today I should talk about build settings for Xcode projects. They’re inscrutable! The manatees, that is, not the build settings…at least not for the most part.

Some developers never dare to change the default build settings. Why? Because the Xcode build settings pane is scary — perhaps not as scary as the Oompa-Loompas, but scary nonetheless. And like the Oompa-Loompas, there is more than one pane. Besides the project build settings, each target in the project has its own build settings too. It’s enough to drive you mad! (That’s what happened to this friend of mine, so he had a lobotomy. Now he’s well again.) Still, you might want to change the build settings in your project, because the default settings were designed for backwards compatibility, not for the latest-and-greatest, state-of-the-art, up-to-the-minute, cutting-and-bleeding-edge technologies (such as Mac OS X 10.2). Even Apple recommends changing the value of ALWAYS_SEARCH_USER_PATHS, for example.

The default build settings for a project, indeed many of the elements of a project, come from a template in the folder Project Templates. When you create a new project in Xcode, it uses the template corresponding to the project type. The template for a Cocoa application project is in the Cocoa Application folder. Like other items in the /Library/ folder, you can override the default template in a particular user account, say, yours, by putting a parallel item in the user’s ~/Library/ folder. To change the template for a Cocoa application, create the folder ~/Library/Application Support/Apple/Developer Tools/Project Templates/Application/, copy the Cocoa Application/ template to that folder, and modify your copy of the template. The build settings are stored in the file CocoaApp.xcodeproj/project.pbxproj. If you’re adventurous, you could edit that file directly. On the other hand, you could just open the CocoaApp project in Xcode and change the build settings there, but afterward you’d want to delete the Xcode-generated files such as build/ in the project folder as well as the .mode1 and .pbxuser files in xcodeproj/. You might also want to delete those pesky Finder-generated .DS_Store files. (Please, please get rid of them in Leopard!) Xcode will use your custom template rather than the factory template whenever you create a new Cocoa application project.

There are many different types of project template, even for a Cocoa application — Cocoa Application, Cocoa Document-based Application, Core Data Application, etc. — so it could become tedious to change every template you need. If you only want to change the default build settings, it would be much easier to create a build settings configuration file that you can use in all of your projects.

Which default build settings should you change? As I mentioned, you should uncheck Always Search User Paths. You should check Enable Objective-C Exceptions (GCC_ENABLE_OBJC_EXCEPTIONS) to use @try, @catch, and @throw exception handling. You’ll probably also want to set the value of Mac OS X Deployment Target (MACOSX_DEPLOYMENT_TARGET) to the oldest version that your application will support. If you want to be cruel, set it to 10.5.

The most confusing collection of build settings, in my opinion, are the compiler warnings. Apple has an interesting article about this, and you can find definitions of the warnings in the GCC manual. If you hate to RTFM, you’re in luck, because I already did. I recommend using the warnings Missing Function Prototypes (GCC_WARN_ABOUT_MISSING_PROTOTYPES), Missing Newline At End Of File (GCC_WARN_ABOUT_MISSING_NEWLINE), Sign Comparison (GCC_WARN_SIGN_COMPARE), and for Other Warning Flags (WARNING_CFLAGS), -Wall. You would think that -Wall would cover all warnings, but noooooooooooo! However, the -Wall option does enable the default warnings in a Cocoa application project, Mismatched Return Type (GCC_WARN_ABOUT_RETURN_TYPE) and Unused Variables (GCC_WARN_UNUSED_VARIABLE), so those settings can be deleted when you use this flag.

If you would like to use my settings, you can copy the text below into an .xcconfig file. The values of SDKROOT and PREBINDING are preserved from the default Cocoa application template. For information on prebinding, see the documentation.

P.S. The manatees have asked me to remind you to use precompiled prefix headers!

// Jeff's project build settings
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk
ALWAYS_SEARCH_USER_PATHS = NO
PREBINDING = NO
MACOSX_DEPLOYMENT_TARGET = 10.4
GCC_ENABLE_OBJC_EXCEPTIONS = YES
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
GCC_WARN_ABOUT_MISSING_NEWLINE = YES
GCC_WARN_SIGN_COMPARE = YES
WARNING_CFLAGS = -Wall

Update: I’ve revised the build settings to remove some warnings. It turns out that the flags -Wall -Wextra already enable GCC_WARN_UNUSED_PARAMETER, and that warning can get annoying anyway, so I removed it and the -Wextra flag. I removed the flag -Wconversion too, because it does far more than I wanted it to. The warning GCC_WARN_SHADOW was ditched because it doesn’t like you to use the variable index. I added GCC_WARN_SIGN_COMPARE, which was enabled by -Wextra.

6 Responses to “Build settings for Xcode projects”

  1. Tim says:

    I guess I think like a manatee. Thanks. This is useful stuff.

  2. Jeff says:

    So, where is the best place to put this .xcconfig file?

  3. Jeff says:

    If you want to use the xcconfig file in a project, just use Add to Project, but make sure to de-select the target. Then open the build settings pane and select the file under Based on: to base your build configurations on the settings in the file.

  4. Dave Parizek says:

    Thanks! As a newbie I have been somewhat overwhelmed by XCode’s settings and this post and its references have helped me immensely. Karma points to you.

  5. Jeff says:

    I’ve updated my build settings. Sorry, I should have tested them more before posting. Fortunately, some extra warnings never killed anyone (I hope)!

  6. index is a function, that’s why you get a shadowed warning.

    NAME
    index, rindex — locate character in string

    LIBRARY
    Standard C Library (libc, -lc)

    SYNOPSIS
    #include

    char *
    index(const char *s, int c);

    char *
    rindex(const char *s, int c);