控制 Xcode 将包含哪个项目头文件
-
25-09-2019 - |
题
我的 Xcode 项目使用两个目标构建同一产品的变体。两者之间的区别仅在于使用所包含库的版本。对于 .c 源文件,可以使用目标复选框轻松将正确的版本分配给正确的目标。但是,包含的头文件始终包含相同的文件。这对于一个目标是正确的,但对于另一个目标是错误的。
有没有办法控制每个目标包含哪个头文件?
这是我的项目文件层次结构(在 Xcode 中复制):
MyProject
TheirOldLib
theirLib.h
theirLib.cpp
TheirNewLib
theirLib.h
theirLib.cpp
myCode.cpp
myCode.cpp 执行以下操作:
#include "theirLib.h"
…
somecode()
{
#if OLDVERSION
theirOldLibCall(…);
#else
theirNewLibCall(…);
#endif
}
当然,我定义 OLDVERSION
对于一个目标而不是另一个目标。
请注意 #include
必须如图所示。以下两项均失败并出现文件未找到错误:
#include "TheirOldLib/theirLib.h"
#include "TheirNewLib/theirLib.h"
那么有没有办法告诉 Xcode 哪个 theirLib.h
包括每个目标?
限制条件:
- 两个头文件具有相同的名称。作为最后的手段,我可以重命名其中一个,但我宁愿避免这样做,因为这会导致其他平台上的重大问题。
- 必须改变 #include
添加对封闭文件夹的引用也是我宁愿避免的事情,因为我需要使用条件编译指令执行两次。
- 我可以随意调整我的项目,只要我认为合适
谢谢你的帮助。
解决方案
答案的关键部分是按照 Chris 在评论中的建议使用 USE_HEADERMAP = NO 。以下是详细信息。
简短的配方(在 Xcode 3.2.2 中检查):
为每个相关目标添加 USE_HEADERMAP = NO 的自定义构建设置。具体方法如下:
1.1.在“构建”窗格中打开目标的信息面板。
1.2.下拉窗口左下方的操作弹出菜单,选择“添加用户定义的设置”。
1.3.在新添加的行中,将第一列(“设置”)设置为USE_HEADERMAP
, ,第二列(“值”)NO
.将正确的包含路径添加到每个目标(目标构建设置“标题搜索路径”)。在我的例子中,这将是:
2.1.添加TheirOldLib
对于“旧”目标
2.2.添加TheirNewLib
对于“新”目标
步骤1 禁用 Xcode 的自动头映射功能,通过该功能,项目中包含的任何头文件都可以通过其名称直接访问,无论其实际路径如何。当两个标头具有相同的名称时,此功能会导致无法解决的歧义。
第2步 允许 #include "theirLib.h"
无需限定头文件实际路径名即可工作。
这两个步骤一起满足了我的两个限制。
最后, USE_HEADERMAP
是 不是 据我所知,苹果有记录。我将为此填写一份错误报告,因为此设置在许多情况下至关重要,正如谷歌搜索所揭示的那样。报告为 rdar://7840694。也在开放雷达上作为 http://openradar.appspot.com/radar?id=253401
其他提示
USE_HEADERMAP=NO 对于某些项目来说是多余的。仅使用 HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT=NO 就足够了。文档在这里: https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW159
为什么不能在每个目标中使用不同的包含路径?
使用 USE_HEADERMAP=NO 并在“用户标头搜索路径”中首先包含您的自定义目录,然后递归地包含项目目录:${PROJECT_DIR}/theirNewLib ${PROJECT_DIR}/**