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

时间:2011-12-13 21:34:01

标签: xcode build-rules

我有一个包含大量目标的Xcode项目,我希望在Ad-hoc和Debug配置下构建应用程序的设置包,但不包括Release配置。

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

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

我启动的构建规则将Process设置设置为“Source files with names matching:”,Settings.bundle作为名称。 “使用”设置为“自定义脚本:”。

我的自定义脚本如下(需要注意我的bash脚本是在货物崇拜级别上):

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

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

因为我在这里,显然它不起作用。我的第一个问题是,是否有某个地方我可以将构建规则的输出视为执行,以确保1)它实际上正在执行,以及2)我在某处没有愚蠢的语法错误。

此外,将输出复制到?

的正确位置(以环境变量的形式)是什么?

6 个答案:

答案 0 :(得分:75)

我终于明白了。

对于要有条件地包含设置包的每个目标,从源列表中选择其项目,选择目标,然后切换到“构建阶段”选项卡。

单击“添加构建阶段”按钮,然后选择“添加运行脚本”。

然后为脚本输入以下内容:

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

答案 1 :(得分:44)

我知道这个问题已经得到了解答,答案对我很有帮助,但我也想把自己修改过的解决方案也放在那里。

我的要求是为不同的构建配置提供不同的设置包,而不是仅在发布时不包含它。假设只有 Debug Release 配置的简单方法,这里是如何做到的:

首先向项目添加2个设置包,名为Settings-debug.bundleSettings-release.bundle,然后从复制包资源构建阶段中删除这些文件。接下来添加一个名为SETTINGS_BUNDLE的用户定义构建设置,该设置对每个配置都有不同的值:

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

接下来,在Frank的解决方案中添加一个名为复制设置包的运行脚本构建阶段(带有复制设置包)和修改后的脚本版本。

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

这里的区别在于,无论源名称如何,复制的包总是以 Settings.bundle 命名。

然后,您需要添加另一个构建阶段脚本,以防止在设置包中发生唯一更改时出现代码签名错误。它强制代码签名步骤在每个构建上发生。这应该在 编译源文件构建阶段之前运行。我打电话给我 Force Codesign

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

答案 2 :(得分:21)

对于已编译的来源,可以添加一个记录不明的用户定义构建设置。文件可以被排除并包含在编译中

转到目标的构建设置>点按+按钮>添加用户定义的设置

密钥为INCLUDED_SOURCE_FILE_NAMESEXCLUDED_SOURCE_FILE_NAMES

该值是以空格分隔的文件路径列表

参见参考: http://lists.apple.com/archives/xcode-users/2009/Jun/msg00153.html

答案 3 :(得分:7)

无论是Release还是Debug配置,都会将Settings.bundle复制到目标区域。所以,也许你需要以下代码:

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

答案 4 :(得分:3)

我不是shell脚本专家,但我认为你需要方括号和条件之间的空格。另外,引用变量可能会有所帮助:

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

至于位置,我使用"$BUILT_PRODUCTS_DIR"/"$FULL_PRODUCT_NAME"作为我的OS X应用程序包的根目录。

答案 5 :(得分:2)

(使用 Xcode 9.3 进行测试)

我无法找到Xcode何时包含此功能,但EXCLUDED_SOURCE_FILE_NAMES现在可以直接使用Build Settings > Build Options > Excluded Source File Names

因此,您不再需要创建User-Defined Setting

见下文: enter image description here

它会自动在.pbxproj中添加此行。 enter image description here