Xcode 4无法从静态库依赖项中找到公共头文件

rjs*_*ing 91 preprocessor header static-libraries xcode4

替代标题以帮助搜索

  • Xcode找不到标题
  • 在Xcode中缺少.h
  • 找不到Xcode .h文件
  • 未找到词法或预处理器问题文件

我正在开发一个来自Xcode 3的iOS应用程序项目.我现在已经转移到Xcode 4,我的项目构建了许多静态库.

这些静态库还声明了公共头文件,这些头文件由应用程序代码使用.在Xcode 3.x中,标题被复制(作为构建阶段)public headers directory,然后在应用程序项目中public headers directory被添加到headers search list.

在Xcode 4下,构建目录被移动到~/Library/Developer/Xcode/DerivedData/my-project.

问题是我如何在标题搜索设置中引用这个新位置?看起来:

  • public headers directory是相对于DerivedData目录,但是
  • headers search 目录是相对于其他东西(可能是项目位置)

我应该如何在Xcode 4中为iOS开发设置静态库目标,以确保在尝试编译为依赖项时,使用静态库的客户端可以使用头文件?

Col*_*lin 125

我在这个问题上看到的每个解决方案要么看起来不够优雅(将标题复制到应用程序的项目中),要么过度简化,以至于它们只能在琐碎的情况下工作.

简短的回答

将以下路径添加到用户标头搜索路径

"$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts"

为什么这样做?

首先,我们需要了解这个问题.在正常情况下,也就是说当您运行,测试,配置文件或分析时,Xcode构建您的项目并将输出放在Build/Products/Configuration/Products目录中,该目录可通过$ BUILT_PRODUCTS_DIR宏获得.

大多数有关静态库的指南建议将公共标题文件夹路径设置为$ TARGET_NAME,这意味着您的lib文件变为$ BUILT_PRODUCTS_DIR /libTargetName.a,并且您的标题将放入$ BUILT_PRODUCTS_DIR/TargetName.只要您的应用在其搜索路径中包含$ BUILT_PRODUCTS_DIR,那么导入将在上面给出的4种情况下起作用.但是,当您尝试存档时,这将不起作用.

存档的工作方式略有不同

存档项目时,Xcode使用名为ArchiveIntermediates的其他文件夹.在该文件夹中,您将找到/ YourAppName/BuildProductsPath/Release-iphoneos /.这是$ BUILT_PRODUCTS_DIR在您进行存档时指向的文件夹.如果你查看那里,你会看到你的内置静态库文件有一个符号链接但是缺少带有头文件的文件夹.

要查找标头(和lib文件),您需要转到IntermediateBuildFilesPath/UninstalledProducts /.还记得当你被告知将静态库的Skip Install设置为YES时吗?那么这就是您进行存档时设置的效果.

附注:如果您没有将其设置为跳过安装,您的标题将被放入另一个位置,并且lib文件将被复制到您的存档中,从而阻止您导出可以提交到App Store的.ipa文件.

经过大量搜索后,我找不到任何与UninstalledProducts文件夹完全对应的宏,因此需要使用"$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts"构建路径

摘要

对于您的静态库,请确保您跳过安装并将公共标题放入$ TARGET_NAME.

对于您的应用,将用户标题搜索路径设置为"$(BUILT_PRODUCTS_DIR)",这适用于常规版本,"$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts",适用于存档版本.

  • 请注意,*$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts*实际上是`$(TARGET_BUILD_DIR)`.即使在存档时.;) (7认同)
  • 对我来说,使用带有递归复选框的"$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts"不起作用.只要我使用"$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts/<nameOfStaticLibrary>"而没有递归标记,它就适用于我. (3认同)

gda*_*vis 85

我在开发自己的静态库时遇到了同样的问题,尽管Colin的回答非常有用,但我不得不修改它以便一致地工作,只需在使用工作区在Xcode 4下运行和归档项目时.

我的方法有什么不同,您可以为所有构建配置使用单个用户标头路径.

我的方法如下:

创建工作区

  1. 在Xcode 4下,转到File,New,Workspace.
  2. 然后,您可以从Finder中将.xcodeproj项目拖入要使用的静态库和正在构建的使用该库的新应用程序中.有关设置工作区的详细信息,请参阅Apple Docs:https://developer.apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Workspace.html

静态库项目设置

  1. 确保将所有静态库的标头设置为"Public".这是在静态库目标>构建阶段的设置下完成的.在"复制标题"阶段,确保所有标题都在"公共"部分中.
  2. 接下来转到Build Settings,找到"Public Headers Folder Path"并输入库的路径.我选择使用这个:

包括/库名称

我已经使用它与RestKit一起使用,发现它最适合我的所有静态库.这样做是告诉Xcode将我们移动到步骤1中"Public"标题部分的所有标题复制到我们在此处指定的文件夹,该文件夹在构建时位于Derived Data文件夹中.与RestKit一样,我喜欢使用单个"include"文件夹来包含我在项目中使用的每个静态库.

我也不喜欢在这里使用宏,因为它允许我们稍后在使用静态库配置项目时使用单个用户头搜索路径.

  1. 找到"跳过安装"并确保将其设置为YES.

使用静态库的项目设置

  1. 在Build Phases> Link Binary With Libraries下添加静态库作为框架,并为要使用的静态库添加libLibraryName.a文件.
  2. 接下来,确保将项目设置为搜索用户搜索路径.这是在Build Settings> Always Search User Paths下完成的,并确保将其设置为YES.
  3. 在同一区域找到用户标题搜索路径并添加:

    "$(PROJECT_TEMP_DIR)/../ UninstalledProducts /包括"

这告诉Xcode在构建过程中Xcode创建的中间构建文件夹中查找静态库.在这里,我们有"include"文件夹,我们用于我们在步骤2中为静态库项目设置设置的静态库位置.这是让Xcode正确查找静态库的最重要步骤.

配置工作区

在这里,我们要配置工作区,以便在构建应用程序时构建静态库.这是通过编辑用于我们的应用程序的方案来完成的.

  1. 确保选择了将创建应用程序的方案.
  2. 从方案下拉列表中,选择"编辑方案".
  3. 选择左侧列表顶部的Build.按中间窗格上的+添加新目标.
  4. 您应该看到静态库显示您尝试链接的库.选择iOS静态库.
  5. 单击"运行"和"存档".这告诉方案在构建应用程序时编译静态库的库.
  6. 将静态库拖到应用程序目标上方.这使得静态库在应用程序目标之前进行编译.

开始使用库

现在,您应该能够使用导入静态库

import <LibraryName/LibraryName.h>
Run Code Online (Sandbox Code Playgroud)

这种方法避免了为不同的配置设置不同的用户头路径的麻烦,因此编译档案时应该没有问题.

为什么这样做?

这一切都取决于这条道路:

"$(PROJECT_TEMP_DIR)/../UninstalledProducts/include"
Run Code Online (Sandbox Code Playgroud)

因为我们将静态库配置为使用"跳过安装",所以编译的文件将移动到临时构建目录中的"UninstalledProjects"文件夹中.我们的路径也解析为我们为静态库设置的"include"文件夹,并用于我们的用户头搜索路径.这两个一起工作让Xcode知道在编译过程中在哪里找到我们的库.由于此临时构建目录同时存在于Debug和Release配置中,因此Xcode只需要一个路径即可搜索静态库.

  • 你很棒,伙计!这非常有用,它可以像你描述的那样工作. (3认同)

rjs*_*ing 16

Xcode 4 Project无法编译静态库

相关问题:Xcode 4中"未找到词法或预处理器问题文件"

错误可能包括; 丢失头文件,"词法或预处理器问题"

解决方案:

  1. 检查"用户标题路径"是否正确
  2. 将"始终搜索用户路径"设置为YES
  3. 在项目中创建一个组调用"索引标题"并将标题拖到该组,在提示时不要添加到任何目标.

  • 另一个容易被忽视但非常重要的步骤:确保您的搜索路径用双引号括起来以逃避任何空格.我总是忘记那样做. (11认同)

小智 15

这是一个非常有用的线程.在研究我自己的情况时,我发现Apple有一份12页的文件,标题为"在iOS中使用静态库".这是pdf链接:http://developer.apple.com/library/ios/technotes/iOSStaticLibraries/iOSStaticLibraries.pdf

它比大多数互联网讨论简单得多,并且通过一些小的mod来说明我正在使用的外部库是如何配置的,它对我来说很有用.最重要的部分可能是:

如果您的库目标具有"复制标题"构建阶段,则应将其删除; 在Xcode中执行"归档"操作时,复制标头构建阶段无法与静态库目标一起正常工作.

使用Xcode 4.4或更高版本创建的新静态库目标将为头文件提供适当配置的"复制文件"阶段,因此您应该在创建一个之前检查是否已有一个.如果不这样做,请按目标编辑器底部的"添加构建阶段",然后选择"添加复制文件".公开新的"复制文件"构建阶段并将"目标"设置为"产品目录".将子路径设置为包含/ $ {PRODUCT_NAME}.这会将文件复制到以库命名的文件夹(取自PRODUCT_NAME构建设置),位于构建产品目录中名为include的文件夹中.build products目录中的include文件夹位于应用程序的默认头搜索路径中,因此这是放置头文件的合适位置.

我相信在许多现有情况下,Apple的方法可能还不够.我在这里发布这个版本给那些刚开始他们在静态图书馆花园路径上旅行的人 - 这可能是简单案例的最佳起点.