Program Options failures (and fixes)

Vladimir, I have some fixes for the program_options library on Win32 for you, first off here's the problem: On Win32 you must use the a dynamic runtime if you are building or using a dll: if you don't do this then separate runtimes/memory managers etc get linked to each module and the result is almost always a runtime crash some point. However you are also using std::locale and so have added std::facet-support std::locale-support to your build requirements. Doing so however, causes the static runtime to be used, so you're in a bit of a catch-22 situation here I'm afraid. You've also failed to define BOOST_ALL_DYN_LINK when *using* your dll - this is causing the mscv link failures. The patches below address both of these issues, tested with: VC7.1: everything passes. VC7.0: everything passes except the tests that use \u (unsupported). Intel 8 on vc7.1: everything passes. Intel 7.1 on vc7.1 everything pases except the tests that use \u (unsupported). Borland 5.6.4: all tests pass. Borland 5.5.1: Internal compiler error in function from_8bit, haven't investigated further yet. The fact that these tests do pass with Intel, possibly means that std::facet-support could be deprecated - it looks like Intel have fixed that problem with their recent patches. However, you may still experience problems with Metrowerks - I think there is any way around this - the dll version of the library is going to be unusable with that compiler. One final thing: you declare the environ variable in your sources, which is leading to warnings from MSVC and Intel about conflicting dll-specifications for that variable, perhaps you should include the header required rather than defining the variable yourself (unistd.h when BOOST_HAS_UNISTD_H is defined, or stdlib.h on WIN32)? John Index: build/Jamfile =================================================================== RCS file: /cvsroot/boost/boost/libs/program_options/build/Jamfile,v retrieving revision 1.2 diff -u -r1.2 Jamfile --- build/Jamfile 18 May 2004 06:38:17 -0000 1.2 +++ build/Jamfile 14 Jul 2004 10:32:56 -0000 @@ -21,7 +21,7 @@ <define>BOOST_ALL_DYN_LINK=1 # tell source we're building dll's <runtime-link>dynamic # build only for dynamic runtimes <include>$(BOOST_ROOT) <sysinclude>$(BOOST_ROOT) - std::facet-support std::locale-support + #std::facet-support std::locale-support : debug release # build variants ; cvs diff: Diffing doc cvs diff: Diffing example cvs diff: Diffing src cvs diff: Diffing test Index: test/Jamfile =================================================================== RCS file: /cvsroot/boost/boost/libs/program_options/test/Jamfile,v retrieving revision 1.4 diff -u -r1.4 Jamfile --- test/Jamfile 28 Jun 2004 09:31:28 -0000 1.4 +++ test/Jamfile 14 Jul 2004 10:32:56 -0000 @@ -19,7 +19,9 @@ run $(name).cpp <dll>../build/boost_program_options <lib>../../test/build/boost_test_exec_monitor : : : <include>$(BOOST_ROOT) - std::facet-support std::locale-support + #std::facet-support std::locale-support + <define>BOOST_ALL_DYN_LINK=1 + <runtime-link>dynamic : $(name)_dll ] ; }

Hi John,
I have some fixes for the program_options library on Win32 for you, first off here's the problem:
On Win32 you must use the a dynamic runtime if you are building or using a dll: if you don't do this then separate runtimes/memory managers etc get linked to each module and the result is almost always a runtime crash some point.
And the tests themself must be build with dynamic runtime, right? It would took me a lot of time to figure out.
However you are also using std::locale and so have added std::facet-support std::locale-support to your build requirements. Doing so however, causes the static runtime to be used, so you're in a bit of a catch-22 situation here I'm afraid.
Ah... that's troublesome.
You've also failed to define BOOST_ALL_DYN_LINK when *using* your dll - this is causing the mscv link failures.
Thanks for figuring this out. But... how comes that *everything* works except for importing a variable. I recall reading that __declspec(dllimport) on functions is just an optimization -- maybe this is the explanation.
The patches below address both of these issues, tested with:
VC7.1: everything passes.
Great. Once I'll have all-pass in main regression results, I'll switch all tests to use dynamic linking, to reduce the testing overhead.
VC7.0: everything passes except the tests that use \u (unsupported).
Intel 8 on vc7.1: everything passes.
Intel 7.1 on vc7.1 everything pases except the tests that use \u (unsupported).
Borland 5.6.4: all tests pass.
Borland 5.5.1: Internal compiler error in function from_8bit, haven't investigated further yet.
The fact that these tests do pass with Intel, possibly means that std::facet-support could be deprecated - it looks like Intel have fixed that problem with their recent patches. However, you may still experience problems with Metrowerks - I think there is any way around this - the dll version of the library is going to be unusable with that compiler.
That's not good, but anyway, I think dropping DLL on one compiler is not so terrible.
One final thing: you declare the environ variable in your sources, which is leading to warnings from MSVC and Intel about conflicting dll-specifications for that variable, perhaps you should include the header required rather than defining the variable yourself (unistd.h when BOOST_HAS_UNISTD_H is defined, or stdlib.h on WIN32)?
Yes, though my man pages say that on Linux, this variable must be defined in user program. I'll make an attempt to define it only when not on windows.
Index: build/Jamfile
Thanks for helping out! I've comitted the modification you've suggested. - Volodya

And the tests themself must be build with dynamic runtime, right? It would took me a lot of time to figure out.
Yes.
Thanks for figuring this out. But... how comes that *everything* works except for importing a variable. I recall reading that __declspec(dllimport) on functions is just an optimization -- maybe this is the explanation.
I don't know: VC7.1 at least mangles the names differently when __declspec(dllimport) is used. In fact when I built from the IDE I got initially got errors from the free-functions as well, but I didn't see those on the command line for some reason :-( John.

Vladimir, Some more patches for you, this time for cygwin, they don't get all the tests passing, in particular the dll doesn't build and all the wide character tests fail because there is no wstring support, but at least the library builds and some tests now pass, Regards, John. Index: boost/program_options/value_semantic.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/program_options/value_semantic.hpp,v retrieving revision 1.4 diff -u -r1.4 value_semantic.hpp --- boost/program_options/value_semantic.hpp 13 Jul 2004 15:12:25 -00001.4 +++ boost/program_options/value_semantic.hpp 14 Jul 2004 11:51:06 -0000 @@ -100,11 +100,12 @@ const std::vector<std::string>& new_tokens, bool utf8) const; protected: // interface for derived classes. +#if !defined(BOOST_NO_STD_WSTRING) virtual void xparse(boost::any& value_store, const std::vector<std::wstring>& new_tokens) const = 0; +#endif }; - /** Class which specify handling of value for which user did not specified anything. */ class BOOST_PROGRAM_OPTIONS_DECL cvs diff: Diffing boost/program_options/detail Index: boost/program_options/detail/convert.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/program_options/detail/convert.hpp,v retrieving revision 1.10 diff -u -r1.10 convert.hpp --- boost/program_options/detail/convert.hpp 13 Jul 2004 15:12:25 -00001.10 +++ boost/program_options/detail/convert.hpp 14 Jul 2004 11:51:06 -0000 @@ -8,6 +8,8 @@ #include <boost/program_options/config.hpp> +#if !defined(BOOST_NO_STD_WSTRING) + #include <boost/detail/workaround.hpp> #include <string> @@ -84,4 +86,22 @@ $ } +#else +#include <vector> +#include <string> +namespace boost{ + namespace program_options{ + BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string&); + + template<class T> + std::vector<std::string> to_internal(const std::vector<T>& s) + { + std::vector<std::string> result; + for (unsigned i = 0; i < s.size(); ++i) + result.push_back(to_internal(s[i])); + return result; + } + } +} +#endif #endif Index: boost/program_options/detail/value_semantic.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/program_options/detail/value_semantic.hpp,v retrieving revision 1.7 diff -u -r1.7 value_semantic.hpp --- boost/program_options/detail/value_semantic.hpp 13 Jul 2004 15:12:25 -00 00 1.7 +++ boost/program_options/detail/value_semantic.hpp 14 Jul 2004 11:51:06 -00 00 @@ -90,11 +90,12 @@ bool*, int); +#if !defined(BOOST_NO_STD_WSTRING) BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v, const std::vector<std::wstring>& xs, bool*, int); - +#endif // For some reason, this declaration, which is require by the standard, // cause gcc 3.2 to not generate code to specialization defined in // value_semantic.cpp @@ -107,11 +108,13 @@ std::string*, int); +#if !defined(BOOST_NO_STD_WSTRING) BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v, const std::vector<std::wstring>& xs, std::string*, int); #endif +#endif /** Validates sequences. Allows multiple values per option occurence and multiple occurences. */ cvs diff: Diffing libs/program_options cvs diff: Diffing libs/program_options/build Index: libs/program_options/build/Jamfile =================================================================== RCS file: /cvsroot/boost/boost/libs/program_options/build/Jamfile,v retrieving revision 1.2 diff -u -r1.2 Jamfile --- libs/program_options/build/Jamfile 18 May 2004 06:38:17 -0000 1.2 +++ libs/program_options/build/Jamfile 14 Jul 2004 11:51:06 -0000 @@ -21,7 +21,7 @@ <define>BOOST_ALL_DYN_LINK=1 # tell source we're building dll's <runtime-link>dynamic # build only for dynamic runtimes <include>$(BOOST_ROOT) <sysinclude>$(BOOST_ROOT) - std::facet-support std::locale-support + #std::facet-support std::locale-support : debug release # build variants ; cvs diff: Diffing libs/program_options/doc cvs diff: Diffing libs/program_options/example cvs diff: Diffing libs/program_options/src Index: libs/program_options/src/value_semantic.cpp =================================================================== RCS file: /cvsroot/boost/boost/libs/program_options/src/value_semantic.cpp,v retrieving revision 1.7 diff -u -r1.7 value_semantic.cpp --- libs/program_options/src/value_semantic.cpp 13 Jul 2004 15:12:26 -00001.7 +++ libs/program_options/src/value_semantic.cpp 14 Jul 2004 11:51:07 -0000 @@ -123,6 +123,7 @@ // since wstring can't be constructed/compared with char*. We'd need to // create auxilliary 'widen' routine to convert from char* into // needed string type, and that's more work. +#if !defined(BOOST_NO_STD_WSTRING) BOOST_PROGRAM_OPTIONS_DECL void validate(any& v, const vector<wstring>& xs, bool*, int) { @@ -139,7 +140,7 @@ else throw validation_error("invalid bool value"); } - +#endif BOOST_PROGRAM_OPTIONS_DECL void validate(any& v, const vector<string>& xs, std::string*, int) { @@ -152,6 +153,7 @@ v = any(s); } +#if !defined(BOOST_NO_STD_WSTRING) BOOST_PROGRAM_OPTIONS_DECL void validate(any& v, const vector<wstring>& xs, std::string*, int) { @@ -163,7 +165,7 @@ else v = any(s); } - +#endif namespace validators { cvs diff: Diffing libs/program_options/test Index: libs/program_options/test/Jamfile =================================================================== RCS file: /cvsroot/boost/boost/libs/program_options/test/Jamfile,v retrieving revision 1.4 diff -u -r1.4 Jamfile --- libs/program_options/test/Jamfile 28 Jun 2004 09:31:28 -0000 1.4 +++ libs/program_options/test/Jamfile 14 Jul 2004 11:51:07 -0000 @@ -19,7 +19,9 @@ run $(name).cpp <dll>../build/boost_program_options <lib>../../test/build/boost_test_exec_monitor : : : <include>$(BOOST_ROOT) - std::facet-support std::locale-support + #std::facet-support std::locale-support + <define>BOOST_ALL_DYN_LINK=1 + <runtime-link>dynamic : $(name)_dll ] ; }

Hi John,
Some more patches for you, this time for cygwin, they don't get all the tests passing, in particular the dll doesn't build and all the wide character tests fail because there is no wstring support, but at least the library builds and some tests now pass,
Thanks again! Is it possible, though, to resent the patch as attachmenent. It seems it was damaged along the way.
- /** Class which specify handling of value for which user did not specified anything. */
Like here, which I can fix.
+#if !defined(BOOST_NO_STD_WSTRING) + #include <boost/detail/workaround.hpp>
#include <string> @@ -84,4 +86,22 @@ $ }
And like here -- 'patch' is really upset with the '$' symbol and I have no idea why it's there..... Thanks, Volodya
participants (2)
-
John Maddock
-
Vladimir Prus