'xcode info.plist build variable ${PRODUCT_NAME:rfc1034identifier} seems completely undocumented?

I'm trying to find documentation that describe the syntax and possibilities suggested by the construction ${PRODUCT_NAME:rfc1034identifier}. Obviously this turns into some version of the product name, but where is the documentation that describes how? I just grepped the entire /Developer directory, and got nothing useful.

I'm not looking for the narrow definition of what happens to this particular variable, I want to know about all such modifiers like rfc1034identifier.



Solution 1:[1]

By using strings I also dug out the following things that look like they're related to :rfc1034identifier:

  • :quote - adds backslashes before whitespaces (and more), for use in shell scripts
  • :identifier - replaces whitespace, slashes (and more) with underscores
  • :rfc1034identifier - replaces whitespace, slashes (and more) with dashes
  • :dir - don't know, observed replace with ./ in some cases
  • :abs - don't know

Exact command:

strings /Developer/Library/PrivateFrameworks/DevToolsCore.framework/Versions/A/DevToolsCore|grep '^:'

There are more things that look like interesting modifiers (for example, :char-range=%@), but I couldn't get these to work. There's only one example of :char-range on the net, and it's from a crash log for Xcode.

Someone asked how do we know it's a modifier specification. Well, we know because it works on multiple variables in build settings. Plist preprocessor probably uses the same mechanisms to resolve build variables as does the build system.

Hack Saw, if you get a response via that bug report, don't forget to keep us informed :-)

Solution 2:[2]

Looks like you can stack these as well. The useful case floating around out there is

com.yourcompany.${PRODUCT_NAME:rfc1034identifier:lower}

such that a product name of "Your App" becomes com.yourcompany.your-app.

Solution 3:[3]

$ strings /Developer/Library/PrivateFrameworks/DevToolsCore.framework/Versions/A/DevToolsCore

PRODUCTNAME
PRODUCTNAMEASIDENTIFIER
PRODUCTNAMEASRFC1034IDENTIFIER
PRODUCTNAMEASXML

It seems that there are :identifier, :rfc1034identifier and :xml modifiers. But I have no clue except this.

Solution 4:[4]

After stumbling over this question and its existing answers, I have to say: Apples documentation did not improve on this topic over the recent years. We are currently at Xcode 13 and there is still no complete list of all modifiers available.

Therefore I did some spelunking and found the supported modifiers in DVTFoundation.framework which I will list below.

I've tested them all in Xcode 13.3 build settings and used the following two macros to illustrate their impact:

MY_MACRO = Some "text" with umlauts äöüçñ and special characters are ',/|\-_:;%&<>.!
MY_SOURCE = /Applications/Xcode.app/Contents/Frameworks/../SharedFrameworks/DVTFoundation.framework

Retrieval operators/modifiers

Retrieval modifiers are used to extract and/or transform all or parts of a macro/variable/setting.
They are applied using the following syntax: $(<VARIABLE>:<MODIFIER>)

  • quote: Escapes all characters which have a special meaning in shell scripts/commands like space, colon, semicolon and backslash.
RESULT_quote = $(MY_MACRO:quote)

Some\ \"text\"\ with\ umlauts\ äöüçñ\ and\ special\ characters\ are\ \',/|\\-_:;%&<>.!
  • upper: Transforms all characters to their uppercase equivalents.
RESULT_upper = $(MY_MACRO:upper)

SOME "TEXT" WITH UMLAUTS ÄÖÜÇÑ AND SPECIAL CHARACTERS ARE ',/|\-_:;%&<>.!
  • lower: Transforms all characters to their lowercase equivalents.
RESULT_lower = $(MY_MACRO:lower)

some "text" with umlauts äöüçñ and special characters are ',/|\-_:;%&<>.!
  • identifier: Replaces any non-C identifier characters with an underscore (_).
RESULT_identifier = $(MY_MACRO:identifier)

Some__text__with_umlauts_______and_special_characters_are________________
  • rfc1034identifier: Replaces any non-rfc1034 identifier characters with a hyphen (-)
RESULT_rfc1034identifier = $(MY_MACRO:rfc1034identifier)


Some--text--with-umlauts-------and-special-characters-are----------------------------
  • c99extidentifier: Replaces any non-C99 identifier characters with an underscore (_). Umlauts are allowed as C99 uses Unicode!
RESULT_c99extidentifier = $(MY_MACRO:c99extidentifier)

Some__text__with_umlauts_äöüçñ_and_special_characters_are___________________________
  • xml: According to Apple documentation it should replace special xml characters with the corresponding escape string. For example, less-than (<) is replaced with <. But in my examples this didn't work.
RESULT_xml = $(MY_MACRO:xml)

Some "text" with umlauts äöüçñ and special characters are ',/|\-_:;%&<>.!
  • dir: Extracts the directory part of a path
RESULT_dir = $(MY_SOURCE:dir)

/Applications/Xcode.app/Contents/Frameworks/../SharedFrameworks/
  • file: Extracts the filename part of a path
RESULT_file = $(MY_SOURCE:file)

DVTFoundation.framework
  • base: Extracts the filename base part of a path (=filename without suffix/extension)
RESULT_base = $(MY_SOURCE:base)

DVTFoundation
  • suffix: Extracts the filename extension/suffix a path or filename
RESULT_suffix = $(MY_SOURCE:suffix)

.framework
  • standardizepath: Standardizes the path (e.g. ../ and tilde (~) are resolved)
RESULT_standardizepath = $(MY_SOURCE:standardizepath)

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework

Replacement operators/modifiers

Beside above extracting/transforming operators, there is support built into the build settings system to replace specific parts of a directory which are matched using a modifier.
They are applied using the following syntax: $(<VARIABLE>:<MODIFIER>=<VALUE>)

  • dir=<VALUE>: Replaces the directory part of a path with <VALUE> and returns the new path
RESULT2_dir = $(MY_SOURCE:dir=/Developer/SharedFrameworks)

/Developer/SharedFrameworks/DVTFoundation.framework
  • file=<VALUE>: Replaces the filename part of a path and returns the new path
RESULT2_file = $(MY_SOURCE:file=my_file.txt)

/Applications/Xcode.app/Contents/Frameworks/../SharedFrameworks/my_file.txt
  • base=<VALUE>: Replaces the filename base part of a path (=filename without suffix/extension) and returns the new path
RESULT2_base = $(MY_SOURCE:base=Dummy)

/Applications/Xcode.app/Contents/Frameworks/../SharedFrameworks/Dummy.framework
  • suffix=<VALUE>: Replaces the filename extension/suffix a path and returns the new path
RESULT2_suffix = $(MY_SOURCE:suffix=.txt)

/Applications/Xcode.app/Contents/Frameworks/../SharedFrameworks/DVTFoundation.txt

I hope this list will help more people looking at Xcodes build settings and wondering how they can be transformed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ivan Vučica
Solution 2 Ben Lachman
Solution 3 Kazuki Sakamoto
Solution 4