53

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:

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

  • Drag the .xcodeproj file of the required framework into my main framework project
  • In my main framework under TARGETS > MyFramework > Build Phases > Target Dependencies: Add the nested project's target
  • 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)
  • Build products path of both targets are set to ${BUILT_PRODUCTS_DIR} and tell me they are at the DerivedData/Debug (or Release) location
  • 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.

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...


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.

Pascal
  • 16,846
  • 4
  • 60
  • 69
  • Found a solution to this? I have this problem too. Only for Ad Hoc strangely enough. App Store Distribution works.... – PEZ Jul 15 '11 at 14:23
  • No, not yet. Didn't need to submit this specific app lately, so I haven't been affected by the issue in a while. – Pascal Jul 15 '11 at 20:35
  • I see, I now posted my "answer". Here's wishing you luck in solving your problem! – PEZ Jul 17 '11 at 08:54

8 Answers8

54

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.

  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:

    "$(PROJECT_DIR)" (recursive enabled)

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

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

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

    "$(TARGET_BUILD_DIR)"

  4. Make sure all the static library projects that you use have Skip Install set to 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.

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


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
  • In the Xcode menu, select Product > Build For > Build For Archiving

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.

Pascal
  • 16,846
  • 4
  • 60
  • 69
  • With Xcode 4.6, Apple seems to have changed their build order stuff again, and this didn't work. However, based on this, and setting "User Search Header Paths" to "$(TARGET_BUILD_DIR)/path/where/subproject/exports/its/public/headers" worked for me - no other steps needed – Adam Jun 06 '13 at 11:35
  • Sorry, I should have been clearer: your answer will work fine on trivial projects, but it's wrong to use recursive on ../, and it's unnecessary. Public headers + User Search Headers + $(TARGET_BUILD_DIR) works even on complex projects where the recursive ../ fails. – Adam Jun 06 '13 at 15:17
  • I'll edit the `../`, it's only necessary for non-nested projects. My projects are nested and it works fine, even for a complex project using a wrapper framework around a C-library (Redland-ObjC) that includes C-headers. Have you tried Archiving an App with `$(TARGET_BUILD_DIR)`? – Pascal Jun 06 '13 at 23:21
  • Yes, and tis horrible :). Personally I only use nested projects for debug builds - too many bugs in Xcode specific to nesting :(. But some projects never need to archive, and the nesting makes compile/test/debug a few seconds faster! – Adam Jun 07 '13 at 11:29
  • I Struggled with this for more than 4 Days and thanks to your Answer I Got it Solved... If I Had a +4 or +5 I'd Use it NOW :-) – Hernan Arber Apr 28 '14 at 23:26
  • link for **Developing a Static Library and Incorporating It in Your App** is dead. – Cœur Mar 24 '19 at 18:21
3

(As of 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

$(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.

Eclectic DNA
  • 386
  • 2
  • 5
  • Solved my problem for Xcode 6.3.1 Added it to "Header Search Paths" for Release. Thanks! – cat Apr 30 '15 at 13:20
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...

Macmade
  • 52,708
  • 13
  • 106
  • 123
  • I have added it so that I see the blue project icon indented just below the main blue project icon. I can also expand it to see the nested project's files. Is that what you mean? – Pascal Mar 24 '11 at 09:22
  • Drag the .framework file from your sub-project into your main project. – Macmade Mar 24 '11 at 09:36
  • 1
    Ha, I had to remove `.framework` from the `EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES` build setting, then add the framework as you say, now it works! Thanks! – Pascal Mar 24 '11 at 09:51
  • Sorry, have to unmark your response again – this does not work for me when Archiving, the frameworks use a *Release* configuration, the App a *Distribution*, so the header paths won't be the same and there we are, same problem. Can it be so hard? :P – Pascal Mar 24 '11 at 10:42
  • @Pascal wow! `.framework` in `EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES`! FKN MIRACLE!!! – Ian Bytchek Feb 15 '16 at 19:23
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.

gummihaf
  • 93
  • 1
  • 7
  • 1
    Found the reason for this: each entry in the Header Search Paths was not in quotation marks, which probably should fix the space naming issue (e.g. instead of $(BUILT_PRODUCTS_DIR)/../three20 it should be "$(BUILT_PRODUCTS_DIR)/../three20") – gummihaf Apr 20 '12 at 21:19
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

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

Meroon
  • 3,458
  • 4
  • 25
  • 29
  • "this doc on apples site that completely saved my life." That is of course MIA now. Commenting to save anyone else from the clickthru of despair... – crgt Sep 20 '17 at 01:41
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"

  • Issue remains the same for me. What do you have as "build location" for the targets? – Pascal Mar 26 '11 at 11:04
  • The "Build Products Path" and "Intermediate Bulid Files Path" are in both projects set to "build". – windtaenzer Mar 28 '11 at 08:04
  • Oh, okay, so in a subfolder in the project. I want to avoid that, all build products are in the IntermediateFiles directory. – Pascal Mar 29 '11 at 17:13
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.

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.

PEZ
  • 16,821
  • 7
  • 45
  • 66
  • I finally got back to the project giving me this headache - and this is not the problem I have. I just can't make Xcode look into the `Release` built files directory for the static libraries when building the app `AdHoc`. Maybe I'm too demanding... – Pascal Sep 25 '11 at 22:25
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.

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

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

Alex
  • 7,432
  • 20
  • 75
  • 118