merged 1 commit into from Feb 19, 2013

3 participants


As far as I can tell this flag does two things:

  1. Looks in USER_HEADER_SEARCH_PATHS before HEADER_SEARCH_PATHS for both quoted and bracketed includes. This is so you can override system headers with your own versions of the same headers by adding them to USER_HEADER_SEARCH_PATHS.

  2. Enables Xcode magic includes, letting you include any project header with quoted includes regardless of it's position in the file system hierarchy ("header_in_another_folder.h"), and any subproject header with bracketed includes, regardless of whether the subproject even exports it and copies it to the build directory (<subproject/private_unexported_header.h>).

The first point seems weird to me. I feel like the correct way of doing that would be to specify your system headers overrides in HEADER_SEARCH_PATHS instead.

The second point leaves me baffled, in fact I'm not even sure it's as I understood it, because if it is, it's pretty crazy.

Anyway, the documentation of this flag says it's enabled by default for backwards compatibility, and strongly recommends disabling it, so there.


This was brought to my attention by the fact that the magic subproject includes seems to randomly screw up the build process if you have a subproject that has a subproject that's the same as your main project.
In my case my project has both ReactiveCocoa and ReactiveCocoaIO as subprojects, and ReactiveCocoaIO has ReactiveCocoa as subproject.

Every once in a while the build fails because of redefinitions in RACBacktrace.h and I have to clear out the build intermediates directories and rebuild.


I do like to state via the #import ".." or #import <> that I'm including a system or just a project header.

@Coneko Coneko referenced this pull request in ReactiveCocoa/ReactiveCocoa Feb 18, 2013

Build issues when using ReactiveCocoa and another Reactive framework. #332


Sorry for taking so long to respond to this. I apparently wasn't watching my own repo. :C

The second part is mostly for libextobjc includes nested under libraries like ReactiveCocoa and Mantle. Wouldn't imports like:

#import "EXTKeyPathCoding.h"

… break? Maybe that's okay, but I just want to understand what the alternatives are.


Yes that would break.

The alternatives are:

  1. Adding the path to EXTKeyPathCoding.h to the user or system header search paths in the project explicitly. Then you can import it directly. If the user header search paths have libextobjc/extobjc for example, you can #include "EXTKeyPathCoding.h".

  2. Including it with it's relative path. #include "libextobjc/extobjc/EXTKeyPathCoding". A lot uglier, the include is different depending on where the including file is in the directory hierarchy, and will break if the including file is moved.

  3. A mixture of the two. If the system header search paths have libextobjc you can #include <extobjc/EXTKeyPathCoding.h>. Probably not the best in this particular case because libextobjc has subdirectories, but if you have a project where the sources are all in the project's root directory, and is in a directory with the same name as the project, you can add the parent directory to the system header search paths and include the header with #include <project/header.h> which is a neat trick (yes those are some big ifs there).

All three methods have their pros and cons, but they all break if the included file is moved. I don't think that's a deal breaker since moving the file would break the magic include anyway with the Xcode project showing the file as missing. You're still breaking project encapsulation, the correct procedure would be to have the subproject export the headers through a target and import them from the build products directory, so a bit of ugliness is unavoidable.


👍 Thanks for the thorough explanation. 💥

@jspahrsummers jspahrsummers merged commit 809b24f into jspahrsummers:master Feb 19, 2013
@Coneko Coneko deleted the EnthusiasticCode:disable-alwayssearchuserpaths branch Feb 19, 2013

A little follow-up:

Turns out ALWAYS_SEARCH_USER_PATHS doesn't have anything to do with Xcode's magic includes.

From the Xcode Build Setting Reference:
HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT allows quoted includes to include any header in the current target.
HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES allows bracketed includes to include any header in any subproject.
HEADERMAP_INCLUDES_PROJECT_HEADERS allows quoted includes to include any header in the current project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment