如何在 Xcode 有条件地包含基于构建配置的文件?

我有一个拥有大量目标的 Xcode 项目,我想在其中包含一个在 Ad-hoc 和 Debug 配置下构建的应用程序的设置包,但不包含在发布配置下。

构建阶段似乎不允许自己以配置为条件(它们显然可以以目标为条件,但是将项目中的目标数量增加一倍将使其完全无法使用)。

这样就只剩下编写自定义生成规则了。我的计划是从所有目标中排除 Settings.bundle,并创建一个构建规则,有条件地将其复制到产品包中,但是很难找到适用的示例。

我已经启动的构建规则将 Process 设置为“与名称匹配的源文件:”,并将 Settings.bundle 作为名称。Use 设置为“ Custom script:”。

我的自定义脚本如下(注意,我的 bash 脚本处于货物狂热级别) :

if [${CONFIGURATION} = 'Debug'] then
cp -r ${INPUT_FILE_PATH} ${DERIVED_FILES_DIR}/.
fi

最后,我将 ${DERIVED_FILES_DIR}/Settings.bundle列为输出文件。

既然我来了,很明显这不管用。我的第一个问题是,我是否可以在某个地方将构建规则的输出视为执行,以确保1)它实际上正在执行,2)我没有在某个地方出现愚蠢的语法错误。

此外,复制输出的正确位置(以环境变量的形式)是什么?

25883 次浏览

I am no shell script expert but I think you need space between the square brackets and the condition. Also, quoting the variables may help:

if [ "${CONFIGURATION}" = "Debug" ] then
cp -r "${INPUT_FILE_PATH}" "${DERIVED_FILES_DIR}"/.
fi

As for the location, I use "$BUILT_PRODUCTS_DIR"/"$FULL_PRODUCT_NAME" for the root of my OS X app bundle.

I finally figured it out.

For each target for which you want to conditionally include the settings bundle, choose its Project from the source list, choose the target, and switch to the "Build Phases" tab.

Click the "Add Build Phase" button and choose "Add Run Script".

Then enter the following for the script:

if [ "${CONFIGURATION}" == "Debug" ]; then
cp -r "${PROJECT_DIR}/Settings.bundle" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app"
fi

I know this question has been answered already, and the answer was very helpful to me, but I wanted to throw my own modified solution out there as well.

My requirement was to have different settings bundles for different build configurations, rather than just not including it at release. Assuming a simplistic approach of only Debug and Release configurations, here's how to do it:

Start by adding 2 settings bundles to the project, named Settings-debug.bundle and Settings-release.bundle and then remove these files from the Copy Bundle Resources build phase. Next add a user defined build setting called SETTINGS_BUNDLE, which has different values for each configuration:

Debug        ${PROJECT_DIR}/relative/path/to/Settings-debug.bundle
Release      ${PROJECT_DIR}/relative/path/to/Settings-release.bundle

Next add a run-script build phase (after Copy Bundle Resources) named Copy Settings Bundle with a modified version of the script in Frank's solution.

cp -r "${SETTINGS_BUNDLE}/" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle"

The difference here is that the copied bundle is always named Settings.bundle regardless of the source name.

You then need to add another build phase script to prevent code signing errors when the only changes are in the settings bundles. It forces the code signing step to occur on every build. This should run before the Compile Source Files build phase. I called mine Force Codesign.

touch "${PROJECT_DIR}/relative/path/to/main.m"

Settings.bundle is always copied into destination area no matter whether Release or Debug configuration. So, maybe you need the following code:

if [ ${CONFIGURATION} == "Release" ]; then
rm -rf ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle
fi

For complied sources, there is a poorly documented user defined build setting that can be added. Files can be both excluded and included from compilation

Go to your target's Build Settings > Tap the + button > Add User-Defined Setting

The key is either INCLUDED_SOURCE_FILE_NAMES or EXCLUDED_SOURCE_FILE_NAMES

The value is a space separated list of file paths

See reference: http://lists.apple.com/archives/xcode-users/2009/Jun/msg00153.html

(Tested with Xcode 9.3)

I can't find when Xcode included this feature but EXCLUDED_SOURCE_FILE_NAMES is now directly available in Build Settings > Build Options > Excluded Source File Names.

So you no longer need to create a User-Defined Setting.

See below: enter image description here

It will automatically add this line in your .pbxproj. enter image description here