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

时间:2011-04-04 20:18:05

标签: xcode4 header preprocessor static-libraries

  

辅助搜索的替代标题

     
      
  • 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 directoryDerivedData目录相关,但
  • headers search目录与其他内容相关(可能是项目位置)

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

17 个答案:

答案 0 :(得分:125)

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

简短回答

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

  

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

为什么这样做?

首先,我们需要了解这个问题。在正常情况下,也就是说当您运行,测试,配置文件或分析时,Xcode构建您的项目并将输出放在Build / Products / Configuration / Products目录中,该目录可通过< strong> $ 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 /。还记得当你被告知为静态库设置跳过安装为YES时?那么这就是您进行存档时设置的效果。

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

经过大量搜索后,我无法找到与UninstalledProducts文件夹完全对应的宏,因此需要使用&#34; $(BUILD_ROOT)/../ IntermediateBuildFilesPath / UninstalledProducts&#构建路径34;

摘要

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

对于您的应用,请将用户标题搜索路径设置为&#34; $(BUILT_PRODUCTS_DIR)&#34;,这适用于常规版本,&#34; $(BUILD_ROOT)/../ IntermediateBuildFilesPath / UninstalledProducts& #34;,适用于存档构建。

答案 1 :(得分:85)

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

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

我的方法如下:

创建工作区

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

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

      包括/库名称

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

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

      1. 找到“跳过安装”并确保将其设置为“是”。
      2. 使用静态库的项目设置

        1. 在Build Phases&gt;下添加静态库作为框架。链接Binary With Libraries并为您要使用的任何静态库添加libLibraryName.a文件。
        2. 接下来确保将项目设置为搜索用户搜索路径。这是在Build Settings&gt;下完成的。始终搜索用户路径并确保将其设置为YES。
        3. 在同一区域找到用户标题搜索路径并添加:

          “$(PROJECT_TEMP_DIR)/../ UninstalledProducts /包括”

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

          配置工作区

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

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

            现在,您应该能够使用

            导入静态库
            import <LibraryName/LibraryName.h>
            

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

            为什么这样做?

            这完全取决于这条道路:

            "$(PROJECT_TEMP_DIR)/../UninstalledProducts/include"
            

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

答案 2 :(得分:16)

Xcode 4 Project无法编译静态库

  

相关问题:“lexical or preprocessor issue file not found ” in Xcode 4

错误可能包含; 缺少标题文件,“词汇或预处理程序问题”

解决方案:

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

答案 3 :(得分: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产品目录中的include文件夹是默认的   应用程序的标头搜索路径,因此这是一个合适的地方   放头文件。

我确信在许多现有情况下,Apple的方法可能还不够。我在这里发布这篇文章给那些刚刚开始他们在静态库花园路径上旅行的人 - 这可能是简单案例的最佳起点。

答案 4 :(得分:4)

http://developer.apple.com/library/ios/#technotes/iOSStaticLibraries/Articles/creating.html

每个Apple文档:

您的库将有一个或多个头库文件,该库的客户端需要导入。要配置导出到客户端的标头,请选择库项目以打开项目编辑器,选择库目标以打开目标编辑器,然后选择构建阶段选项卡。如果您的库目标具有“复制标题”构建阶段,则应将其删除;在Xcode中执行“归档”操作时,复制标头构建阶段无法与静态库目标一起正常工作。

答案 5 :(得分:3)

看看Jonah Wlliam的解决方案(中途向下)&amp; GitHub模型(在评论中)以获得洞察力。 http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/

答案 6 :(得分:2)

$(OBJROOT)/ UninstalledProducts / exactPathToHeaders 添加到标题搜索路径。

由于某种原因,递归复选框对我不起作用,我不得不将其余路径添加到标题所在的位置。

在Xcode中的日志导航器(断点导航器右侧的选项卡)下,您可以看到构建历史记录。如果您选择实际的构建失败,您可以展开其详细信息以查看 setenv PATH ,并检查以确保您的头文件的路径在那里。

答案 7 :(得分:2)

在我的情况下,我的工作区有几个静态库项目,其中一个具有依赖项,包括头文件与另一个。问题在于建筑的顺序。在Build部分下的编辑Scheme页面中,我取消选择了parallelize选项,并根据依赖关系安排了目标的顺序,并通过问题解决了

答案 8 :(得分:1)

冒着显示我是个白痴的风险......我一直在遭受XCode整个下午拒绝找到我的.h文件的痛苦。

然后我意识到了。

因为我使用的是“XCode 4”,所以我“聪明地”决定将所有项目放在名为“ XCode 4项目”的文件夹的子文件夹中。

文件夹名称中的那些空格搞乱了XCode!

将此文件夹重命名为“ XCode_4_Projects ”,这让我的生活更加快乐(而且不那么咒骂)。

再次提醒我,这是什么年?

也许有人可以告诉Apple开发人员......

答案 9 :(得分:1)

上面的答案都没有在Xcode 7上为我工作,但他们给了我一个好主意。对于在Xcode 7上苦苦挣扎的家伙,我通过将以下内容添加到用户标题搜索路径(包括引号)来解决此问题

"$(BUILT_PRODUCTS_DIR)/usr/local/include"

根据公共标题文件夹路径&#39;中的内容更改相对网址部分usr/local/include。设置静态库

答案 10 :(得分:1)

这些答案都不适合我。这是做了什么的。准确添加以下内容(复制并粘贴包括双引号)到用户标题搜索路径构建设置:

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

注意添加&#34; / include /&#34;子目录与其他答案相比。正如其他用户所指出的那样,&#34;递归&#34;选项似乎没有做任何事情,所以你可以忽略它。

我的项目现在能够以下列形式导入静态库头文件时成功存档:

#import "LibraryName/HeaderFile.h"

需要启用始终搜索用户路径设置,除非您的静态库标题包含尖括号(#import <LibraryName/HeaderFile.h>),但是如果它不是系统/框架标题,那么无论如何都不应该这样做。

答案 11 :(得分:1)

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

$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts

这已经过验证!

答案 12 :(得分:0)

这是一个相关的问题,导致我提出这个问题所以我正在严格地为文档添加我的解决方案/它可以节省另一个灵魂出汗的时间

找不到

DropboxSDK.h文件

经过几天试图让VES为iOS编译后,我终于遇到了这个问题。 DropboxSDK.h绝对可以达到search headers我甚至将其添加到framework headers搜索路径,include d .h直接转到各种各样的尝试找到DropboxSDK.h的长度。

解决方案

展开DropboxSDK.framework文件拖到Xcode的Project Navigation中,并确保选中Copy Files if needed。还要确保根据需要检查目标。

警告

build phases中设置显式框架位置对我来说不起作用。我不得不将.framework 拖放到Xcode中并确保将文件复制到我的项目中。

#mbp2015#xcode7#ios9

答案 13 :(得分:0)

有各种复杂的方法可以做到这一点,并且在这个帖子中提出了一些非常聪明的解决方案。

所有这些解决方案的主要问题是它严重降低了您的库可移植性。

  • 每次您需要使用您的库启动一个新项目并将其存档为iTunes, 这是一个配置地狱。
  • 每次您需要分享您的项目 与您的团队或客户一起,它可以因任何原因而中断(上下文, Xcode版本,无论如何,..)

我最终选择使用框架 - 总是 - 按照Apple(WWDC Videos)的推荐使用。

它更容易,最后做同样的工作!

另一个相当优雅的解决方案似乎是使用Private Cocoapods。 Cocoapods完成所有配置工作,标题副本等。

框架摇滚!

答案 14 :(得分:0)

这就是为我解决同样问题的原因。

我有一个App Target和一个iMessage扩展目标。 然后我有2个SDK(我自己的),App Target链接。

问题是:我的iMessage目标也使用了我的2个SDK(单独的项目),但它没有在Build Phases中与它们链接 - &gt;链接二进制文件库。我必须将我的2个SDK添加到那里的iMessage目标,以匹配我的App目标,现在归档。

故事的寓意是:如果您有多个目标,例如扩展,请确保所有目标都链接到他们需要的库。它能够构建和部署到模拟器和设备,但不能存档。

答案 15 :(得分:0)

更新:Xcode 9

以上答案对我使用Xcode 9不起作用,但这个answer对我来说非常适合。我已将$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include添加到我的&#34;标题搜索路径&#34;和Xcode确实链接了我的静态库的标题。

答案 16 :(得分:-17)

省去麻烦并执行此操作=在Mac上创建新用户帐户 - 在新用户帐户下打开项目 - 所有问题都会消失。节省您的时间,保持理智。所有那些书呆子的回复都没有帮助!!

祝你好运