2

In an Objective-C project I am attempting to take a file path from an environment variable and set it as a location to write generated files. This is used to run test code using xcodebuild in an automated testing environment where the file path is not determined until xcodebuild is called.

In attempt to do this I am entering a preprocessor macro in the Build Settings that references the variable:

BUILDSERVER_WORKSPACE=\@\"$(WORKSPACE)\"

and then setting the value of a string using that macro

NSString *workspaceLocation = BUILDSERVER_WORKSPACE;

in cases where the (string value of) the path for $WORKSPACE does not contain spaces it works fine but in cases where the path has spaces, the macro preprocessor sees the whitespaces as a macro separator and attempts to process them as separate macro definitions.

for example:

$WORKSPACE=/foo/bar/thudblat

will set the value of workspacelocation as @"/foo/bar/thudblat" but

$WORKSPACE="/foo/bar/thud blat"

ends up creating multiple preprocessor definitions:

#define BUILDSERVER_WORKSPACE @"/foo/bar/thud

#define blat"

I have attempted to stringify the path, but since the presence or absence of whitespace only happens when i call xcodebuild to build and then run and so I cannot get that to work.

In the end, what I want is to simply take the path at $WORKSPACE and set its value to the NSString *workspaceLocation

so that workspaceLocation could potentially be "\foo\bar\thud blat"

Patrick
  • 416
  • 3
  • 7
  • 2
    Don't you need to put the entire macro expression in quotes? BUILDSERVER_WORKSPACE="\@\"$(WORKSPACE)\"" – nielsbot Aug 26 '15 at 19:37
  • Surely this takes the value of the environment variable at *build* time, or am I missing something? – CRD Aug 26 '15 at 20:13
  • aha good point, I am running this as part of testing using xcodebuild and so it *is* building and then immediately running, so it very likely is evaluating this macro at build time. – Patrick Aug 26 '15 at 20:22

3 Answers3

1

I thought I had tried every scheme of quoting and escaping but, the one thing I had not tried was quoting the entire thing as suggested by @nielsbot BUILDSERVER_WORKSPACE="\@\"$(WORKSPACE)\""

with an unescaped quote at the beginning and end of the entire value statement. Thad did the trick and gave me the string: @"/foo/bar/thud blat" when calling xcodebuild.

Patrick
  • 416
  • 3
  • 7
0

You can achieve that with double stringize trick:

#define STRINGIZE_NX(A) #A
#define STRINGIZE(A) STRINGIZE_NX(A)

static NSString *kWorkspace = @( STRINGIZE(BUILDSERVER_WORKSPACE) );

The way it works is very well explained in here: https://stackoverflow.com/a/2751891/351305

Community
  • 1
  • 1
pronebird
  • 12,068
  • 5
  • 54
  • 82
0

If you wish to really read the environment variable at runtime then you can simply obtain it from NSProcessInfo:

NSString *workspaceLocation = NSProcessInfo.processInfo.environment[@"WORKSPACE"];

That will give you the current value of the environment variables, spaces and all.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • Yes, note my clarifications on compile time vs runtime when calling this in xcode build. processinfo **will** give you the runtime environment variables for the current execution context. It is also interesting to note that my case was running the code on an iOS simulator which did not possess the same environment variables as the workstation on which xcodebuild was called. – Patrick Aug 27 '15 at 00:54