Re: Header Files
Re: Header Files
- Subject: Re: Header Files
- From: koko <email@hidden>
- Date: Wed, 31 Aug 2011 09:06:28 -0600
What a great treatise on header paths !
Thanks for your time and effort.
-koko
On Aug 31, 2011, at 5:40 AM, Andreas Grosam wrote:
>
> On Aug 31, 2011, at 4:48 AM, koko wrote:
>
>> There is not a common parent directory so I did this:
>>
>> in File1.cpp
>>
>> #include "../PROJDIR/Folder A/Header.h"
>>
>> and
>>
>> In File2.cpp
>>
>> #include "../PROJDIR/Folder B/Header.h"
>>
>> So while Header.h is th esame name I get two different versions.
>>
>
> First, I would discourage you from using relative pass names including ".." as a path component.
>
> Second, you probably became a victim of Xcode's "header map" feature, which is enabled by default in Xcode.
> Otherwise, you already had learned how to use header search paths. I don't blame you, but Xcode which for unknown reasons insists to have this "header map" feature enabled by default in Xcode, and that you cannot disable it - or better, there is no documented way to disable it.
>
> Well, the "header map" feature works for many cases, however, it may break your project if you accidentally use a name of a header file which already exists somewhere else in your project. And Xcode will not warn you, but just randomly choose one header file.
>
> Well, in any case, it is better to know how the "header search paths" do work. This is actually a task for the preprocessor of a C/C++ compiler, and as a developer you should read this really carefully:
> <http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html#Search-Path>
>
>
>
> Once you have understood how a compiler uses search paths, you may proceed - and for sanity never ever rely anymore on the header map feature ;)
>
> Important to know is, that if you specify your own header search paths in Xcode, they will be passed in the command line to the compiler *before* the header maps. This effectively lets the compiler find header files at the locations specified at the paths which you defined, and before it possibly looks at other places, say defined in the header map. However, this does not disable those paths defined in the header maps. If the compiler does not find them in custom locations, it will look in paths defined in the header map as well.
>
> In Xcode 4 you can specify your own header search paths in the target settings by adding paths to the "Header Search Path" build setting or "User Header Search Paths" build setting.
> If you add a path to "Header Search Path", Xcode will add a command parameter -I<path> to the command line.
> If you add a path to "User Header Search Paths", Xcode will add a command parameter -iquote<path> to the command line.
>
> You should already know what the difference is between -I<path> and -quote<path> ;)
>
> Suppose, you created a project "MyTest" with one target "MyTest with Xcode 4.
> The file hierarchy looks as follows:
> MyTest
> MyTest.xcodeproj
> MyTest
> main.cpp
>
>
> At this point it's important to know about one Xcode build setting variable, namely: SRCROOT
> <http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html>
>
> When building the target, SRCROOT is defined for instance as "/Users/theuser/Development/MyProjects/MyTest/MyTest"
> That is, it is the path to the folder where main.cpp is located, or better: where the target's root is located.
>
> You can use the build setting variable SRCROOT when you specify your own header search path as follows:
>
> Suppose you add a folder "Headers" within your target root, and add some header files in sub folders:
> MyTest
> MyTest.xcodeproj
> MyTest
> Headers
> FolderA
> header.h
> FolderB
> header.h
> main.cpp
> file1.cpp
> file2.cpp
>
>
>
> Then, you could now specify your own header search path as follows using the SRCROOT variable:
> $(SRCROOT)/Headers
>
> that is, add "$(SRCROOT)/Headers" to the "Header Search Paths" setting in your target.
>
>
> Now, since a path to the folder MyTest/MyTest/Headers is defined, you can include headers as follows:
>
> // file1.cpp
> #include "FolderA/header.h"
>
> // file2.cpp
> #include "FolderB/header.h"
>
>
> Using this technique pretty much eliminates any name clashes and ambiguities regarding header names, and I would strongly recommend to do this in practice.
>
> If you specify a search path "$(SRCROOT)/my_path" in the target setting "Header Search Paths", then Xcode will pass this in the command line as -I/Users/theuser/Development/MyProjects/MyTest/MyTest/my_path.
>
>
>
>
>
> So, for you problem, there is actually a common header path: ../PROJDIR
> I'm pretty sure you can express ../PRJODIR in terms of SRCROOT without using ".." path components. If this is not the case, you may define a user setting in the target build pane which specifies the path to your source, e.g.:
> MY_TEST_ROOT = /Users/me/Devel/MyTest/MyTest
>
> Then, use this variable likewise when defining your header search path:
> $(MY_TEST_ROOT)/Headers
> and you you're done, and you can include the headers just as above:
> // file1.cpp
> #include "FolderA/header.h"
>
> which will locate the header file at $(MY_TEST_ROOT)/Headers/FolderA/
>
>
>
> One thing to note is:
> Accidentally including the header file like this:
>
> // file1.cpp
> #include "header.h"
>
> will still find a header file named "header.h" - if this header file is part of your project or target!
> This is due to the Xcode's header map feature. Which header file will be included if there exist more than one in different locations and are part of the project is implementation defined by Xcode.
>
>
>
> Andreas
>
>> -koko
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Xcode-users mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden