Search code examples
iosxcodexcconfig

XCConfig syntax


If I had an Adhoc.xcconfig where I defined a variable:

PREPROCESSOR_DEFINITIONS = IS_ADHOC=1 CRASHLYTICS=1

and in a run script, there's a check that looks like:

if [ "${PREPROCESSOR_DEFINTIONS/CRASHLYTICS=1}" = "$PREPROCESSOR_DEFINITIONS" ] ; then
    echo "Crashlytics is disabled, skipping Crashlytics dSYM upload"
else
    echo "Crashlytics is on"
end

What does that if statement check? I'm unclear if the / is syntax specific to bash or to xcconfig. What's also confusing is that the if statement is checking the result of an assignment using = not ==.

Breaking down the if statement piece by piece:

  • "${PREPROCESSOR_DEFINITIONS}/CRASHLYTICS=1}" - is a variable expansion.

  • / - is this indexing the larger variable, PREPROCESSOR_DEFINTIONS to check for the existence of the CRASHLYTICS variable?

  • = "$PREPROCESSOR_DEFINITIONS" - Is this just assigning this string literal to the result of the prior expression?

Anyone that could illuminate that syntax and what the if statement is trying to accomplish, that would be great.


Solution

  • This is all about bash, not xcconfig files. The xcconfig file only establishes a build setting. By default, build settings are exported to run-script build phases as environment variables. That's the only relationship between the two. The format of xcconfig files was only relevant while reading the xcconfig file.

    From the bash man page section on Parameter Expansion:

    ${parameter/pattern/string}

    The pattern is expanded to produce a pattern just as in pathname expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. […] If string is null, matches of pattern are deleted and the / following pattern may be omitted. […]

    So, "${PREPROCESSOR_DEFINTIONS/CRASHLYTICS=1}" expands PREPROCESSOR_DEFINTIONS but removes all instances of CRASHLYTICS=1 from the resulting string.

    The single = is not assignment. It's the equals comparison. Bash also supports == but, as the man page says:

    = may be used in place of == for strict POSIX compliance.

    So, technically, = is the more standard.

    Thus, the if is testing if PREPROCESSOR_DEFINTIONS doesn't contain CRASHLYTICS=1. If it did contain it, then the expansion with CRASHLYTICS=1 removed would not equal the unmodified expansion.

    Of course, this makes sense given the echo statements in each branch of the if.