Xcode 4无法从静态库依赖关系find公共头文件
备用标题来帮助search
- Xcode无法find标题
- 在Xcode中缺less.h
- 找不到Xcode .h文件
- 词法或预处理程序问题文件未find
我正在从Xcode 3来的iOS应用程序项目。我现在已经转移到Xcode 4我的项目build立了一些静态库。
那些静态库也声明公共头,这些头被应用程序代码使用。 在Xcode 3.x中,头部被复制(作为构build阶段)到public headers directory
,然后在应用程序项目中, public headers directory
被添加到headers search list
。
在Xcode 4下,构build目录被移动到~/Library/Developer/Xcode/DerivedData/my-project
。
问题是如何在标题search设置中引用这个新位置? 看起来:
-
public headers directory
是相对于DerivedData
目录的,但是 -
headers search
目录是相对于别的东西(可能是项目位置)
我应该如何在Xcode 4中为iOS开发设置一个静态库目标,以确保在试图编译为依赖时,头文件可供使用静态库的客户端使用?
我对这个问题所见到的每个解决scheme都显得不雅(将头文件复制到应用程序的项目中),或者过分简化为只能在微不足道的情况下工作。
简短的回答
将以下path添加到您的用户标题searchpath
“$(BUILD_ROOT)/../ IntermediateBuildFilesPath / UninstalledProducts”
为什么这个工作?
首先,我们需要了解这个问题。 在正常情况下,即运行,testing,configuration文件或分析时,Xcode会构build您的项目,并将输出置于Build / Products / Configuration / Products目录中,该目录可通过$ BUILT_PRODUCTS_DIRmacros获得。
有关静态库的大多数指南build议将公共标题文件夹path设置为$ TARGET_NAME ,这意味着您的lib文件变为$ BUILT_PRODUCTS_DIR /libTargetName.a,并将您的标题放入$ BUILT_PRODUCTS_DIR / TargetName中。 只要您的应用程序在searchpath中包含$ BUILT_PRODUCTS_DIR ,那么导入就可以在上面给出的四种情况下运行。 但是,当您尝试存档时,这不起作用。
存档工作有点不同
归档项目时,Xcode使用一个名为ArchiveIntermediates的不同文件夹。 在该文件夹中,您将find/ YourAppName / BuildProductsPath / Release-iphoneos /。 这是您执行归档时$ BUILT_PRODUCTS_DIR指向的文件夹。 如果你看看那里,你会看到有一个符号链接到你的内置的静态库文件,但缺less头文件夹。
要find标题(和lib文件),您需要转到IntermediateBuildFilesPath / UninstalledProducts /。 记得当你被告知为静态库设置Skip Install为YES吗? 那么这是设置存档时的效果。
注意:如果你不设置它跳过安装,你的头文件将被放到另一个位置,lib文件将被复制到你的压缩文件中,从而阻止你导出一个你可以提交给App Store的.ipa文件。
经过大量search之后,找不到与UninstalledProducts文件夹完全对应的任何macros,因此需要使用“$(BUILD_ROOT)/../ IntermediateBuildFilesPath / UninstalledProducts”构buildpath
概要
对于您的静态库,请确保您跳过安装,并且您的公共头文件被放置在$ TARGET_NAME中。
对于您的应用程序,请将您的用户标题searchpath设置为“$(BUILT_PRODUCTS_DIR)”(适用于常规构build),而“$(BUILD_ROOT)/../ IntermediateBuildFilesPath / UninstalledProducts”适用于归档构build。
我在开发自己的静态库时遇到了同样的问题,尽pipeColin的回答非常有帮助,但我不得不稍微修改它,以便在Xcode 4下使用Workspace运行和归档项目时一致地工作。
我的方法有什么不同之处在于,您可以为所有构buildconfiguration使用单个用户头文件path。
我的方法如下:
创build一个工作区
- 在Xcode 4下,转到文件,新build,工作区。
- 在Finder中,您可以拖放要使用的静态库和使用该库的新build应用程序的.xcodeproj项目。 有关设置工作区的更多信息,请参阅Apple文档: https : //developer.apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Workspace.html
静态库项目设置
- 确保所有静态库的头文件都设置为复制到“Public”。 这是在静态库目标>构build阶段的设置下完成的。 在“复制标题”阶段,确保所有标题都在“公开”部分。
- 接下来转到生成设置,find“公共头文件夹path”,并input您的图书馆的path。 我select使用这个:
包括/库名称
我已经采用了这个从RestKit使用,发现它与我所有的静态库效果最好。 这是告诉Xcode将我们移动到第一步中的“公共”标题部分的所有标题复制到我们在此处指定的文件夹,这个文件夹在构build时位于派生数据文件夹中。 和RestKit一样,我喜欢使用一个“包含”文件夹来包含我在项目中使用的每个静态库。
我也不喜欢在这里使用macros,因为这将允许我们稍后在使用静态库configuration项目时使用单个用户头searchpath。
- find“跳过安装”,并确保这是设置为是。
使用静态库的项目设置
- 将“静态库”添加为“构build阶段”>“链接二进制库”下的框架,并为要使用的任何静态库添加libLibraryName.a文件。
- 接下来确保项目设置为search用户searchpath。 这是在生成设置>总是search用户path,并确保其设置为是。
-
在相同的区域find用户头部searchpath并添加:
“$(PROJECT_TEMP_DIR)/../ UninstalledProducts /包括”
这告诉Xcode在构build过程中在Xcode创build的中间构build文件夹中查找静态库。 在这里,我们有我们用于静态库位置的“包含”文件夹,我们在步骤2中为静态库项目设置进行设置。 这是让Xcode正确find你的静态库的最重要的一步。
configuration工作区
在这里,我们要configuration工作区,以便在构build应用程序时构build静态库。 这是通过编辑我们的应用程序使用的scheme。
- 确保你有select的计划,将创build您的应用程序。
- 从scheme下拉菜单中select编辑scheme。
- select左侧列表顶部的Build。 通过按中间窗格上的+来添加新的目标。
- 你应该看到静态库显示你试图链接的库。 selectiOS静态库。
- 单击运行和存档。 这告诉scheme,当你build立你的应用程序时,编译静态库的库。
- 将静态库拖到应用程序目标上方。 这使得静态库在您的应用程序目标之前编译。
开始使用库
现在,你应该能够使用导入你的静态库
import <LibraryName/LibraryName.h>
这种方法避免了为不同的configuration设置不同的用户头文件path的麻烦,所以你应该没有问题编译档案。
为什么这个工作?
这一切都取决于这个道路:
"$(PROJECT_TEMP_DIR)/../UninstalledProducts/include"
由于我们将静态库configuration为使用“跳过安装”,因此编译的文件将移至临时生成目录中的“UninstalledProjects”文件夹。 我们的path也parsing为我们为静态库设置的“include”文件夹,并用于我们的用户头部searchpath。 两者合作让Xcode在编译过程中知道在哪里find我们的库。 由于这个临时编译目录同时存在于Debug和Releaseconfiguration中,所以Xcode只需要一个path就可以search静态库。
Xcode 4 Project无法编译静态库
相关问题: Xcode 4中的“词法或预处理器问题文件未find”
错误可能包括; 缺less头文件,“词法或预处理器问题”
解决scheme:
- 检查“用户头文件path”是否正确
- 将“始终search用户path”设置为是
- 在您的项目中创build一个“索引标题”的组呼,并将标题拖动到该组, 不要在提示时添加到任何目标。
这是一个非常有用的线程。 在研究自己的情况时,我发现苹果有一份12页的文档,标题为“在iOS中使用静态库”。 这里是pdf链接: http : //developer.apple.com/library/ios/technotes/iOSStaticLibraries/iOSStaticLibraries.pdf
这比大多数的互联网讨论要简单得多,并且用一些小的mod来解释我正在使用的外部库是如何configuration的,这对我来说工作的很好。 最重要的部分可能是:
如果你的图书馆目标有一个“复制头”构build阶段,你应该删除它; 在Xcode中执行“存档”操作时,复制标题生成阶段无法正确使用静态库目标。
使用Xcode 4.4或更高版本创build的新静态库目标将带有一个适当configuration的复制文件阶段的标题,所以你应该检查,看看你是否已经有一个之前创build一个。 如果你不这样做,请按目标编辑器底部的“添加生成阶段”,然后select“添加复制文件”。显示新的复制文件生成阶段,并将目标设置为“产品目录”。将子path设置为包含/ $ {PRODUCT_NAME}。 这会将文件复制到您的库(以PRODUCT_NAME构build设置获取)命名的文件夹中,位于构build的产品目录中名为include的文件夹中。 构build产品目录中的include文件夹位于应用程序的默认头部searchpath中,所以这是放置头文件的适当位置。
我相信,在许多现有的情况下,苹果的方法可能还不够。 我在这里为任何刚刚在静态图书馆花园小路上开始他们的旅程的人发帖 – 这可能是简单情况下最好的起点。
http://developer.apple.com/library/ios/#technotes/iOSStaticLibraries/Articles/creating.html
每个苹果文档:
您的库将有一个或多个头文件,该库的客户端需要导入。 要configuration将哪些标题导出到客户端,请select您的库项目以打开项目编辑器,select库目标以打开目标编辑器,然后select构build阶段选项卡。 如果你的图书馆目标有一个“复制头”构build阶段,你应该删除它; 在Xcode中执行“存档”操作时,复制标题生成阶段无法正确使用静态库目标。
看一下Jonah Wlliam的解决scheme(中途)和GitHub模型(在评论中)以获得洞察。 http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/
将$(OBJROOT)/ UninstalledProducts / exactPathToHeaders添加到标题searchpath。
出于某种原因,recursioncheckbox没有为我工作,我不得不将其余的path添加到标题所在的位置。
在Xcode的日志导航器下(中断点导航器右侧的标签),您可以看到构build历史logging。 如果您select实际的构build失败,则可以展开其详细信息以查看setenv PATH,并检查头文件的path是否存在。
将以下path添加到您的用户标题searchpath:
$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts
这已经validation!
冒着显示我是个白痴的风险…我一直忍受着XCode拒绝find我的.h文件整个下午。
然后我意识到。
因为我使用的是“XCode 4”,所以我“智能地”决定将我的所有项目放在名为“ XCode 4 projects ”的文件夹的子文件夹中。
这些文件夹名称中的空格大大地搞砸了XCode!
把这个文件夹重命名为“ XCode_4_Projects ”给我的生活带来了欢乐(而不是脏话)。
再次提醒我,今年是几年?
也许有人可以告诉苹果开发者…
这些答案都没有为我工作。 这是做了什么。 准确地添加以下内容(复制并粘贴包括双引号)到您的用户标题searchpath构build设置:
"$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts/include/"
请注意与其他答案相比,“/ include /”子目录的添加。 正如其他用户指出的,“recursion”选项似乎没有做任何事情,所以你可以忽略它。
以下列forms导入静态库头文件时,我的项目现在可以成功存档:
#import "LibraryName/HeaderFile.h"
您不需要启用总是search用户path设置,除非您将静态库头包含在尖括号( #import <LibraryName/HeaderFile.h>
)中,但是如果不是这样,一个系统/框架头。
上面的答案没有在Xcode 7上为我工作,但他们给了我一个好主意,但。 对于在Xcode 7上挣扎的人,我通过将以下内容添加到用户头部searchpath(包括引号)
"$(BUILT_PRODUCTS_DIR)/usr/local/include"
根据静态库的“Public Header Folder Path”设置中的内容,更改相对URL部分usr/local/include
在我的情况下,我的工作区有几个静态库项目,其中一个具有依赖项,包括头文件与另一个。 问题在于build筑的顺序。 在Build部分的编辑Scheme页面中,我取消了并行化选项,按照依赖关系排列了目标的顺序,并通过问题来解决
这是一个相关的问题,导致我这个问题,所以我join我的解决scheme严格的文档/它可以拯救另一个灵魂小时的汗
找不到DropboxSDK.h文件
经过几天试图让VES编译为iOS我最终遇到了这个问题。 DropboxSDK.h
绝对是search headers
范围,我甚至将它添加到framework headers
searchpath中,直接include
了.h
,并DropboxSDK.h
尝试获取DropboxSDK.h
。
解
EXPLICITY拖动DropboxSDK.framework
文件到Xcode的Project Navigation
,并确保Copy Files if needed
被选中。 还要确保你的目标是根据需要进行检查。
警告
在build phases
设置显式的框架位置不适合我。 我必须将 .framework 拖放到Xcode中,并确保将这些文件复制到我的项目中。
#mbp2015#xcode7#ios9
有多种复杂的方法可以做到这一点,并在这个线程中提出了一些非常聪明的解决scheme。
所有这些解决scheme的主要问题是,它严重降低了图书馆的便携性。
- 每次你需要使用你的库开始一个新的项目,并将其存档到iTunes,这是一个configuration地狱。
- 每次你需要与你的团队或客户分享你的项目,它可以因为任何原因(上下文,Xcode版本,不pipe…)
我的select终于简单地使用框架 – 永远 – 苹果(WWDCvideo)推荐的。
这是如此简单,最后做同样的工作!
另一个相当优雅的解决scheme,似乎工作是使用私有Cocoapods。 Cocoapods做所有的configuration工作,头文件等等。
框架摇滚!
这是为我解决了同样的问题。
我有一个应用程序目标,和一个iMessage扩展目标。 然后我有2个SDK(我自己的),这是App Target链接的。
问题是:我的iMessage目标也是使用我的2个SDK(单独的项目),但是它没有链接与他们在构build阶段 – >链接二进制库。 我必须将我的2 SDK添加到iMessage目标,以匹配我的应用程序目标,现在它归档。
所以这个故事的寓意是:如果你有多个目标,比如扩展,确保你所有的目标都链接到他们需要的库上。 它能够build立和部署到模拟器和设备,但不能存档。
保存自己的麻烦,并做到这一点=在您的Mac上创build新的用户帐户 – 在新的用户帐户下打开项目 – 所有问题消失。 节省你的时间,保持你的理智。 所有这些书呆子的回复不帮助!
祝你好运