I am trying to pass in a compiler macro definition in Xcode that relies on a simple system shell command.
The first thing I tried was to add it to the specific file in Build Phases->Compile Sources like this:
to my surprise that didn't work, so I tried this:
This printed out the value correctly but the macro wasn't passed to the source file correctly. I figure this one didn't work because it creates a separate shell instance and thus the environment variable is not persisted to the compilation phase.
I tried doing a Google search and looking around StackOverflow as well, and the only promising thing I found was this, which didn't seem to have a working solution: XCode C/C++ Flags Bash Script
The code I wrote looks like this:
#define STRINGIFY(X) #X
#define TOSTRING(X) STRINGIFY(X)
#define AT __FILE__ ":" TOSTRING(__LINE__)
NSString* getBuildHash()
{
return [NSString stringWithCString:TOSTRING(GIT_COMMIT_HASH) encoding:NSASCIIStringEncoding];
}
Any help would be greatly appreciated :) Thanks!
So, thanks to https://therealbnut.wordpress.com/2012/01/01/setting-xcode-4-0-environment-variables-from-a-script/ I was able to solve it!
Putting the simple steps for Xcode 6 here in case anyone else runs into this...
Step 1:
Click on the target and under Build Phases click on the New Run Script Phase under the plus sign.
I used the following script:
Step 2:
Build it! Product->Build This generates a llvm.xcconfig file in the project directory :)
Step 3:
Add the .xcconfig to the project by right clicking on the target and hitting Add Files to ""
Step 4:
In the target settings, under the Build Phases pane, double click on the appropriate source under Compile Sources and add in
$(BUILD_INFO)
for the file's compiler flags.Step 5:
Go to the project settings (not the target settings!). It should bring you to the Info pane. Under Configurations set Debug and Release to use the "llvm" configuration.
Under this menu, you may also have to move the llvm.xcconfig Copy Bundle Resources target.
Step 6:
You're done!! Try building and make sure it all works :)
Here's an idea that might help:
In the shell script (the "run script" in the build phases), instead of setting an environment variable, write your value to a file that's already included in the project. To make it easier you can use the build phase just to launch another shell script that will do the work.
For example, you can have a header file which contains a define (or a static variable):
#define kObjCFlags @"MY_FLAGS"
. Your script will inject and replace the value each time it runs (use a regex to replace just the content of the string).Since it's part of the project you can simply import and use it wherever you need. Also, it doesn't have to be a header file - it can be a plain text file or a plist that you can read from the code.