5 Replies
      Latest reply on Oct 22, 2019 9:00 AM by Crudebyte
      Crudebyte Level 1 Level 1 (15 points)

        Is there still no (in whatever creative) way to set Xcode's own environment variables from a "Run Script Phase" script?

         

        As you might know, the problem with "Run Script" build phase scripts always was that those scripts are forked as a separate process by Xcode. So a script inherits downwards Xcode's environment variables, but any changes made to those environment variables by scripts will not propagate back to Xcode due to that.

         

        Is there maybe in the meantime a way to force scripts being run directly within Xcode's build process instead of being forked? Or is there some RPC that would allow to modify Xcode's environment variables by script?

        • Re: Run Script Phase & Environment Variables
          john daniel Level 4 Level 4 (500 points)

          What are you trying to accomplish?

            • Re: Run Script Phase & Environment Variables
              Crudebyte Level 1 Level 1 (15 points)

              Well, it's about customizing the build process in general. There are various use cases for this. For instance encryption keys which should not be part of source files, or automatically adjusting relative framework pathes (e.g. due to differences in teams). Another very typical use case is dynamically filling Info.plist fields by Xcode scripts.

               

              So let's just stick with the latter use case: Say you wanted to automatically compile an Xcode project using always latest git HEAD commit's SHA1 as user visible build number for the generated app binary. If there was a way to let a "Run Script" build phase script adjust Xcode's environment, then all you had to do was adding a tiny script like this to the Xcode project "Run Script" build phase:

               

              FOO_GIT_REV=`(cd $SRCROOT && git rev-parse --short=4 --verify HEAD)`
              export FOO_GIT_REV

               

              And in the Xcode target's Info.plist you would simply use that environment variable like:

               

              <key>CFBundleVersion</key>
              <string>$(FOO_GIT_REV)</string>
              

               

              and that's it.

               

              Of course there are workarounds for this example. Typically people use something like this instead in an Xcode "Run Script" build phase script:

               

              system("/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion ${FOO_GIT_REV}\" \"${INFOPLIST_FILE}\"");

               

              So you extract the git commit hash and write it literally to the Info.plist file instead within the same Xcode script. But the problem with this approach is that the script is constantly modifying Info.plist itself of course, so you are mixing a file being under version control (Info.plist) with dynamically generated content by a build script. Hence you always have that Info.plist on your dirty list e.g. with "git status" and you cannot git ignore it, since the rest of the Info.plist file is still relevant for version control of course.

               

              If there was some way to manipulate Xcode's environment variables by script, that would convey many build configuration tasks in an easy and convenient way. Because you can actually reference environment variables almost everywhere in Xcode already.

                • Re: Run Script Phase & Environment Variables
                  Crudebyte Level 1 Level 1 (15 points)

                  I just filed a feature request for this (FB7399724), since I assume there is still no way in Xcode for "Run Script" phase scripts to modify Xcode's environment variables.

                   

                  My suggestion was to add a new editable list "Output Environment Variables" to the "Run Script" build phase pane, similar to the existing editable lists there ("Input Files", "Output Files", ...). So once a script ended execution, Xcode would read the current value of the listed environment variables from the script's process and apply them globally to Xcode's environment.

                  • Re: Run Script Phase & Environment Variables
                    john daniel Level 4 Level 4 (500 points)

                    Why not just undo your hack in another run script at the end? You can also add pre and post run scripts to your scheme, which might push it further out off Xcode's core build sequence.

                      • Re: Run Script Phase & Environment Variables
                        Crudebyte Level 1 Level 1 (15 points)

                        Not a bad idea actually. But it's still an unnecessarily too complicated hack for a hack, and dealing directly (by parsing & modifying) with the files is error prone and unclean. Think about the other example: auto adjusting pathes in your Xcode project. Depending on the case you might need some more thorough custom parsing/adjusting (e.g. with regexs) to potentially merge with other things there.

                         

                        Anyway, I still hope this issue will be fixed at its root by simply allowing to adjust/add Xcode environment variables by build phase scripts. It is much cleaner, simpler and would also avoid confusions by members of your team why some certain project setting has just changed "magically". ;-) I mean if you reference a variable e.g. in the project file or any .plist file, then any developer clearly really sees there is a variable. Period. And on doubt (s)he can simply grep for where exactly this variable is filled.