[tr1] Help needed with Darwin port

Can someone with access to various flavours of gcc-4.x on Darwin let me know what directory the glibc++ std lib headers are in? Currently Boost.TR1 is using #include <../c++/header_name> which is taken from STLPort's configuration, but is apparently causing regressions in the boost code, Thanks, John.

At 12:56 PM +0000 1/13/09, John Maddock wrote:
Can someone with access to various flavours of gcc-4.x on Darwin let me know what directory the glibc++ std lib headers are in?
Currently Boost.TR1 is using #include <../c++/header_name> which is taken from STLPort's configuration, but is apparently causing regressions in the boost code,
Using Xcode 3.1.2 (most recent release) and gcc 4.0.1 (one of the two versions of gcc that comes with that release), the file <iostream>, for example, can be found at: </usr/include/c++/4.0.0/iostream> Is that what you were looking for? -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

On Jan 13, 2009, at 7:56 AM, John Maddock wrote:
Can someone with access to various flavours of gcc-4.x on Darwin let me know what directory the glibc++ std lib headers are in?
I only know about vanilla Mac OS X with Apple's developer tools, but I just ran some checks on several systems that have developer tools installed. On Leopard (Darwin 9.6.0) Apple supports both gcc 4.0 and 4.2. Both compilers use the same stdc++ libraries with the same headers. The headers seem to be in /usr/include/c++/4.0.0: $ find /usr/include -name iostream /usr/include/c++/4.0.0/iostream /usr/include/gcc/darwin/3.3/c++/iostream The location of these headers seems to remain the same across the SDKs for Panther, Tiger, Leopard and all versions of the iPhone OS, so I would expect that path to be accurate for any version of Darwin up to 9.6.0 that supports gcc 4.x. In Snow Leopard (Darwin 10.0.0) the situation seems somewhat different, as there are separate headers for gcc 4.0 and 4.2: $ find /usr/include -name iostream /usr/include/c++/4.0.0/iostream /usr/include/c++/4.2.1/iostream I hope this helps. Please let me know if I can provide additional information. Best wishes, --Stuart

I only know about vanilla Mac OS X with Apple's developer tools, but I just ran some checks on several systems that have developer tools installed.
On Leopard (Darwin 9.6.0) Apple supports both gcc 4.0 and 4.2. Both compilers use the same stdc++ libraries with the same headers. The headers seem to be in /usr/include/c++/4.0.0:
$ find /usr/include -name iostream /usr/include/c++/4.0.0/iostream /usr/include/gcc/darwin/3.3/c++/iostream
The location of these headers seems to remain the same across the SDKs for Panther, Tiger, Leopard and all versions of the iPhone OS, so I would expect that path to be accurate for any version of Darwin up to 9.6.0 that supports gcc 4.x.
In Snow Leopard (Darwin 10.0.0) the situation seems somewhat different, as there are separate headers for gcc 4.0 and 4.2:
$ find /usr/include -name iostream /usr/include/c++/4.0.0/iostream /usr/include/c++/4.2.1/iostream
I hope this helps. Please let me know if I can provide additional information.
Thanks to Marshall and Stuart, I suspect based on the information you've provided that it's going to be next to impossible to configure TR1 correctly... but I wonder do you know: * Do people commonly install Boost into a system path such as /usr/include or /usr/local/include ? * Is it possible to detect the Darwin version number (to separate 10.0 from 9.x)? * Do you know what happens if someone installs gcc from source (ie not from Apples developer tools)? Thanks! John.

I only know about vanilla Mac OS X with Apple's developer tools, but I just ran some checks on several systems that have developer tools installed.
On Leopard (Darwin 9.6.0) Apple supports both gcc 4.0 and 4.2. Both compilers use the same stdc++ libraries with the same headers. The headers seem to be in /usr/include/c++/4.0.0:
$ find /usr/include -name iostream /usr/include/c++/4.0.0/iostream /usr/include/gcc/darwin/3.3/c++/iostream
The location of these headers seems to remain the same across the SDKs for Panther, Tiger, Leopard and all versions of the iPhone OS, so I would expect that path to be accurate for any version of Darwin up to 9.6.0 that supports gcc 4.x.
In Snow Leopard (Darwin 10.0.0) the situation seems somewhat different, as there are separate headers for gcc 4.0 and 4.2:
$ find /usr/include -name iostream /usr/include/c++/4.0.0/iostream /usr/include/c++/4.2.1/iostream
I hope this helps. Please let me know if I can provide additional information.
Thanks to Marshall and Stuart, I suspect based on the information you've provided that it's going to be next to impossible to configure TR1 correctly... but I wonder do you know:
* Do people commonly install Boost into a system path such as /usr/include or /usr/local/include ?
I don't know. _I_ don't
* Is it possible to detect the Darwin version number (to separate 10.0 from 9.x)?
There's a shell variable "OSTYPE" which, on my system is set to "darwin9.0" [ Running Leopard ]
* Do you know what happens if someone installs gcc from source (ie not from Apples developer tools)?
Nope. I don't know. -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

On Jan 13, 2009, at 11:46 AM, John Maddock wrote:
* Do people commonly install Boost into a system path such as /usr/ include or /usr/local/include ?
I don't know about others, but my own Boost headers are currently installed in /usr/local/include/boost-1_37, which I explicitly add to the system header search path using the -I option to gcc in my project settings. Before that, I had them checked into my Subversion repository so that each version of my project was paired with the version of Boost used to build it. Under that scheme, there was no version of Boost "installed" at all, just local copies used for particular projects. I don't think you can assume that any particular relative path will get you reliably from a Boost header file to a system header file.
* Is it possible to detect the Darwin version number (to separate 10.0 from 9.x)?
A quick find/grep through the system headers did not come up with anything obvious. I would not attempt to detect the version using a shell variable like OSTYPE, though, since that would presumably detect the version of Darwin that you are running on, not the version that you are compiling for. It's possible to have multiple versions of Apple's developer tools installed, and each one of them can support SDKs from older systems, so the version of Darwin that's running would not be a reliable indicator of where the stdc++ headers are stored.
* Do you know what happens if someone installs gcc from source (ie not from Apples developer tools)?
It's been some time since I've done this, but my recollection is that by default, the stdc++ headers that come with gcc get installed into a deep, deep subdirectory of /usr/local whose location is known only to gcc. This is done so you have have multiple versions of gcc and stdc+ + installed simultaneously. I think that perhaps there's another way out of this situation. I'm assuming that the reason you can't simply #include <iostream> is that you are defining a header whose name is also <iostream>, and attempting to include the stdc++ version of the header simply leads to infinite recursion. I believe that gcc has a non-standard extension called #include_next that is designed to handle exactly this situation. It includes another file, but searches for it _only_ in the directories that come later in the search path than the current directory. You can read more about it at: http://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html It appears that this feature has been part of gcc since at least 4.0, so you should be able to detect that version of gcc and then use that extension. --Stuart

* Is it possible to detect the Darwin version number (to separate 10.0 from 9.x)?
A quick find/grep through the system headers did not come up with anything obvious.
:-(
I would not attempt to detect the version using a shell variable like OSTYPE, though, since that would presumably detect the version of Darwin that you are running on, not the version that you are compiling for. It's possible to have multiple versions of Apple's developer tools installed, and each one of them can support SDKs from older systems, so the version of Darwin that's running would not be a reliable indicator of where the stdc++ headers are stored.
* Do you know what happens if someone installs gcc from source (ie not from Apples developer tools)?
It's been some time since I've done this, but my recollection is that by default, the stdc++ headers that come with gcc get installed into a deep, deep subdirectory of /usr/local whose location is known only to gcc. This is done so you have have multiple versions of gcc and stdc+ + installed simultaneously.
I think that perhaps there's another way out of this situation.
I'm assuming that the reason you can't simply #include <iostream> is that you are defining a header whose name is also <iostream>, and attempting to include the stdc++ version of the header simply leads to infinite recursion.
I believe that gcc has a non-standard extension called #include_next that is designed to handle exactly this situation. It includes another file, but searches for it _only_ in the directories that come later in the search path than the current directory. You can read more about it at:
Sigh, this is what I used to use, but changed it because of bug reports: the issue is that if you install boost in say /usr/include (as some Linux distro's do) then #include_next can never get you from /usr/include to the unknown location of the g++ std lib headers :-( I think what I'm going to do for now is revert to using #include_next on Darwin, and hope folks don't install Boost into a system directory! Thanks for your help with this, John.

John Maddock wrote:
Sigh, this is what I used to use, but changed it because of bug reports: the issue is that if you install boost in say /usr/include (as some Linux distro's do) then #include_next can never get you from /usr/include to the unknown location of the g++ std lib headers :-(
Just a few FYIs... * All the mentions of "/usr/<wahtever>" only apply if you install Xcode to the default location. For example, I have 2 versions of Xcode installed most times and hence they are nowhere near a default location. * Depending on which SDK version of Xcode you install you might get multiple "*/usr/include/*" directories. Each with a corresponding "*/usr/bin/g++*". For example, when I use the iPhone SDK Xcode I get, with the latest version, 7 different "*/usr/include/*" locations. * With the latest Xcode, i.e. 3.x, you can point to an arbitrary system root. Which changes, to whatever you want, where the "*/usr/include/*" and a bunch of other stuff it searches for. * Even though you are running on some version of the OS, that has almost no bearing on which version of the OS you are compiling for nor which version of the headers you are compiling with. For example, you could be running 10.5.2, and compile for 10.3 with the headers for 10.4. HTH (BIDI) -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org (msn) - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim,yahoo,skype,efnet,gmail

John Maddock wrote:
Sigh, this is what I used to use, but changed it because of bug reports: the issue is that if you install boost in say /usr/include (as some Linux distro's do) then #include_next can never get you from /usr/include to the unknown location of the g++ std lib headers :-(
Just a few FYIs...
* All the mentions of "/usr/<wahtever>" only apply if you install Xcode to the default location. For example, I have 2 versions of Xcode installed most times and hence they are nowhere near a default location.
Sure, I don't need absolute paths, just the immediate directory containing the headers, so I can use: #include <../something/utility>, but it seems even that is mighty hard to get right. John.

John, After reading your response and thinking about this problem a bit longer, I've come up with two other possible workarounds if the #include_next solution doesn't work. Solution 1. Create a subdirectory called something like "bridges". For each stdc++ header that you need to include, create a bridge header in this subdirectory whose name is _not_ the same as the name of the original header. It might look something like this: File <boost/tr1/iostream>: #include <boost/tr1/bridges/iostream-bridge.hpp> File <boost/tr1/bridges/iostream-bridge.hpp>: #include <iostream> I _think_ that the #include in the bridge header will reliably locate the original stdc++ <iostream> header, since there is no file named "iostream" in the current directory and the bridges directory is not on the search path. Solution 2. Include some stdc++ header that is _not_ being redefined, and then use the value of __GLIBCXX__ to determine the path to the other headers. #if defined(__GLIBCXX__) #if __GLIBCXX__ == 20050421 #include <c++/4.0.0/iostream> #elif __GLIBCXX__ > 20050421 #include <c++/4.2.1/iostream> #else #error Unknown version of the GCC stdc++ library #endif #endif I certainly don't recommend this since it is so fragile, but a solution like this might work if nothing else does. Let me know if you choose to go this route and I'll try to come up with the possible values of __GLIBCXX__ for you and the corresponding paths. I'd also be happy to do a few test builds for you once you think you've come up with a solution, since we do have a vested interest in this working correctly. ;) --Stuart

After reading your response and thinking about this problem a bit longer, I've come up with two other possible workarounds if the #include_next solution doesn't work.
Solution 1. Create a subdirectory called something like "bridges". For each stdc++ header that you need to include, create a bridge header in this subdirectory whose name is _not_ the same as the name of the original header. It might look something like this:
File <boost/tr1/iostream>:
#include <boost/tr1/bridges/iostream-bridge.hpp>
File <boost/tr1/bridges/iostream-bridge.hpp>:
#include <iostream>
I _think_ that the #include in the bridge header will reliably locate the original stdc++ <iostream> header, since there is no file named "iostream" in the current directory and the bridges directory is not on the search path.
No because we do have a Boost file called <iostream> in the include path, it's getting from there to the real <iostream> that's the hard part :-( This does put in mind another possible solution though.. but it'll need a more or less complete rewrite of the forwarding code, so it'll have to wait for now.
Solution 2. Include some stdc++ header that is _not_ being redefined, and then use the value of __GLIBCXX__ to determine the path to the other headers.
#if defined(__GLIBCXX__) #if __GLIBCXX__ == 20050421 #include <c++/4.0.0/iostream> #elif __GLIBCXX__ > 20050421 #include <c++/4.2.1/iostream> #else #error Unknown version of the GCC stdc++ library #endif #endif
That might work, I'll give it a try.
I certainly don't recommend this since it is so fragile, but a solution like this might work if nothing else does. Let me know if you choose to go this route and I'll try to come up with the possible values of __GLIBCXX__ for you and the corresponding paths.
I think as long as we know the __GLIBCXX__ versions for which the path is "4.0.0", that should be enough, as the case where libstdc++ is correctly tied to the compiler version is already handled.
I'd also be happy to do a few test builds for you once you think you've come up with a solution, since we do have a vested interest in this working correctly. ;)
Can you try running the tests in Trunk now? There will be some failures from the *tricky.cpp tests, but the others should all pass. Thanks, John.
participants (4)
-
John Maddock
-
Marshall Clow
-
Rene Rivera
-
Stuart A. Malone