dynamic link error: boost::program_options::arg not found

Hi, I am trying to dynamically link one of my *libraries* to boost program_options on windows with msvc-8.0 but linking fails due to a missing symbol. Quickly googling for this problem revealed no resolution to my problem, although it appears other people ran into this issue before. Did anyone resolve it or is everyone linking boost program_options statically? I initially ran into this issue on boost 1_34_1 but have since upgraded to 1_36 hoping it would have gotten fixed with no luck. error LNK2001: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > boost::program_options::arg" (?arg@program_options@boost@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A) Here is the link command line: link /NOLOGO /INCREMENTAL:NO /DLL /DEBUG /subsystem:console /out:"foo.dll" /IMPLIB:"foo.lib" /LIBPATH:"..\boost_1_36_0\lib.x86-nt-msvc8" @"foo.dll.rsp" And foo.dll.rsp contains besides the name of my object files also references to the following external import libraries: "boost_date_time-vc80-mt-gd-1_36.lib" "boost_filesystem-vc80-mt-gd-1_36.lib" "boost_program_options-vc80-mt-gd-1_36.lib" "boost_system-vc80-mt-gd-1_36.lib" Thanks, Sebastian

Hi! I had the same problem. This seems to be an MS bug. In our case using VC++ 7.1 we compiled an application with 4 byte struct member alignment and were unable to link it. Using the dependency walker has shown, that this symbol is differently exported in program_options.dll as expected from the linker which links to the DLL. I remember that I have written what we did to resolve the problem. Here is my previous post: http://groups.google.am/group/boost-list/browse_frm/thread/3ec1940f2517241f/... We had the similar issue with boost::filesystem and 4 byte alignment as well. With Kind Regards, Ovanes On Wed, Sep 17, 2008 at 5:29 PM, Sebastian Hauer <sebastian.hauer@gmail.com>wrote:
[...] error LNK2001: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > boost::program_options::arg" (?arg@program_options@boost@@3V?$basic_string@DU?$char_traits@D@std@ @V?$allocator@D@2@@std@@A) [...]

Hello Ovanes, thanks for the reply. I fixed it. I eventually found your posting and tried your suggestion attributing boost::program_options::arg with an additional __declspec(selectany) but either I did something wrong or things are different with msvc-8.0 it did not work for me. Instead I went down a different path and got rid of the global arg variable altogether. Since nothing seems to write into it and the value is always copied it seemed like a reasonable thing to do considering it causes so much grief with the linking. Once this was fixed I got another linker error: error LNK2001: unresolved external symbol "public: static unsigned int const boost::program_options::options_description::m_default_line_length" (?m_default_line_length@options_description@program_options@boost@@2IB) I found the solution to that one from this posting from Evert at http://archives.free.net.ph/message/20080815.085344.d72efb54.en.html . Once I changed the declaration of the class static const m_default_line_length to: BOOST_STATIC_CONSTANT (unsigned, m_default_line_length = 80); With these two changes in place all compiled and linked without a problem. Below I've inlined the patch of my changes against the original boost_1_36_0 source as reference for other people running into this issue. If these changes seem like a good idea to others perhaps they could be included with the next boost release. Regards, Sebastian diff -ru -x '*~' boost_1_36_0_src_orig/boost/program_options/detail/value_semantic.hpp boost_1_36_0_src/boost/program_options/detail/value_semantic.hpp --- boost_1_36_0_src_orig/boost/program_options/detail/value_semantic.hpp 2007-11-25 13:07:19.000000000 -0500 +++ boost_1_36_0_src/boost/program_options/detail/value_semantic.hpp 2008-09-17 12:36:20.447677200 -0400 @@ -10,12 +10,11 @@ namespace boost { namespace program_options { - extern BOOST_PROGRAM_OPTIONS_DECL std::string arg; - template<class T, class charT> std::string typed_value<T, charT>::name() const { + static std::string arg("arg"); if (!m_implicit_value.empty() && !m_implicit_value_as_text.empty()) { std::string msg = "[=arg(=" + m_implicit_value_as_text + ")]"; if (!m_default_value.empty() && !m_default_value_as_text.empty()) diff -ru -x '*~' boost_1_36_0_src_orig/boost/program_options/options_description.hpp boost_1_36_0_src/boost/program_options/options_description.hpp --- boost_1_36_0_src_orig/boost/program_options/options_description.hpp 2007-11-25 13:07:19.000000000 -0500 +++ boost_1_36_0_src/boost/program_options/options_description.hpp 2008-09-17 12:35:37.306223900 -0400 @@ -155,8 +155,8 @@ */ class BOOST_PROGRAM_OPTIONS_DECL options_description { public: - static const unsigned m_default_line_length; - + BOOST_STATIC_CONSTANT (unsigned, m_default_line_length = 80); + /** Creates the instance. */ options_description(unsigned line_length = m_default_line_length); /** Creates the instance. The 'caption' parameter gives the name of diff -ru -x '*~' boost_1_36_0_src_orig/libs/program_options/src/options_description.cpp boost_1_36_0_src/libs/program_options/src/options_description.cpp --- boost_1_36_0_src_orig/libs/program_options/src/options_description.cpp 2007-11-25 13:38:02.000000000 -0500 +++ boost_1_36_0_src/libs/program_options/src/options_description.cpp 2008-09-17 13:07:03.748692900 -0400 @@ -201,8 +201,6 @@ return *this; } - const unsigned options_description::m_default_line_length = 80; - options_description::options_description(unsigned line_length) : m_line_length(line_length) {} diff -ru -x '*~' boost_1_36_0_src_orig/libs/program_options/src/value_semantic.cpp boost_1_36_0_src/libs/program_options/src/value_semantic.cpp --- boost_1_36_0_src_orig/libs/program_options/src/value_semantic.cpp 2007-11-25 13:38:02.000000000 -0500 +++ boost_1_36_0_src/libs/program_options/src/value_semantic.cpp 2008-09-17 12:40:16.983468600 -0400 @@ -64,12 +64,10 @@ } #endif - BOOST_PROGRAM_OPTIONS_DECL std::string arg("arg"); - std::string untyped_value::name() const { - return arg; + return "arg"; } unsigned
participants (2)
-
Ovanes Markarian
-
Sebastian Hauer