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


77

我有一个带有大量目标的Xcode项目,我想在其中包含针对在Ad-hoc和Debug配置下(而不在Release配置下)构建的应用程序的设置包。

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

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

我已经开始的构建规则将“处理”设置设置为“名称匹配的源文件:”,并将Settings.bundle设置为名称。使用设置为“自定义脚本:”。

我的自定义脚本如下(需要注意的是,我的bash脚本是在“邪教”级别上执行的):

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

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

由于我在这里,因此很明显它没有工作。我的第一个问题是,是否可以在某处查看构建规则的输出,以确保1)它实际上正在执行,以及2)我在某处没有愚蠢的语法错误。

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

Answers:


83

我终于弄明白了。

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

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

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

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

2
谢谢,我已经习惯了针对不同配置来管理Firebase项目plist文件的方法。
iCoder

44

我知道这个问题已经回答了,这个回答对我非常有帮助,但是我也想把自己的修改过的解决方案扔在那里。

我的要求是为不同的构建配置提供不同的设置包,而不是在发布时不包括它。假设仅采用“调试”和“发布”配置的简单方法,请按以下步骤操作:

加入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的解决方案中添加一个名为Copy Settings Bundle的运行脚本构建阶段(在Copy Bundle Resources之后),并添加脚本的修改版本。

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

此处的区别在于,无论源名称如何,复制的捆绑包始终始终命名为Settings.bundle

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

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

1
内置设置应用程序中仅调试应用程序首选项窗格的绝佳解决方案,这正是我所追求的。非常感谢你!
benvolioT 2014年

4
您还可以编写:cp -r“ $ {PROJECT_DIR} / settings_bundle / Settings-$ {CONFIGURATION} .bundle /”“ $ {BUILT_PRODUCTS_DIR} / $ {PRODUCT_NAME} .app / Settings.bundle”这将使您避免添加任何内容用户定义的构建条目,并将使用文件“ settings_bundle / Settings-Debug.bundle”,“ settings_bundle / Settings-Release.bundle”等
Kashif Hisam 2014年

作为SETTINGS_BUNDLE变量,我使用了$ {PROJECT_DIR} / $ {PROJECT_NAME} /Resources/Settings.bundle
Johan

1
并且,无需在“复制捆绑资源”构建阶段中查找要删除的文件,只需在“文件”检查器中删除捆绑文件的任何目标成员身份即可。快点
约翰,

26

对于合规的源代码,可以添加记录不充分的用户定义的构建设置。文件可以从编译中排除和包含

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

关键是无论是INCLUDED_SOURCE_FILE_NAMESEXCLUDED_SOURCE_FILE_NAMES

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

请参阅参考资料:http : //lists.apple.com/archives/xcode-users/2009/Jun/msg00153.html


1
我可以确认添加EXCLUDED_SOURCE_FILE_NAMES在Xcode 8.2..x
Eli Burke

9

(使用Xcode 9.3测试)

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

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

见下文: 在此处输入图片说明

它将自动将此行添加到您的中.pbxproj在此处输入图片说明


8

无论Release配置还是Debug配置,Settings.bundle总是复制到目标区域。因此,也许您需要以下代码:

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

4

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

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

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


这在构建时给了我语法错误。弗兰克(Frank)的解决方案(复制和粘贴)非常完美。
Lance

1
为了公平起见,这个家伙的答案是三个月前发布的。
小狗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.