Simple monotonically increasing build numbers in Xcode

Time and time again a thread will come up on the xcode-users mailing list about how to make Xcode put a build number in an application’s Info.plist.

The first answer is always agvtool, but it’s the wrong answer, as agvtool is a version manager for public versions. It’s what generates all those wacky numbers you see in Mac software, such as “Mac OS X Version 10.6.2 Build 10C540″ or “Xcode version 3.2.1 build 1613.0″. It’s certainly not the simple build number people are looking for.

Everyone has their own way of dealing with this, as Xcode makes it extremely difficult to handle it in any elegant way. For example, because Xcode absolutely insists on processing Info.plist before doing anything else in a build (why? why!?), you can’t just plug in a build setting replacement and be done. Various and sundry methods exist, most of which involve either writing the value to the generated Info.plist in the built product or modifying the original Info.plist on every build.

I don’t like those methods, so I came up with one that will work nicely and store the build number as a setting within the project file. Much nicer, IMO, than having to touch your Info.plist file every build and then committing the numbers to your version control system.

  1. Add a new Run Script build phase to your project. Place it before all other build phases if you want the number to increase for all builds, or after if you want it only to increase on successful builds.
  2. Make sure “Run script only when installing” is shut off.
  3. Enter “/usr/bin/osascript” as the Shell for the script.
  4. Enter this script:
    tell application "Xcode"
        set prj to system attribute "PROJECT_NAME"
        repeat with config in build configurations of project prj
            try
                set x to build setting "CURRENT_PROJECT_VERSION" of config
                set value of x to ((((value of x) as number) + 1) as string)
            on error
                set value of build setting "CURRENT_PROJECT_VERSION" of config to "1"
            end try
        end repeat
    end tell
    set srcrt to system attribute "SRCROOT"
    set iplstf to system attribute "INFOPLIST_FILE"
    do shell script "touch " & srcrt & "/" & iplstf
    
  5. In your Info.plist file, add or set a key like this:
        <key>CFBundleVersion</key>
        <string>${CURRENT_PROJECT_VERSION}</string>
    

Figuring out how to make build numbers on a per-target or per-configuration basis is left as an exercise to the reader :-).

P.S. I hate Applescript, but it’s the only way I know of to set build settings in an Xcode project.

6 thoughts on “Simple monotonically increasing build numbers in Xcode

  1. Excellent! :-)

    However, because I’m a bloody beginner at this: isn’t CFBundleVersion already a key in my Info.plist? I used to set it to some “marketing” version string like “2.0 beta 1″ or similar.
    So does this mean if I want this version string AND the increasing build number I should use another (new) key for the Info.plist file? One that I can choose freely? Like CFBundleShortVersion? Or like CFBundleBuildNumber? Or like GeeeeWhatsThat?

  2. WHOA!

    I get this in my build log:

    2010-02-06 01:11:07.908 osascript[41553:60f] Error loading /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: dlopen(/Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types, 262): no suitable image found. Did find:
    /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: no matching architecture in universal wrapper
    osascript: OpenScripting.framework – scripting addition “/Library/ScriptingAdditions/Adobe Unit Types.osax” declares no loadable handlers.

    ???

  3. Okay. Two things:
    1) The errors don’t mind. Script works anyway.
    2) Sometimes (often) increasing doesn’t work for one build but in the next build the number increases by 2. Where’s the problem?

    1. You can choose any key you like; I just used CFBundleVersion here because it’s convenient for my particular usage.
    2. That error means your installation of some Adobe program (Acrobat Reader would be my first guess) isn’t compatible with your OS install. You probably need an update, or if you don’t have any such thing, just trash /Library/ScriptingAdditions/Adobe Unit Types.osax.
    3. The first time you build, the build setting doesn’t exist, so you get no replacement at all. After that, the build version you get in your Info.plist is one behind the one in your project settings, because of the above-noted issue with Xcode insisting on processing Info.plist before doing anything else. You’re probably seeing some kind of race condition with the touch command the AppleScript runs to force Xcode to reprocess the plist. I wouldn’t bother trying too hard to fix it, since a monotonically increasing build number has no intrinsic absolute value, and thus it generally isn’t critical for it to be one number out of date. If you’re depending on such a build number for anything other than your own personal tracking of things, you might want to reexamine your situation. Such numbers aren’t suitable for, for example, tracking what version of your code a user has (use an agvtool-style build version for that).

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>