Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode custom shell scripts are slowing down the compiling time

Testing any changes to my Xcode project has become an exercise in patience whenever I build. After all the source files have compiled, I get the following message in the activity window at the top of Xcode:

"Running 3 of 3 Custom Shell Scripts"

I have not added any of my own custom shell scripts but I am using quite a few dependencies via Cocoapods and I am using 2 frameworks for the build environment, Crashlytics and Tapstream. Crashlytics requires you add a run script in the build phases, other than that I don't know where the other ones are coming from and they appear to be the bottleneck in my build time.

Can anyone enlighten me as to what is going on and how i possibly speed it up?

like image 545
Genhain Avatar asked Dec 18 '13 03:12

Genhain


People also ask

Why does Xcode run my script every time I build?

If you don’t specify input or output files, Xcode runs your script every time you build the target. For more information, see Improving the Speed of Incremental Builds. Xcode configures the execution environment for your script and gives your script access to the same build settings and environment variables as the target.

How can I speed up my Xcode build time?

Xcode uses the set of input and output files to optimize build times, by running your script only when necessary. If you don’t specify input or output files, Xcode runs your script every time you build the target. For more information, see Improving the Speed of Incremental Builds.

How do I execute a custom script at build time?

To execute a custom script at build time, add a Run Script build phase to your target. This build phase runs separately from the target’s other build phases, such as the compilation and link build phases. You may add multiple script-related build phases to your target to execute scripts at different stages of the build.

Do I need to specify input and output files in Xcode?

You don’t have to specify input and output files, but it’s highly recommended that you do. Xcode uses the set of input and output files to optimize build times, by running your script only when necessary. If you don’t specify input or output files, Xcode runs your script every time you build the target.


2 Answers

I can't enlighten you but I can tell you how I stopped mine from running. This also happened after installing Cocoapods. In my main project's Target, under Build Phases, I noticed two entries entitled Check Pods Manifest.lock and another called Copy Pods Resources.

Under both there was an unchecked option Run script only when installing. I checked both and at least for now my projects build and run fine without running the scripts.

This is kind of a crappy answer because I can't really give you any more information, and it might not even work for your case, so hopefully someone comes along and enlightens us.


POSSIBLE EXTERNAL BUNDLE ISSUES

So I just had a frustrating experience debugging an issue where a pod installed library's NSLocalized strings file weren't working. Turns out it was because I checked the option mentioned above. Pods-resources.sh, which had the lines to install the bundle, wasn't running in debug mode. It was only running when installing - of course! Something to watch out for.

More info in this question:

NSLocalizedStringFromTable not working in CocoaPod dependency

like image 141
OdieO Avatar answered Oct 11 '22 15:10

OdieO


To fix the slow "Copy pods resources" problem I figured out a solution to only copy the resources if they haven't been copied before.

For this purpose we have to patch the *-resources.sh files that are created by cocoapods such that the copy procedure only happens if a generated file in the target directory doesn't exist (it is created upon first copy). As long as this target directory exists and includes this autogenerated file, the copy resources phase is skipped. This saves me about 30 seconds in my project (of course depends on your project size). To accomplish this do the following:

Create a patch file called 'copy_pod_resources_once.patch' in your project root dir with the following contents:

5a6,13 > NONCE_FILE="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/copyresources-done.nonce" > if [ -f "$NONCE_FILE" ]; then >    echo "already copied resources" >    exit 0 > else >    touch "$NONCE_FILE" > fi >  

In the Podfile for your project add the following post install hook:

post_install do |installer_representation|     system('find "./Pods/Target Support Files" -name "*-resources.sh" | xargs -I{} patch -p0 {} -i ./copy_pod_resources_once.patch')      <other post install stuff> end 
like image 21
Werner Altewischer Avatar answered Oct 11 '22 15:10

Werner Altewischer