Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode 10 Build Phase Shell Script

Tags:

xcode10

In our project we derive our release version from git tag etc then write it to the built folder's Info.plist with a shell script like:

GIT_RELEASE_VERSION=$(some git command) defaults write "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH%.*}" "CFBundleShortVersionString" "${GIT_RELEASE_VERSION#*v}"

This has worked well for all past Xcode versions, but in Xcode 10's New Build System this failed to actually update the CFBundleShortVersionString in the info.list file. The value is correctly updated with Xcode 10's Legacy Build System though.

I added some echos to the script and compared the build log on New and Legacy systems and cannot see any difference:

echo "git release version:" ${GIT_RELEASE_VERSION} echo "info path:" ${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH%.*} echo "grv:" "${GIT_RELEASE_VERSION#*v}"

Not sure if anyone out there encountered similar issues with the New Build System?

like image 290
CodeBrew Avatar asked Sep 26 '18 18:09

CodeBrew


People also ask

How do I run a build phase script in Xcode?

Go to the Build Phases section of your project. (Click on the project, then on the main target, then on the “Build Phases” tab along the top.) Click the + at the top left to create a new build phase; choose “New Run Script Phase.” Xcode creates the script at the end of the list, naming it “Run Script.”

How do I add build phases in Xcode?

To view the build phases for a target, select the target and navigate to the Build Phases tab, as shown in the following figure. To add a new build phase, click the Add button (+) and select an appropriate build phase from the pop-up menu. Xcode disables any menu options that aren't valid.

How do I create a shell script in Xcode?

To create a custom build script: Open your project or workspace in Xcode and navigate to the Project navigator. Control-click the ci_scripts group you created earlier and choose New File. Choose the Shell Script template.

What is legacy build system Xcode?

If you need it, the legacy build system is still available in Xcode 10. To use the legacy build system, select it in the File > Project/Workspace Settings sheet. Projects configured to use the legacy build system will display an orange hammer icon in the Activity View.


2 Answers

It seems like the problem is that sometimes your Run Script Phase will execute before Xcode creates the Info.plist. If you’d like to ensure that your script phase runs after a specific step, you need use the inputs to mark your dependencies.

For instance, adding:

$(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)

As an input to your script phase should enforce the ordering you are looking for: Xcode will create the Info.plist and sometime after, your script will execute and modify the Info.plist.

like image 118
David G. Avatar answered Sep 29 '22 06:09

David G.


(Xcode 11.2)

  • In the New Build System, any custom build steps will run before the New Build System's Process .../Info.plist step:

enter image description here

  • To run a shell script after Xcode finishes building, you can add it to your scheme(s) as a build post-action:

Product > Scheme > Edit Scheme... > Build > Post-actions

I stole this image from https://stackoverflow.com/a/54232034/969305

  • If you're going to reference any build system environment variables (e.g. BUILT_PRODUCTS_DIR or INFOPLIST_PATH), make sure you change the Provide build settings from selection.

  • Add your shell script, but remember that if you edit any file in the app bundle (i.e. Info.plist), you'll need to re-sign the app. Add this to your post build step:

export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
/usr/bin/codesign --force --sign - --entitlements "${TARGET_TEMP_DIR}/${FULL_PRODUCT_NAME}.xcent" --timestamp=none "${CODESIGNING_FOLDER_PATH}"
like image 44
sam-w Avatar answered Sep 29 '22 08:09

sam-w