我的 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 中检查):

  1. 为每个相关目标添加 USE_HEADERMAP = NO 的自定义构建设置。具体方法如下:
    1.1.在“构建”窗格中打开目标的信息面板。
    1.2.下拉窗口左下方的操作弹出菜单,选择“添加用户定义的设置”。
    1.3.在新添加的行中,将第一列(“设置”)设置为 USE_HEADERMAP, ,第二列(“值”) NO.

  2. 将正确的包含路径添加到每个目标(目标构建设置“标题搜索路径”)。在我的例子中,这将是:
    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}/**

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top