Dear STLport Team,
I got these error messages when building Boost.Datetime (and other Boost non-header-only libs):
/media/sda5/OpenSourceLibrary/boost_1_34_1/libs/date_time/src$ g++ -pthread -fexceptions -frtti -fident -fPIC -O2 -D_REENTRANT -D_GNU_SOURCE -I../../.. -I../../../../STLport-5.1.4/stlport -D_STLP_USE_BOOST_SUPPORT=1 -D_STLP_DEBUG_LEVEL=_STLP_STANDARD_DBG_LEVEL -D_STLP_DEBUG_MODE_THROWS=1 -D_STLP_DEBUG_UNINITLIALIZED=1 -D_STLP_DEBUG_ALLOC=1 -D_STLP_SHRED_BYTE=0xA3 -D_STLP_NO_ANACHRONISMS=1 -D_STLP_NO_EXTENSIONS=1 -D_STLP_USE_TEMPLATE_EXPRESSION=1 -D_STLP_DONT_USE_SHORT_STRING_OPTIM=1 -D_STLP_LEAKS_PEDANTIC=1 -D_STLP_USE_MALLOC=1 -D_STLP_USE_PERTHREAD_ALLOC=1 -c ./gregorian/greg_month.cpp -o ./lib/greg_month.o
../../../boost/mpl/integral_c_tag.hpp:22: error: 'value' has not been declared
../../../boost/mpl/integral_c_tag.hpp:22: error: ISO C++ forbids declaration of 'BOOST_STATIC_CONSTANT' with no type
../../../boost/mpl/aux_/integral_wrapper.hpp:45: error: 'value' has not been declared
../../../boost/mpl/aux_/integral_wrapper.hpp:45: error: ISO C++ forbids declaration of 'BOOST_STATIC_CONSTANT' with no type
[too many error messsages, stop here]
It's true that I can get Boost.Datetime (and other Boost libs) if _STLP_USE_BOOST_SUPPORT is turned off. But why did gcc (3.4.5 on Win, 4.1.3 on Linux) complain like that ? Why does _STLP_USE_BOOST_SUPPORT "conflict" with BOOST_STATIC_CONSTANT ?
I also wrote a small program to test Boost.Datetime (which was built without _STLP_USE_BOOST_SUPPORT), and it is interesting because my program was compiled and ran smoothly even with '-D_STLP_USE_BOOST_SUPPORT=1'.
Can you give me some ideas, please ? Thanks in advance.
Can't confirm: compiled fine with STLport trunk.
Yes, 5.1 has problem; indeed I don't expect that one will be fixed in 5.1, and just not recommend to use _STLP_USE_BOOST_SUPPORT in 5.1: it not ready for TR1/TR2 inclusion into STLport (but not prevent usage of pre-TR1/TR2 from boost).
Lets rather say that it is not recommended to use _STLP_USE_BOOST_SUPPORT when building boost. Looks like there is no problem using it in any other situation.
Dear Petr and Francois,
Thats nice because I've already known why we got these error messages.
It looks like a problem of self referencing header (in this case, I think it is <boost/config.hpp>), which is the result of insisting on including <utility> by Boost whenever it needs information of configuration of standard library.
Here is my workaround:
1. Building boost libs (e.g Boost.Datetime) with BOOST_STDLIB_CONFIG defined manually:
Without it, Boost will try to auto-detect the STL platform used (Dinkumware, STLport, etc.) by including <utility> and we'll run into trouble if Boost does this (Exactly, boost libs will include <boost/config.hpp>, which in turn wrapping <boost/config/select_stdlib_config.hpp> that contains <boost/config/no_tr1/utility.hpp>).
2. Editing <boost/config/stdlib/stlport.hpp>:
Boost requires <utility> once again (just looking for STLport settings), so we must replace the line:
to break self referencing.
I did this because all STLport settings are actually located in it (Is it correct ?) and Boost needs not only _STLP_VERSION, but also other macro definitions like _STLP_STATIC_CONST_INIT_BUG, _STLP_CLASS_PARTIAL_SPECIALIZATION, etc. Obviously, the best place to find them all is <stlport/stl/config/features.h>.
And now the command:
/media/sda5/OpenSourceLibrary/boost_1_34_1/libs/date_time/src$ g++ -pthread -fexceptions -fident -frtti -fPIC -O2 -D_REENTRANT -D_GNU_SOURCE -D_STLP_DEBUG_LEVEL=_STLP_STANDARD_DBG_LEVEL -D_STLP_DEBUG_MODE_THROWS=1 -D_STLP_DEBUG_UNINITIALIZED=1 -D_STLP_DEBUG_ALLOC=1 -D_STLP_SHRED_BYTE=0xA3 -D_STLP_NO_ANACHRONISMS=1 -D_STLP_NO_EXTENSIONS=1 -D_STLP_USE_TEMPLATE_EXPRESSION=1 -D_STLP_DONT_USE_SHORT_STRING_OPTIM=1 -D_STLP_LEAKS_PEDANTIC=1 -D_STLP_USE_MALLOC=1 -D_STLP_USE_PERTHREAD_ALLOC=1 -DBOOST_STDLIB_CONFIG="<boost/config/stdlib/stlport.hpp>" -I/usr/include/stlport -I../../.. -c ./gregorian/greg_month.cpp -o ./lib/greg_month.o
is no longer producing error messages.
It seems the problem is at Boost side so I think we should contact Boost team to fix it.
Hope this will help.
I don't think this is solution: define -DBOOST_STDLIB_CONFIG="<boost/config/stdlib/stlport.hpp>" would require for every compilation, and can't be placed safely in any header file (due to includes order may vary);
Here a lot of other aspects, see related work in STLport's trunk: "grep boost etc/ChangeLog";
> It seems the problem is at Boost side so I think we should contact Boost team to fix it.
Problem on both sides: this like chicken-and-egg problem Boost expect that STL implementation don't include boost, while STLport very sensitive for include order too.
Thank you for your reply, Petr. I agree with you that defining BOOST_STDLIB_CONFIG whenever compiling Boost is very inconvenient and it can not be considered a workaround.
I also study the solution you suggest me. It works fine but may result in warnings of macro redefinitions. Therefore, I think we should look for a better way.
This is my new idea in detail:
- Adding few lines of code to <utility> to determine whether it needs to be included by Boost for reading standard library settings.
- And if Boost only requires <utility> to collect such info, <utility> will be a wrapper of <stl/config/features.h>, i.e we protect its "real" content against the unwanted inclusion.
- Removing BOOST_STDLIB_CONFIG from <stl/config/features.h> to skip the warning of BOOST_STDLIB_CONFIG redefinition (as you did in your solution).
Extra code in <utility> as below:
/* <EXTRA CODE>
* <utility> will be a <stl/config/features.h> wrapper
* if Boost only needs it to collect stdlib information.
#if defined(BOOST_CONFIG_HPP) && !defined(BOOST_CONFIG_SUFFIX_HPP)
# include <stl/config/features.h>
# if defined(_STLP_USE_BOOST_SUPPORT) && !defined(_STLP_USE_BOOST_SUPPORT_WORKAROUND)
# define _STLP_USE_BOOST_SUPPORT_WORKAROUND
#if defined(BOOST_CONFIG_HPP) && defined(BOOST_CONFIG_SUFFIX_HPP)
# ifdef _STLP_USE_BOOST_SUPPORT_WORKAROUND
# undef _STLP_USE_BOOST_SUPPORT_WORKAROUND
* Otherwise, <utility> is "real" <utility>
* </EXTRA CODE>
#endif /* _STLP_UTILITY */
#endif /* _STLP_USE_BOOST_SUPPORT_WORKAROUND */
In other words, we will take Boost to <stl/config/features.h> right away if we know exactly that it only needs <utility> for collecting STLport settings. This will prevent both Boost and STLport from including each other.
Besides that, <utility> is a standard header so we should minimize changes in it by dropping the extra code into a separate file, e.g <stl/_stlp_use_boost_support_workaround.h>. And then our <utility> will look like this:
#endif /* _STLP_UTILITY */
#endif /* _STLP_USE_BOOST_SUPPORT_WORKAROUND */
In general, this solution will give us the following benefits:
- There is no need for modifying the outside header <boost/config/stdlib/stlport.hpp>.
- There is no need for defining BOOST_STDLIB_CONFIG="<boost/config/stdlib/stlport.hpp>".
- There is no warning of macro redefinition because all headers are only included once.
- Minimizing changes in STLport source code (we only add three lines to <utility> and remove BOOST_STDLIB_CONFIG in <stl/config/features.h>).
- Headers can be included in any order.
Its true that my solution still has its own drawback. For example, if boost switchs to another standard header to look for standard library settings, we'll have to remove our extra code from <utility> to it. An in this case, STLport users will run into trouble because of different boost versions. However, as the comment in Boost source code says, <utility> is the smallest header, and it is therefore the best choice in order to gather neccessary information.
Unfortunately, there's nothing to make sure that they will not add a smaller header into standard library in long run, as well as both <boost/config/select_stdlib_config.hpp> and <boost/config/stdlib/stlport.hpp> are not marked to be "completely stable". For this reason, it is better to (1) find a safe place to drop such extra code into it, or (2) use _STLP_USE_BOOST_SUPPORT_WORKAROUND to protect every standard headers that wrapping <stl/type_traits.h> directly or indirectly.
(2) is simple and easy but adding "#include <stl/_stlp_use_boost_support_workaround.h>" then checking for _STLP_USE_BOOST_SUPPORT_WORKAROUND in many headers is ugly.
(1) is acceptable but difficult. In fact, I haven't discover a proper header to do this yet :-(
What do you think of my new idea ?
Workarounds of such kind isn't what I would see in headers like <utility>;
You don't take into account order of inclusion, that may be very different; problems happens with other headears too. I don't want to type here samples, because all ones are bulky, and my position really expressed in trunk.
This issues are part of inclusion TR1/TR2/draft 0x, and [partially] already resolved in trunk (more-or-less, unit tests presents too); I don't want to include work under this issues into 5.1 branch, because of significant changes in public headers.
IMO the only clean solution can only come from boost. STLport only use boost for type_traits or for its tr1 implementation. I don't think those things require Standard library detection on boost side. boost would have to be more selective when Standard library has to be detected. But this is a big work, I don't expect boost guys to take time to achieve it unless their tr1 module already do so, if only I didn't had to lose my time sleeping...
Sign up for the SourceForge newsletter:
You seem to have CSS turned off.
Please don't fill out this field.