问题
Im trying to run the following command on XCode adding it as a C/C++ Flags to I can get the build number coming from a shell script that is executed at the run script phase of my project.
This work fine with GCC on another Unix like system:
-D__BUILD_VERSION=$(cat build_number)
And ok XCode Im trying to use the following:
-D__BUILD_VERSION=$(cat $PROJECT_DIR/build_number)
But it doesn't work, what Im I doing wrong? In XCode, how can I assign the result of cat build_number to the __BUILD_VERSION defined variable?
回答1:
if you are trying to set that value in the Xcode compile build-phase, you may run into trouble, as i don't know that any interpretive operation takes place with the settings you are trying to set up the way you are trying to set them up.
for auto-setting the version number, i have a much more complex semi-auto-version and auto-numbering scheme so i don't have to remember to change either, or so i can give a version-number i want but always increment the build number, and in both cases, it will put the build number in the About box in the app-settings that are displayed in the iOS system settings.
you may not need much of any of it, but there are a couple of tricks for getting and writing information that you may find useful and may lead to a solution for your problem.
the following scripts were inspired by a stack-overflow answer for how to do this that i can't find at the moment. i put in a bit more work, because (a) i want the version number to show up in the settings displayed in system settings; and (b) Xcode caches the contents of the Info.plist file, so doing this is not nearly as simple as i would have expected.
in a build phase that comes before compile, i run the following (with Run script only when installing unchecked)
sh xolawareStashProductSettings.sh
the contents of xolawareStashProductSettings.sh check the git status of the info.plist file, and if not clean, stash it aside temporarily for later restoration.
#!/bin/sh
#
# should be run prior to the Copy Bundle Resources step
# and prior to any version information modifier scripts
INFOPLIST_GIT_PATH=${PROJECT}/`basename ${INFOPLIST_FILE}`
echo "-- Temp Hold ${INFOPLIST_GIT_PATH} Script --"
set -e
# a fallback in case the user has made changes to the file
if [ `git status --porcelain ${INFOPLIST_GIT_PATH} ]|wc -l` -gt 0 ]; then
echo cp -p ${INFOPLIST_GIT_PATH} ${TARGET_TEMP_DIR}
cp -p ${INFOPLIST_GIT_PATH} ${TARGET_TEMP_DIR}
fi
script #2 (with Run script only when installing unchecked):
sh xolawareStashSettingsBundleRootPlist.sh
the contents of xolawareStashSettingsBundleRootPlist.sh are similar to the contents of script 1.
#!/bin/sh
#
# should be run prior to the Copy Bundle Resources step
# and prior to any version information modifier scripts
echo '-- Temp Hold Settings.bundle/Root.plist Script --'
ROOT_PLIST=${PROJECT}/Resources/Settings.bundle/Root.plist
set -e
# a fallback in case the user has made changes to the file
if [ `git status --porcelain ${ROOT_PLIST} ]|wc -l` -gt 0 ]; then
echo cp -p ${ROOT_PLIST} ${TARGET_TEMP_DIR}
cp -p ${ROOT_PLIST} ${TARGET_TEMP_DIR}
fi
script #3 (with Run script only when installing checked)
sh xolawareIncrementProductSettingsBuildNumber.sh
the contents of xolawareIncrementProductSettingsBuildNumber use plistbuddy to see what it is and bump it by one:
#!/bin/sh
#
# this should be prior to xolawareAboutInfoVersionInfoInSettings.sh
echo "-- Auto-Increment ${INFOPLIST_FILE} Build Version Install Script --"
PLISTBUDDYCMD="/usr/libexec/PlistBuddy -c"
CONFIGURATION_BUILD_SETTINGS_PATH=${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}
CFBV=$(${PLISTBUDDYCMD} "Print :CFBundleVersion" ${PRODUCT_SETTINGS_PATH})
if [[ "${CFBV}" == "" ]]; then
echo "No build number in ${PRODUCT_SETTINGS_PATH}"
exit 2
fi
CFBV=$(expr $CFBV + 1)
set -e
echo ${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${PRODUCT_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${PRODUCT_SETTINGS_PATH}"
echo ${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleVersion $CFBV" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
script #4 (with Run script only when installing unchecked)
sh xolawareProductSettingsShortVersion-from-git.sh
sh xolawareAboutInfoVersionInfoInSettings.sh
the contents of xolawareProductSettingsShortVersion-from-git rely a little on me tagging my branch in git appropriately, but if i forget, it will use the number of commits since the last commit to auto-version my build for me.
#!/bin/sh
#
# this should be run after xolawareStashSettingsBundleRootPlist.sh
# and prior to xolawareAboutInfoVersionInfoInSettings.sh
echo '-- Get Product Settings Short Version String from git describe --'
PLISTBUDDYCMD="/usr/libexec/PlistBuddy -c"
CONFIGURATION_BUILD_SETTINGS_PATH=${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}
CFBVS=`git describe|awk '{split($0,a,"-"); print a[1]}'`
CFBVSI=`git describe|awk '{split($0,a,"-"); print a[2]}'`
if [[ "$CFBVSI" != "" ]]; then
CFBVS=${CFBVS}.${CFBVSI}
fi
set -e
echo ${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${PRODUCT_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${PRODUCT_SETTINGS_PATH}"
echo ${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
${PLISTBUDDYCMD} "Set :CFBundleShortVersionString $CFBVS" "${CONFIGURATION_BUILD_SETTINGS_PATH}"
the contents of xolawareAboutInfoVersionInfoInSettings.sh place the contents in the About box in my Root.plist like i want. it relies on the About box being the first thing in your Root.plist of your settings.bundle:
#!/bin/sh
#
# this should be invoked after xolawareStashInfoAndRootPlist.sh,
# xolawareIncrementProductSettingsBuildNumber.sh and
# xolawareProductSettingsShortVersion-from-git.sh, and before
# the regular Copy Bundle Resources Build Phase
echo '-- Auto-Insert Version Info In System Settings Script --'
PLISTBUDDYCMD="/usr/libexec/PlistBuddy -c"
ROOT_PLIST=${PROJECT_DIR}/${PROJECT}/Resources/Settings.bundle/Root.plist
CFBSVS=`exec -c ${PLISTBUDDYCMD} "Print :CFBundleShortVersionString" ${PRODUCT_SETTINGS_PATH}`
CFBV=`exec -c ${PLISTBUDDYCMD} "Print :CFBundleVersion" ${PRODUCT_SETTINGS_PATH}`
set -e
echo ${PLISTBUDDYCMD} "Set :PreferenceSpecifiers:1:DefaultValue '${CFBSVS} (b${CFBV})'" ${ROOT_PLIST}
${PLISTBUDDYCMD} "Set :PreferenceSpecifiers:1:DefaultValue '${CFBSVS} (b${CFBV})'" ${ROOT_PLIST}
there are also a couple of cleanup scripts to be run after the Compile, Link & Copy bundle resources phases
sh xolawareStashRestoreSettingsBundleRootPlist.sh
this may not be necessary, but i adjust other items in the Root.plist for release builds, so this restores those settings for debug builds.
#!/bin/sh
#
# should be run as the second to last script in Build Phases, after the Copy Bundle Resources Phase
echo "-- Manual Restore $INFOPLIST_FILE Script --"
ROOT_PLIST=${PROJECT}/Resources/Settings.bundle/Root.plist
set -e
# first, see if it was stashed earlier due to uncommitted changes
if [ -e ${TARGET_TEMP_DIR}/Root.plist ]; then
echo mv ${TARGET_TEMP_DIR}/Root.plist ${ROOT_PLIST}
mv ${TARGET_TEMP_DIR}/Root.plist ${ROOT_PLIST}
# the better option when available: restore to the pristine state
elif [ `git status --porcelain ${ROOT_PLIST}|wc -l` -gt 0 ]; then
echo git checkout -- ${ROOT_PLIST}
git checkout -- ${ROOT_PLIST}
fi
and finally, the step to auto-tag the git repo if i haven't already tagged the item just now myself:
sh xolawareProductSettings-git-commit-and-tag.sh
#!/bin/sh
#
# this should be run after xolawareAboutInfoVersionInfoInSettings.sh
# and xolawareProductSettingsShortVersion-from-git.sh
echo "-- ${INFOPLIST_FILE} git commit & tag Install Script --"
SCRIPT_VERSION=`/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' ${INFOPLIST_FILE}`
SCRIPT_BUILD_NUMBER=`/usr/libexec/Plistbuddy -c 'Print :CFBundleVersion' ${INFOPLIST_FILE}`
if [ `git status --porcelain ${SCRIPT_INFO_PLIST}|wc -l` -gt 0 ]; then
echo git commit -m '"'version ${SCRIPT_VERSION} build ${SCRIPT_BUILD_NUMBER}'"' ${INFOPLIST_FILE}
git commit -m "version ${SCRIPT_VERSION} build ${SCRIPT_BUILD_NUMBER}" ${INFOPLIST_FILE}
fi
echo git tag -f ${SCRIPT_VERSION}
git tag -f -F /dev/null ${SCRIPT_VERSION}
回答2:
Try:
-D__BUILD_VERSION=`cat $PROJECT_DIR/build_number`
Note the "backticks" - they're not regular single quote characters.
回答3:
One possibility might be to have the first script put the build number into an environment variable? Not sure if that would work but it might.
来源:https://stackoverflow.com/questions/14680025/xcode-c-c-flags-bash-script