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
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::valuestd::string(), "Optional")
("optional2,p", po::valuestd::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"].asstd::string();
/** Handling optionalParam ... */
}
if (vm.count("optional2"))
{
std::string optionalParam2 = vm["optional2"].asstd::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,class std::basic_string
,class std::basic_string 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,class std::basic_string >,class std::basic_string
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,struct boost::filesystem::path_traits> >(class boost::filesystem::basic_path,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"
Subject: Re: [Boost-users] dynamic link error:
boost::program_options::arg not found
To: boost-users@lists.boost.org
Message-ID:
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