How to solve the biggest problems with automating iOS builds

Automating iOS Builds in Jenkins should be easy. When you say it fast it sounds like it could be easy. 2 weeks of my life later, the automation of iOS builds has some complexities which I hadn’t expected. The main problem I had was with precompiled headers. It wasn’t long before I got the error “has been modified since the precompiled header”.

For simplicity I am going to write about how to overcome this problem in simple shell commands. For this post at least I am going to shy away from translating this into re-usable build scripts which can be called from Jenkins. The topic sounds like a good future blog post topic through so rest assured I will write about how to create a Jenkins build for iOS builds in the future.

The basics of building an iOS project from a shell script are as easy as:

#!/bin/bash
set DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
export DEVELOPER_DIR
xcodebuild -project SampleProject.xcodeproj

Simple right, and it is.

  • Line 1: Standard line which tells the shell what program to interpret the script with, when executed.
  • Line 2 & 3: Selects the version of Xcode you want to use.
  • Line 3: Use Xcode to build the project.

We of course want to run our unit tests when we build, how would we know the code was a good build otherwise?

#!/bin/bash
set DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
export DEVELOPER_DIR
xcodebuild build test -project SampleProject.xcodeproj -scheme SampleProject -configuration Debug -sdk iphonesimulator

Still easy stuff, so what’s so hard? This will work a few times then you will most likely start getting errors. When you scan the error you will more than likely see the phrase “has been modified since the precompiled header”. A search of this error will lead you to lots of articles.

  1. http://stackoverflow.com/questions/19391768/file-has-been-modified-since-the-precompiled-header-was-built
  2. http://stackoverflow.com/questions/14793329/fixing-file-project-pch-has-been-modified-since-the-precompiled-header-was-bui
  3. https://developer.appcelerator.com/question/148500/error–prefixpch-has-been-modified-since-the-precompiled-header-was-buil-why-

They will kind of help but the key to success is cleaning your build fully. So I tried this …

xcodebuild clean build test -project SampleProject.xcodeproj -scheme SampleProject -configuration Debug -sdk iphonesimulator

Kind of works but doesn’t always clean the Derived Data folders. I tried doing this as well:

rm -rf ~/Library/Developer/Xcode/DerivedData/

That didn’t work, you won’t have permissions to do that. You can work around it but not really from a build server. Then I stumbled onto something, maybe we could just move where Xcode writes out to, after all you can do this for other things, for example the OBJROOT. It turns out you can, simply moving where the Derived Data Folder is means it can be cleaned properly and you will only effect this project.

xcodebuild build test -project SampleProject.xcodeproj -scheme SampleProject -derivedDataPath derivedData -configuration Debug -sdk iphonesimulator

So in the end I settled on changing the location of the Derived Data Folder, Object Root and Configuration Build Directory.

#!/bin/bash
set DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
export DEVELOPER_DIR

rm -rf derivedData
rm -rf tmp/objs
rm -rf build/SampleProject

xcodebuild build test -project SampleProject.xcodeproj -scheme SampleProject -derivedDataPath derivedData OBJROOT=tmp/objs CONFIGURATION_BUILD_DIR=build/SampleProject -configuration Debug -sdk iphonesimulator

With this in place I no longer have problems with precompiled headers. Builds and tests are also a lot more consistent.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *