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.
- 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.
- Make sure “Run script only when installing” is shut off.
- Enter “
/usr/bin/osascript” as the Shell for the script. - 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
- 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.
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?
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.
???
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?
CFBundleVersionhere because it’s convenient for my particular usage./Library/ScriptingAdditions/Adobe Unit Types.osax.touchcommand 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 anagvtool-style build version for that).Check out agvtool.
If you read the comments, you would see that I mention agvtool elsewhere. It doesn’t do what my script does – i.e. run automatically or update your Info.plist.