Xcode 4和嵌套项目——未找到头文件。

时间:2023-01-13 20:23:29

I'm having a myriad of problems with Xcode 4 and nested projects that worked just well under Xcode 3.2. Here's a very basic one I cannot solve:

我在Xcode 4和嵌套项目中遇到了很多问题,这些问题在Xcode 3.2下运行得很好。这是一个我不能解决的基本问题:

I'm building a cocoa framework that requires another cocoa framework for which I have the source. So I perform the usual steps:

我正在构建一个cocoa框架,它需要另一个cocoa框架,我有这个框架。所以我按照通常的步骤:

  • Drag the .xcodeproj file of the required framework into my main framework project
  • 将所需框架的.xcodeproj文件拖到我的主框架项目中。
  • In my main framework under TARGETS > MyFramework > Build Phases > Target Dependencies: Add the nested project's target
  • 在我的主要框架下,> MyFramework >构建阶段>目标依赖项:添加嵌套项目的目标。
  • Make sure the header files of the nested framework are public
  • 确保嵌套框架的头文件是公共的。
  • In Xcode Settings > Locations > Build Location I have it set to Place build products in derived data location (recommended)
  • 在Xcode设置>位置>构建位置,我将它设置为在派生数据位置(推荐)中放置构建产品
  • Build products path of both targets are set to ${BUILT_PRODUCTS_DIR} and tell me they are at the DerivedData/Debug (or Release) location
  • 将两个目标的产品路径设置为${BUILT_PRODUCTS_DIR},并告诉我它们位于DerivedData/Debug(或发布)位置。
  • Architecture settings for both targets are identical
  • 两个目标的架构设置是相同的。

Then I hit [CMD] + B to build and it tells me that it doesn't find the header files of the nested framework. When I check the settings, User Header Search Paths contain the path to DerivedData/Debug, and inside there is the nested framework target with the header files in Versions/A/Headers.

然后我点击[CMD] + B来构建,它告诉我它没有找到嵌套框架的头文件。当我检查设置时,用户头搜索路径包含了DerivedData/Debug的路径,其中包含了包含在版本/A/Header中的头文件的嵌套框架目标。

I'm sitting here, anybody an idea what I'm doing wrong?

我坐在这里,有人知道我做错了什么吗?


The issue goes away when building for Debug when I change the User header search paths to ${BUILT_PRODUCTS_DIR}/MyFramework.framework/Headers. However this doesn't work when building for Distribution as the frameworks then use their Release settings, which ends up in a different subdirectory...

当我改变用户头搜索路径到${BUILT_PRODUCTS_DIR}/MyFramework.framework/ header时,问题就会消失。然而,当框架使用它们的发布设置(最终在一个不同的子目录下)构建时,这并不适用。


My temporary solution is to also define a Distribution configuration for the nested projects. This way the headers are found and the linker can link successfully.

我的临时解决方案是为嵌套项目定义一个分布配置。这样就可以找到标题,链接器可以成功链接。

8 个解决方案

#1


51  

Here's my synthesized knowledge so far:

这是我迄今为止的综合知识:

Forget the whole public header thing with Xcode, it's a PITA and doesn't work correctly when archiving your app. Instead, have all static library header files on the project level and tell your app where to find it.

忘记了Xcode的整个公共消息头,它是一个PITA,在存档你的应用程序时没有正确的工作。相反,在项目级别上拥有所有静态库头文件,并告诉你的应用程序在哪里找到它。

  1. Ease your pain by making sure all targets have the same name for the build configuration (i.e. add an "AdHoc" and "Deployment" configuration to the static libraries).

    通过确保所有目标都具有相同的构建配置名称(例如,向静态库中添加一个“临时”和“部署”配置)来减轻您的痛苦。

  2. In build settings, point the Header Search Paths (if you use #include <file.h>) or User Header Search Paths (if you use #include "file.h") to the directory of the static library project. If the static library project is inside your app directory, use this:

    在构建设置中,点头搜索路径(如果您使用#include )或用户头搜索路径(如果您使用#include“file.h”)到静态库项目的目录中。如果静态库项目位于应用程序目录中,请使用以下内容:

    "$(PROJECT_DIR)" (recursive enabled)

    " $(PROJECT_DIR)"启用(递归)

    If you have a directory which contains a) the static library project and b) your app, then this should work:

    如果你有一个包含a)静态库项目和b)你的应用程序的目录,那么这个应该可以工作:

    "$(PROJECT_DIR)/.." (recursive enabled)

    “(PROJECT_DIR)/美元…”启用(递归)

  3. If the submodule contains compiled libraries, set your Library Search Paths to:

    如果子模块包含已编译的库,则将库搜索路径设置为:

    "$(TARGET_BUILD_DIR)"

    " $(TARGET_BUILD_DIR)"

  4. Make sure all the static library projects that you use have Skip Install set to YES.

    请确保您使用的所有静态库项目都将跳过安装设置为YES。

  5. Again, no public header files (Build Phases » Copy Headers) in any of the static libraries, otherwise Xcode will not be able to archive an app.

    同样,在任何静态库中,没有公共头文件(构建阶段»复制头),否则Xcode将无法对应用程序进行存档。

  6. Make sure to tell Xcode when to build the static libraries, as shown in this Tech Doc from Apple.

    确保在构建静态库时告诉Xcode,如苹果公司的技术文档所示。


Old Answer:

旧的回答:

I still haven't found a real solution to this problem with static libraries. What works for me is:

我仍然没有找到一个真正的解决方法来解决这个问题,使用静态库。对我有用的是:

  • Create an "AdHoc" Configuration for the static library
  • 为静态库创建一个“临时”配置。
  • Add $(BUILT_PRODUCTS_DIR) to User Header Search paths for the application (with recursive checked) -> this is used when running the app
  • 将$(BUILT_PRODUCTS_DIR)添加到应用程序的用户头搜索路径(使用递归检查)->在运行应用程序时使用。
  • In the Xcode menu, select Product > Build For > Build For Archiving
  • 在Xcode菜单中,选择产品>构建为>构建存档。

This works, the app finds the header files and builds itself, it ends up in DerivedData//Build/Products/AdHoc-iphoneos/ as an App bundle. Following these simple instructions (dead link) from TestFlightApp.com I can pack this App into an IPA and send it around. Simply selecting to Archive the app from Xcode does again not find the headers, even if they truly are in the AdHoc-iphoneos build directory.

这个应用程序可以找到头文件并构建它自己,最终得到的是DerivedData//Build/Products/AdHoc-iphoneos/作为一个应用程序包。下面这些简单的指令(死链接)可以从TestFlightApp.com下载,我可以把这个应用程序打包到IPA,然后发送出去。简单地选择将应用程序从Xcode中存档,仍然没有找到header,即使它们确实存在于AdHoc-iphoneos构建目录中。

#2


3  

(As of Xcode 5.1)

(如Xcode 5.1)

When the subproject is built by XCode, the subproject header files are copied into the build directory. When archiving, it seems that this copy destination directory is not added to the header/include search path. You'll want to go to your Build Settings and add

当子项目由XCode构建时,子项目头文件被复制到构建目录中。当归档时,似乎这个复制目标目录没有被添加到头/包含搜索路径。您将希望进入您的构建设置并添加。

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

to the "Header Search Paths" for the scheme that you use for archiving.

对于用于存档的方案的“标题搜索路径”。

If you're not sure which scheme is used for archiving, go to Product -> Scheme -> Edit Schemes and look for Archive in the left column.

如果您不确定该计划用于存档,请访问产品->方案->编辑方案,并在左侧栏中查找存档。

#3


2  

Make sure your third party framework is added as «group» to your main project, so you can see it in your project's hierarchy...

确保您的第三方框架作为«group»添加到您的主项目中,因此您可以在项目的层次结构中看到它……

#4


1  

I had the same problem here and I could solve the problem by setting "Build Location" to Place build products in locations specified by targets"

我在这里遇到了同样的问题,我可以通过设置“Build Location”来解决这个问题,在目标指定的位置放置构建产品。

#5


1  

I had this problem: I could build both Debug and App Store configurations, but not Ad Hoc. Building Ad Hoc gave me errors because it couldn't find .h files needed by nested projects.

我有一个问题:我可以构建调试和应用程序存储配置,但不是临时的。由于无法找到嵌套项目所需要的.h文件,构建Ad Hoc给了我错误。

Turned out I had an expired provisioning lingering in my Release configuration. I updated that provisioning link and now I can both build Ad Hoc and use the Archive feature to package it.

结果显示,在我的发布配置中有一个过期的配置。我更新了这个配置链接,现在我既可以构建临时文件,也可以使用存档特性来打包它。

Took me hours to figure it out! My mind just didn't jump from missing .h files to provisioning errors just by itself. =) There might have been an error or warning complaining about the missing provisioning, but if so it was well buried among the hundreds of .h related errors.

我花了好几个小时才弄明白!我的思维并没有从丢失的.h文件中跳转到仅由它自己来提供错误。()可能有一个错误或警告,抱怨丢失的供应,但如果是这样,它很好地隐藏在数百个。h相关的错误中。

#6


1  

I was having the same issue with a Configuration named "Ad Hoc" (as per TestFlight recommendation at http://help.testflightapp.com/customer/portal/articles/402782-how-to-create-an-ipa-xcode-4) and the main project could not find some of the headers from the nested projects. I renamed the project to "AdHoc" (no spaces) and the problem went away; seems like spaces can mess up header search paths in some cases, although I haven't figured out the specifics of when that might happen and why.

我遇到了一个与名为“Ad Hoc”的配置相同的问题(在http://help.testflightapp.com/customer/portal/articles/articles/402782-howto -to-create- to- ipa-xcode-4中),主项目无法从嵌套项目中找到一些头文件。我把这个项目重新命名为“临时”(没有空格),问题就消失了;在某些情况下,空格可能会搞砸头搜索路径,不过我还没有弄清楚可能发生的具体情况以及原因。

#7


1  

I was having this issue with a nested project that built a static library. I found this doc on apples site that completely saved my life.

我有一个嵌套项目,它构建了一个静态库。我在苹果网站上找到了这个完全救了我一命的医生。

http://developer.apple.com/library/ios/#DOCUMENTATION/Xcode/Conceptual/ios_development_workflow/AA-Developing_a_Static_Library_and_Incorporating_It_in_Your_Application/archiving_an_application_that_uses_a_static_library.html

http://developer.apple.com/library/ios/文档/ Xcode /概念/ ios_development_workflow / AA-Developing_a_Static_Library_and_Incorporating_It_in_Your_Application / archiving_an_application_that_uses_a_static_library.html

I'm so glad I didn't have to muck around with the derived data paths.

我很高兴我不用在派生的数据路径上乱搞。

#8


0  

For me, this happened after a GIT merge, which created many conflicts, one of them related to the project file. After the merge, I'm sure the structure of the project file changed.

对我来说,这发生在一个GIT合并之后,它创建了许多冲突,其中一个与项目文件有关。合并之后,我确定项目文件的结构发生了变化。

What I ended up doing was going into the project "Build Settings", then looking for "Always Search User Paths" and turning it to Yes.

我最后做的是进入项目“构建设置”,然后寻找“总是搜索用户路径”并将其变为Yes。

I guess the merge turned this boolean to No, therefore the project wasn't looking in the right places for the header files.

我猜是合并将这个布尔值变成了No,因此项目没有在正确的位置查找头文件。

#1


51  

Here's my synthesized knowledge so far:

这是我迄今为止的综合知识:

Forget the whole public header thing with Xcode, it's a PITA and doesn't work correctly when archiving your app. Instead, have all static library header files on the project level and tell your app where to find it.

忘记了Xcode的整个公共消息头,它是一个PITA,在存档你的应用程序时没有正确的工作。相反,在项目级别上拥有所有静态库头文件,并告诉你的应用程序在哪里找到它。

  1. Ease your pain by making sure all targets have the same name for the build configuration (i.e. add an "AdHoc" and "Deployment" configuration to the static libraries).

    通过确保所有目标都具有相同的构建配置名称(例如,向静态库中添加一个“临时”和“部署”配置)来减轻您的痛苦。

  2. In build settings, point the Header Search Paths (if you use #include <file.h>) or User Header Search Paths (if you use #include "file.h") to the directory of the static library project. If the static library project is inside your app directory, use this:

    在构建设置中,点头搜索路径(如果您使用#include )或用户头搜索路径(如果您使用#include“file.h”)到静态库项目的目录中。如果静态库项目位于应用程序目录中,请使用以下内容:

    "$(PROJECT_DIR)" (recursive enabled)

    " $(PROJECT_DIR)"启用(递归)

    If you have a directory which contains a) the static library project and b) your app, then this should work:

    如果你有一个包含a)静态库项目和b)你的应用程序的目录,那么这个应该可以工作:

    "$(PROJECT_DIR)/.." (recursive enabled)

    “(PROJECT_DIR)/美元…”启用(递归)

  3. If the submodule contains compiled libraries, set your Library Search Paths to:

    如果子模块包含已编译的库,则将库搜索路径设置为:

    "$(TARGET_BUILD_DIR)"

    " $(TARGET_BUILD_DIR)"

  4. Make sure all the static library projects that you use have Skip Install set to YES.

    请确保您使用的所有静态库项目都将跳过安装设置为YES。

  5. Again, no public header files (Build Phases » Copy Headers) in any of the static libraries, otherwise Xcode will not be able to archive an app.

    同样,在任何静态库中,没有公共头文件(构建阶段»复制头),否则Xcode将无法对应用程序进行存档。

  6. Make sure to tell Xcode when to build the static libraries, as shown in this Tech Doc from Apple.

    确保在构建静态库时告诉Xcode,如苹果公司的技术文档所示。


Old Answer:

旧的回答:

I still haven't found a real solution to this problem with static libraries. What works for me is:

我仍然没有找到一个真正的解决方法来解决这个问题,使用静态库。对我有用的是:

  • Create an "AdHoc" Configuration for the static library
  • 为静态库创建一个“临时”配置。
  • Add $(BUILT_PRODUCTS_DIR) to User Header Search paths for the application (with recursive checked) -> this is used when running the app
  • 将$(BUILT_PRODUCTS_DIR)添加到应用程序的用户头搜索路径(使用递归检查)->在运行应用程序时使用。
  • In the Xcode menu, select Product > Build For > Build For Archiving
  • 在Xcode菜单中,选择产品>构建为>构建存档。

This works, the app finds the header files and builds itself, it ends up in DerivedData//Build/Products/AdHoc-iphoneos/ as an App bundle. Following these simple instructions (dead link) from TestFlightApp.com I can pack this App into an IPA and send it around. Simply selecting to Archive the app from Xcode does again not find the headers, even if they truly are in the AdHoc-iphoneos build directory.

这个应用程序可以找到头文件并构建它自己,最终得到的是DerivedData//Build/Products/AdHoc-iphoneos/作为一个应用程序包。下面这些简单的指令(死链接)可以从TestFlightApp.com下载,我可以把这个应用程序打包到IPA,然后发送出去。简单地选择将应用程序从Xcode中存档,仍然没有找到header,即使它们确实存在于AdHoc-iphoneos构建目录中。

#2


3  

(As of Xcode 5.1)

(如Xcode 5.1)

When the subproject is built by XCode, the subproject header files are copied into the build directory. When archiving, it seems that this copy destination directory is not added to the header/include search path. You'll want to go to your Build Settings and add

当子项目由XCode构建时,子项目头文件被复制到构建目录中。当归档时,似乎这个复制目标目录没有被添加到头/包含搜索路径。您将希望进入您的构建设置并添加。

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

to the "Header Search Paths" for the scheme that you use for archiving.

对于用于存档的方案的“标题搜索路径”。

If you're not sure which scheme is used for archiving, go to Product -> Scheme -> Edit Schemes and look for Archive in the left column.

如果您不确定该计划用于存档,请访问产品->方案->编辑方案,并在左侧栏中查找存档。

#3


2  

Make sure your third party framework is added as «group» to your main project, so you can see it in your project's hierarchy...

确保您的第三方框架作为«group»添加到您的主项目中,因此您可以在项目的层次结构中看到它……

#4


1  

I had the same problem here and I could solve the problem by setting "Build Location" to Place build products in locations specified by targets"

我在这里遇到了同样的问题,我可以通过设置“Build Location”来解决这个问题,在目标指定的位置放置构建产品。

#5


1  

I had this problem: I could build both Debug and App Store configurations, but not Ad Hoc. Building Ad Hoc gave me errors because it couldn't find .h files needed by nested projects.

我有一个问题:我可以构建调试和应用程序存储配置,但不是临时的。由于无法找到嵌套项目所需要的.h文件,构建Ad Hoc给了我错误。

Turned out I had an expired provisioning lingering in my Release configuration. I updated that provisioning link and now I can both build Ad Hoc and use the Archive feature to package it.

结果显示,在我的发布配置中有一个过期的配置。我更新了这个配置链接,现在我既可以构建临时文件,也可以使用存档特性来打包它。

Took me hours to figure it out! My mind just didn't jump from missing .h files to provisioning errors just by itself. =) There might have been an error or warning complaining about the missing provisioning, but if so it was well buried among the hundreds of .h related errors.

我花了好几个小时才弄明白!我的思维并没有从丢失的.h文件中跳转到仅由它自己来提供错误。()可能有一个错误或警告,抱怨丢失的供应,但如果是这样,它很好地隐藏在数百个。h相关的错误中。

#6


1  

I was having the same issue with a Configuration named "Ad Hoc" (as per TestFlight recommendation at http://help.testflightapp.com/customer/portal/articles/402782-how-to-create-an-ipa-xcode-4) and the main project could not find some of the headers from the nested projects. I renamed the project to "AdHoc" (no spaces) and the problem went away; seems like spaces can mess up header search paths in some cases, although I haven't figured out the specifics of when that might happen and why.

我遇到了一个与名为“Ad Hoc”的配置相同的问题(在http://help.testflightapp.com/customer/portal/articles/articles/402782-howto -to-create- to- ipa-xcode-4中),主项目无法从嵌套项目中找到一些头文件。我把这个项目重新命名为“临时”(没有空格),问题就消失了;在某些情况下,空格可能会搞砸头搜索路径,不过我还没有弄清楚可能发生的具体情况以及原因。

#7


1  

I was having this issue with a nested project that built a static library. I found this doc on apples site that completely saved my life.

我有一个嵌套项目,它构建了一个静态库。我在苹果网站上找到了这个完全救了我一命的医生。

http://developer.apple.com/library/ios/#DOCUMENTATION/Xcode/Conceptual/ios_development_workflow/AA-Developing_a_Static_Library_and_Incorporating_It_in_Your_Application/archiving_an_application_that_uses_a_static_library.html

http://developer.apple.com/library/ios/文档/ Xcode /概念/ ios_development_workflow / AA-Developing_a_Static_Library_and_Incorporating_It_in_Your_Application / archiving_an_application_that_uses_a_static_library.html

I'm so glad I didn't have to muck around with the derived data paths.

我很高兴我不用在派生的数据路径上乱搞。

#8


0  

For me, this happened after a GIT merge, which created many conflicts, one of them related to the project file. After the merge, I'm sure the structure of the project file changed.

对我来说,这发生在一个GIT合并之后,它创建了许多冲突,其中一个与项目文件有关。合并之后,我确定项目文件的结构发生了变化。

What I ended up doing was going into the project "Build Settings", then looking for "Always Search User Paths" and turning it to Yes.

我最后做的是进入项目“构建设置”,然后寻找“总是搜索用户路径”并将其变为Yes。

I guess the merge turned this boolean to No, therefore the project wasn't looking in the right places for the header files.

我猜是合并将这个布尔值变成了No,因此项目没有在正确的位置查找头文件。