Skip to content

Instantly share code, notes, and snippets.

@csknns
Last active November 19, 2022 08:06
Show Gist options
  • Save csknns/788c99e0ce89f30c27c0d2305d2729b1 to your computer and use it in GitHub Desktop.
Save csknns/788c99e0ce89f30c27c0d2305d2729b1 to your computer and use it in GitHub Desktop.
Xcode build phase script to preprocess a plist file
#!/usr/bin/env bash
# Add this to a custom build phase script to enable preprocessing plist files.
#
# This takes as input all the input files from the build phase script
# and runs the preprocessor using the token definitions from the GCC_PREPROCESSOR_DEFINITIONS
# enviroment variable.
#
# This allows you to have the following plist:
#
# <dict>
# <key>SomeKey</key>
# #ifdef SOME_TOKEN
# <string>SomeValueA</string>
# #else
# <string>SomeValueB</string>
# #endif
#
# This script will keep either `<string>SomeValueA</string>` or `<string>SomeValueB</string>`
# and strip all the preprocessor commands
set -a
process_plist_file() {
local inputfile="${1}"
local outputfile="${2}"
# unifdef will exit with exit code 1 if no replacement is done
/usr/bin/unifdef -t $unifdef_symbols_options -o "$outputfile" "$inputfile" >&2> /dev/null
tempfile=$(mktemp)
/usr/bin/unifdefall "$outputfile" > "${tempfile}.plist" 2> /dev/null
}
export -f process_plist_file
# Type a script or drag a script file from your workspace to insert its path.
# You can also use the ACTIVE_COMPILATION_CONDITIONS here
preprocessor_definitions=$GCC_PREPROCESSOR_DEFINITIONS
echo "preprocessor definitions ${preprocessor_definitions}"
unifdef_symbols_options=""
for definition in $preprocessor_definitions; do
unifdef_symbols_options="-D${definition} ${unifdef_symbols_options}"
done
COUNTER=0
while [ $COUNTER -lt "$SCRIPT_INPUT_FILE_COUNT" ]; do
tmpinput="SCRIPT_INPUT_FILE_$COUNTER"
INPUTFILE=${!tmpinput}
tmpoutput="SCRIPT_OUTPUT_FILE_$COUNTER"
OUPTUTFILE=${!tmpoutput}
# if given input file is .bundle, process all .plist files inside it.
if [[ $INPUTFILE =~ -template\.bundle$ && -d $INPUTFILE ]]; then
rm -rf "${OUPTUTFILE}" || true
cp -r "${INPUTFILE}" "${OUPTUTFILE}"
# Process each .plist inside bundle
find ${INPUTFILE} -type f -name '*.plist' -exec /bin/bash -c 'process_plist_file "$0" "${0/$INPUTFILE/$OUPTUTFILE}"' {} \;
elif [[ $INPUTFILE =~ -template\.plist$ && -f $INPUTFILE ]]; then
rm -f "${OUPTUTFILE}" || true
process_plist_file "$INPUTFILE" "$OUPTUTFILE"
else
echo "Error: Unknown input file \"$INPUTFILE\" type/format. Input files should have the following pattern: Info-XYZ-template.plist or XYZ-template.bundle"
exit 1
fi
(( COUNTER=COUNTER+1 ))
done
set +a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment