2

I have a linker problem while compiling mongo db client example on Windows. I'm using Visual Studio 2012.

I'm trying to compile src\mongo\client\examples\clientTest.cpp from mongo's git.

I did following steps:

  • Built Boost v1.51 using bjam2. I'm using it on another project so I know binaries are good.
  • Built MongoDB C++ driver as scons --dd mongoclient.lib
  • Included boost include directory in my project as an Additional Include Directory.
  • Define _CRT_SECURE_NO_WARNINGS to avoid warnings on use of strncpy and such by the MongoDB client code.
  • Include the boost (binary) libraries directory to the project.

Still, I get following errors

1>mongoclient.lib(log.obj) : error LNK2019: unresolved external symbol "void __cdecl boost::filesystem3::path_traits::convert(char const *,char const *,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > &,class std::codecvt<wchar_t,char,int> const &)" (?convert@path_traits@filesystem3@boost@@YAXPBD0AAV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABV?$codecvt@_WDH@5@@Z) referenced in function "void __cdecl boost::filesystem3::path_traits::dispatch<class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > &,class std::codecvt<wchar_t,char,int> const &)" (??$dispatch@V?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@path_traits@filesystem3@boost@@YAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@4@ABV?$codecvt@_WDH@4@@Z)
1>mongoclient.lib(log.obj) : error LNK2019: unresolved external symbol "private: static class std::codecvt<wchar_t,char,int> const * & __cdecl boost::filesystem3::path::wchar_t_codecvt_facet(void)" (?wchar_t_codecvt_facet@path@filesystem3@boost@@CAAAPBV?$codecvt@_WDH@std@@XZ) referenced in function "public: static class std::codecvt<wchar_t,char,int> const & __cdecl boost::filesystem3::path::codecvt(void)" (?codecvt@path@filesystem3@boost@@SAABV?$codecvt@_WDH@std@@XZ)
1>mongoclient.lib(log.obj) : error LNK2019: unresolved external symbol "class boost::filesystem3::file_status __cdecl boost::filesystem3::detail::status(class boost::filesystem3::path const &,class boost::system::error_code *)" (?status@detail@filesystem3@boost@@YA?AVfile_status@23@ABVpath@23@PAVerror_code@system@3@@Z) referenced in function "bool __cdecl boost::filesystem3::exists(class boost::filesystem3::path const &)" (?exists@filesystem3@boost@@YA_NABVpath@12@@Z)
1>mongoclient.lib(background.obj) : error LNK2019: unresolved external symbol "public: __thiscall boost::thread::~thread(void)" (??1thread@boost@@QAE@XZ) referenced in function "public: class mongo::BackgroundJob & __thiscall mongo::BackgroundJob::go(void)" (?go@BackgroundJob@mongo@@QAEAAV12@XZ)

So it looks like it ignores #pragma comment lib directives in boost's headers.

I tried explicitly adding libboost_thread-vc110-mt-sgd-1_51.lib in Linker/Input tab of project settings. It didn't help.

I tried specifying #pragma comment(lib, "libboost_thread-vc110-mt-sgd-1_51.lib") in main cpp file of the example. It didn't help either.

But! Adding

#include <boost/thread/thread.hpp>

and

boost::thread _thrd(&Func);
_thrd.join();

at the beginning of clientTest.cpp helped to get rid of error about missing boost::thread::~thread(void). Looks like it forced linker to link to thread's lib binary.

Unfortunately repeating this trick with <boost/filesystem.hpp> didn't help :(

I also made sure that all LIB files, of Boost and Mongo client, are compiled for 32-bit target using dumpbin.exe.

What else could it be guys ?

Thanks!

4

2 回答 2

1

Looks like my messages to mongo-dev mailing list don't reach the destination. Perhaps it's premoderated.

But I managed to make it work via a bit hacky solution because I never used Scons before.

Core of the problem was that mongo is prebundled with Boost 1.49 and I have Boost 1.51 installed in my system. I was trying to compile sample against boost 1.51 while mongo was compiled with 1.49 therefore mismatch of certain classes/methods.

I built library by calling

scons -j4 --dd --use-system-boost mongoclient.lib

Also I modified SConstruct script. Find line elif "win32" == os.sys.platform:. In this section I added

env.Append( EXTRACPPPATH=[ "C:/work/externals/boost_1_51_0" ] )

to specify additional "system" folder.

Also I had to disable existence check of boost binary libraries which looked like

    for b in boostLibs:
        l = "boost_" + b
        if not conf.CheckLib([ l + boostCompiler + "-mt" + boostVersion,
                               l + boostCompiler + boostVersion ], language='C++' ):
            Exit(1)

because naming of my libraries is very different.

Of course it doesn't cover situation when boost is dynamically compiled with MSVC libraries.

I hope Mongo team or somebody who knows Scons well will modify build script to

  • Allow to specify path to system boost library
  • Allow building dynamically linked libraries for MSVC
于 2012-10-31T18:45:29.913 回答
0

Solution for Mac OS

I know this is not a place to post the answer for Mac OS. But, I was struggling for a couple of days solving the msgasserted linker error and finally got it to work...

mmacosx-version-min=10.5 should be added to the command line.

g++ -m64 -I/Users/accessmac/mgoclient/include -L/Users/accessmac/mgoclient/lib second.cpp -lboost_system-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_thread-mt -lmongoclient  -mmacosx-version-min=10.5 -o second

compiles and produces second

于 2014-05-03T11:28:44.587 回答