Re: [Boost-users] dynamic link error: boost::program_options::arg not found (Sebastian Hauer)
Hi Sebastian and Ovanes, I am facing the same problems as you with linking to boost::program_options, and boost::system too. In all my win32 projects (I use msvc9.0), I define BOOST_DYN_LIB using a common property sheet. It compiles just fine with 1.36.0 but it does not link. I also specify BOOST_LIB_DIAGNOSTIC so that I can see what boost auto link is trying to do. May be I should say that I built my boost 1.36.0 libraries on Win32 (Windows XP Professional SP3) using following command line: ./bjam.exe toolset=msvc --build-type=complete --build-dir="D:\tmp" --threading=multi --runtime-link=static,shared --prefix="C:\boost1.36" install --without-mpi --without-python --without-wave When I compile my project (some libraries using boost_filesystem and boost_system, some not), I can see in the compiler output: Linking to lib file: boost_filesystem-vc90-mt-1_36.lib Linking to lib file: boost_system-vc90-mt-1_36.lib When I compile my main : #include <iostream> #include <boost/program_options.hpp> namespace po = boost::program_options; int main(int argc, char **argv) { int ret = 0; po::variables_map vm; po::options_description all("Allowed options"); try { po::options_description general("General options"); general.add_options() ("help,h", "Show this message and exit.") ("version,v", "Output version information and exit."); po::options_description optional("Optional options"); optional.add_options() ("optional,o", po::value<std::string>(), "Optional") ("optional2,p", po::value<std::string>(), "Optional2"); all.add(general).add(optional); po::store(po::parse_command_line(argc, argv, all), vm); po::notify(vm); } catch (const po::invalid_command_line_syntax &badsyntax) { /* My log error with badsyntax*/ ret = -1; } catch (const po::unknown_option &badoption) { /* My log error with badoption*/ ret = -2; } catch (const po::error &err) { /* My log error with err*/ ret = -3; } if (vm.count("optional")) { std::string optionalParam = vm["optional"].as<std::string>(); /** Handling optionalParam ... */ } if (vm.count("optional2")) { std::string optionalParam2 = vm["optional2"].as<std::string>(); /** Handling optionalParam2 ... */ } if (vm.count("help")) { std::cout << all << std::endl; return 0; } return ret; } with following command line: /O2 /Ob2 /Oy /I all-my-includes-here /I "../../../../boost/include/boost-1_36" /D "BOOST_PROGRAM_OPTIONS_DYN_LINK" /D "UNICODE" /D "NDEBUG" /D "BOOST_LIB_DIAGNOSTIC" /D "BOOST_SYSTEM_DYN_LINK" /D "BOOST_FILESYSTEM_DYN_LINK" /D "BOOST_THREAD_DYN_LINK" /D "NOMINMAX" /D "WIN32_LEAN_AND_MEAN" /D "WIN32" /D "_WINDOWS" /D "_CRT_NONSTDC_NO_WARNINGS" /D "_CRT_SECURE_NO_WARNINGS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /FD /EHsc /MD /GS- /arch:SSE2 /Fo"./../../Release/MyApp/" /Fd"./../../Release/MyApp/vc90.pdb" /W3 /nologo /c /TP /wd4100 /wd4290 /errorReport:prompt -EHsc -Zm200 -w34100 -w34189 -w34189 I can see in the compiler output following lines: Linking to lib file: boost_program_options-vc90-mt-1_36.lib ../../../../boost/include/boost-1_36\boost/program_options/errors.hpp(21) : warning C4275: non dll-interface class 'std::logic_error' used as base for dll-interface class 'boost::program_options::error'
C:\Programme\MicrosoftVisualStudio9.0\VC\include\stdexcept(21) : see declaration of 'std::logic_error' ../../../../boost/include/boost-1_36\boost/program_options/errors.hpp(21) : see declaration of 'boost::program_options::error' ../../../../boost/include/boost-1_36\boost/program_options/errors.hpp(61) : warning C4251:
'boost::program_options::ambiguous_option::alternatives' : class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::ambiguous_option'
with [ _Ty=std::string ]
[snip a lot of similar warnings] Then, linking with following command line /OUT:"../../Release\MyApp.exe" /INCREMENTAL /NOLOGO /LIBPATH:"../../Release" /LIBPATH:"..\..\..\..\boost/lib/vc90" /MANIFEST /MANIFESTFILE:"../../Release/MyApp\MyApp.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /NODEFAULTLIB:"libcpmt.lib" /NODEFAULTLIB:"libcmt.lib" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /MACHINE:X86 /ERRORREPORT:PROMPT msvcrt.lib msvcprt.LIB binmode.obj kernel32.lib user32.lib netapi32.lib Iphlpapi.lib Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib I get following errors: Memain.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall boost::program_options::detail::cmdline::set_additional_parser(class boost::function1<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &>)"
(__imp_?set_additional_parser@cmdline@detail@program_options@boost@@QAEXV?$function1@U?$pair@V?$basic_string@DU?$char_traits@D@std@@V?$alloc ator@D@2@@std@@V12@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@4@@Z) referenced in function "public: class boost::program_options::basic_command_line_parser<char> & __thiscall boost::program_options::basic_command_line_parser<char>::extra_parser(class boost::function1<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char>
const &>)"
(?extra_parser@?$basic_command_line_parser@D@program_options@boost@@QAEAAV123@V?$function1@U?$pair@V?$basic_string@DU?$char_traits@D@std@@V? $allocator@D@2@@std@@V12@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@3@@Z) 1>metiscalibrationdata.lib(MetisMatrixCalibration_io.obj) : error LNK2019: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::get_generic_category(void)" (?get_generic_category@system@boost@@YAABVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'generic_category''(void)" (??__Egeneric_category@system@boost@@YAXXZ) error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const & __cdecl boost::system::get_generic_category(void)" (__imp_?get_generic_category@system@boost@@YAABVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'generic_category''(void)" (??__Egeneric_category@system@boost@@YAXXZ) 1>filesystem.lib(FileUtils.obj) : error LNK2001: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const & __cdecl boost::system::get_generic_category(void)" (__imp_?get_generic_category@system@boost@@YAABVerror_category@12@XZ) 1>filesystem.lib(FileUtils.obj) : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_code boost::filesystem::detail::throws" (__imp_?throws@detail@filesystem@boost@@3Verror_code@system@3@A) referenced in function "void __cdecl boost::filesystem::remove<class boost::filesystem::basic_path<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct boost::filesystem::path_traits> >(class boost::filesystem::basic_path<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct boost::filesystem::path_traits> const &,class boost::system::error_code &)" (??$remove@V?$basic_path@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@Upath_traits@filesystem@boost@@@filesystem@boost@@@fi lesystem@boost@@YAXABV?$basic_path@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@Upath_traits@filesystem@boost@@@01@AAVerror _code@system@1@@Z) When I open boost\include\boost-1_36\boost\program_options\detail\cmdline.hpp I can see BOOST_PROGRAM_OPTIONS_DECL declared as __declspec(dllimport) when compiling my application. When I open boost\include\boost-1_36\boost\system\error_code.hpp, I can see BOOST_SYSTEM_DECL declared as __declspec(dllimport) as well. So my question (at last!) is: how can I check if those symbols were properly exported when building boost ? thank you, Cheers, Florent ---------------------------------------------------------------------- Message: 1 Date: Wed, 17 Sep 2008 13:21:41 -0400 From: "Sebastian Hauer" <sebastian.hauer@gmail.com> Subject: Re: [Boost-users] dynamic link error: boost::program_options::arg not found To: boost-users@lists.boost.org Message-ID: <fb92d9f00809171021k8c0cf93i75f67b9564281852@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1 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
Hello Florent, To check if a symbol is exported correctly I simply use dumpbin which is a command line tool that comes with msvc. E.g.: dumpbin /exports ..\boost_1_36_0\lib.x86-nt-msvc8\boost_program_options-vc80-mt-gd-1_36.lib | grep program_options::arg The "non dll-interface" warnings are OK, but am I missing something or are you not linking against boost_program_options-*.lib ? I have to say that I currently don't use auto linking maybe you should try adding all libraries manually and turn off the auto linking feature by defining: BOOST_ALL_NO_LIB=1. Regards, Sebastian
participants (2)
-
Sebastian Hauer
-
Vial, Florent