[CDRIVER-2054] Windows static build is broken in 1.5.0 Created: 06/Feb/17  Updated: 03/May/17  Resolved: 08/Mar/17

Status: Closed
Project: C Driver
Component/s: None
Affects Version/s: 1.5.0
Fix Version/s: 1.7.0

Type: Bug Priority: Major - P3
Reporter: Rustam Abdullaev Assignee: A. Jesse Jiryu Davis
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive mongotest.zip    
Issue Links:
Related
related to CDRIVER-2037 Distribute pkg-config files for dynam... Closed
related to CDRIVER-1347 Define per symbol visibility rather t... Closed
Epic Link: convenient-static

 Description   

As of libmongoc 1.5.0, attempting to link applications against the static build of the driver will fail with the error that symbols like "__imp_bson_iter_init" and "__imp_mongoc_read_prefs_new" cannot be resolved.

Original description:

Linking with bson-static-1.0.lib, mongoc-static-1.0.lib, libbsoncxx.lib, libmongocxx.lib worked in version 3.0.1 but fails with 3.1.0:

1>libbsoncxx.lib(view.cpp.obj) : error LNK2001: unresolved external symbol __imp_bson_iter_init
1>libbsoncxx.lib(core.obj) : error LNK2001: unresolved external symbol __imp_bson_iter_init
1>libbsoncxx.lib(view.cpp.obj) : error LNK2001: unresolved external symbol __imp_bson_iter_init
1>libbsoncxx.lib(view.cpp.obj) : error LNK2001: unresolved external symbol __imp_bson_iter_init_find
1>libbsoncxx.lib(view.cpp.obj) : error LNK2001: unresolved external symbol __imp_bson_iter_init_find
1>libbsoncxx.lib(view.cpp.obj) : error LNK2001: unresolved external symbol __imp_bson_iter_next
etc, etc.



 Comments   
Comment by levuphuong [ 23/Mar/17 ]

Hi

I pull new source code and change my project win32 to x64 platform which is same with mongoc platform build tool on windows.
Now it is successfully built without error.

Thanks so much.

Comment by Githook User [ 21/Mar/17 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-2054 use MONGOC_EXPORT for gridfs funs
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/14cc86790f158288da4dad636d904064a91dee06

Comment by Githook User [ 21/Mar/17 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-2054 use MONGOC_EXPORT for exports

We'd used BSON_EXPORT, but that doesn't work now because it was updated
in libbson commit 5b5b74e0. Now, if BSON_COMPILATION isn't defined,
BSON_EXPORT does not export symbols. We should properly make a new
macro MONGOC_EXPORT that exports symbols iff MONGOC_COMPILATION is set.
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/6341c7fecbb828fa0f8df6020dc7beeb355400bd

Comment by levuphuong [ 20/Mar/17 ]

I make sure mongoc_static-1.0.lib added already. I added libs with config VC ++> Library Directories, Linker>Input and also checked with 2 lines code. no error with these lines.

#pragma comment( lib, "bson-static-1.0.lib" )
#pragma comment( lib, "mongoc-static-1.0.lib" )

I also try to create sample .lib and then add to my project. it worked fine.

i have problem "_imp_mongoc" when
#include "mongoc.h"
then i changed

#define BSON_STATIC
#include "mongoc.h"

The problem is "_imp_mongoc".

I think "_imp_bson", "_imp_mongoc" and "_mongoc" also relate to prefix in "bson-macros.h" file.
And I also suspect problem my project use C++ and the lib in C which i showed problem in below link.
https://github.com/mongodb/libbson/commit/5b5b74e0f045d7c639bc071d124515e2c982c29e

Thanks.

Comment by Rustam Abdullaev [ 19/Mar/17 ]

This will not fix "unresolved external symbol _mongoc_init". You probably forgot to link with mongoc_static-1.0.lib.

This particular issue is limited to __imp_bson_ related errors. Once libbson is bumped and BSON_STATIC is added to static builds, __imp_bson_ related errors should go away.

Comment by levuphuong [ 09/Mar/17 ]

I am sorry but i still get error.
My simple test cpp in MS C++ studio still has error:
error LNK2019: unresolved external symbol _mongoc_init referenced in function _wmain
I commented in the commit. Can you take a look and help me find out solution?
https://github.com/mongodb/libbson/commit/5b5b74e0f045d7c639bc071d124515e2c982c29e

Comment by Githook User [ 06/Mar/17 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-2054 fix libbson static lib in MSVC
Branch: master
https://github.com/mongodb/libbson/commit/5b5b74e0f045d7c639bc071d124515e2c982c29e

Comment by A. Jesse Jiryu Davis [ 02/Mar/17 ]

I'm going to submit a libbson fix to for code review. Then:

  • libmongoc fix
  • Instructions in both libs' docs
  • C++ Driver update to take advantage of the fixes
  • Update C++ Driver docs if needed
Comment by levuphuong [ 02/Mar/17 ]

Hi @Rustam Abdullaev
I have "__mpl" problem when i call API. and my project is using visual studio 2012. So i cannot build mongocxx.
And I also tried to define BSON_API or BSON_COMPILATION, but it causes many other errors.

Can you share me the way hack to use static library C on Windows?

Comment by Hannes Magnusson [ 15/Feb/17 ]

Thank you for the detailed analysis.

You are correct that we do not have any tests for static builds in evergreen at the moment.

Comment by J Rassi [ 15/Feb/17 ]

I can reproduce rustyx's issue with their attached project. Building on Rustam's investigation, the cause of this issue appears to be a libmongoc regression introduced in 1.5.0 by CDRIVER-1347, which breaks the static build of the C driver on Windows. When I attempt to reproduce this issue with Rustam's attached project against mongocxx r3.0.3, the build succeeds when I have libmongoc da7e2e2 installed (just prior to first commit of CDRIVER-1347), and fails when I have libmongoc 44765ab installed (last commit of CDRIVER-1347). As such, I'm moving this issue to CDRIVER.

CDRIVER-1347 applies the BSON_API macro to the entire API surface of the driver. Based on my reading of CDRIVER-1347, the original intent of doing this was to add __attribute__((visibility("default"))) to all API function declarations when __GNUC__ is defined; however, this also unconditionally adds __declspec(dll*) to all API function declarations when _MSC_VER is defined, and it's not clear to me whether that was considered at the time. The issue is that __declspec(dll*) should only be applied when building/using the shared library on Windows, not when building/using the static library on Windows. The analogous logic for the legacy C++ driver is here: https://github.com/mongodb/mongo-cxx-driver/blob/legacy-1.1.2/src/mongo/client/export_macros.h#L43-L55. The symptom of this issue is that the DLL-ified symbol names that the application is looking for (e.g. "__imp__bson_iter_init") don't match the symbol names exported by the libmongoc/libbson static libraries (e.g. "bson_iter_init").

The C++ driver team never noticed this issue, as we currently have no build integration for static libmongoc at all, Windows or otherwise (I'll be filing a ticket for this shortly, and linking it here). However, four of our users noticed this in the past week or two (users Simon and Romain at https://groups.google.com/forum/#!topic/mongodb-user/iUaqAMScXMM, user Pia_who_love_Sia at http://stackoverflow.com/questions/42003413/mongocxx-in-windows-lnk2001-unresolved-external-symbol-imp-mongoc-read-prefs, and Rustam, on this ticket) when they upgraded to mongocxx 3.1.x, which requires libmongoc 1.5.0+. These users are manually listing mongoc-static-1.0.lib / bson-static-1.0.lib as project library dependencies in Visual Studio.

Does the C driver Evergreen integration attempt to compile the examples against a static build of the driver? If not, then we should certainly file a ticket for that as well, as I believe that would have also caught this issue.

Rustam reports above that the hack of defining BSON_COMPILATION while building mongocxx appears to work around this issue (by forcing BSON_API to expand to __declspec(dllexport), so the symbol names match), but I'm not sure if there are any other adverse affects of doing this. Linking against the dynamic build of the C driver also avoids this issue, but I would guess that that isn't feasible for all users.

Thank you so much for your original report, your reproducible case, and your patience, rustyx!

Comment by Rustam Abdullaev [ 08/Feb/17 ]

Please try using it.

bson-static-1.0.lib is fine, but it can't be used. As the header declares everything __declspec(dllimport) none of entries in bson-static-1.0.lib can be found as everything gets the __imp__ prefix.

Comment by A. Jesse Jiryu Davis [ 08/Feb/17 ]

I don't think this is a libbson build bug. Our CMakeLists.txt defines BSON_COMPILATION:

https://github.com/mongodb/libbson/blob/1.6.0/CMakeLists.txt#L202

I've rebuilt the driver just now with VS 2015 according to the standard build instructions:

cmake -G 'Visual Studio 14 2015 Win64'
MSBuild.exe /m ALL_BUILD.vcxproj
dumpbin /SYMBOLS bson-static-1.0.lib

This shows that "bson_iter_init" is defined. There's no "__imp__bson_iter_init".

Comment by David Golden [ 07/Feb/17 ]

Thank you. We'll take a look.

Comment by Rustam Abdullaev [ 07/Feb/17 ]

Added test project

Comment by David Golden [ 07/Feb/17 ]

Rustam, I'd like to try to replicate this locally and diagnose it. Could you please send/attach/post the build-equivalent of an SSCCE? I.e. The exact step by step commands you're executing to get the failure you described and the exact step by step commands you're executing to get the success?

Thank you!

Comment by Rustam Abdullaev [ 06/Feb/17 ]

Don't think it's a versioning issue because adding "/D BSON_COMPILATION" to CMAKE_CXX_FLAGS for libbsoncxx fixes the issue.

I tried libmongoc 1.6.0 and master with libmongocxx (release/stable).

Comment by David Golden [ 06/Feb/17 ]

Hi, Rustam. Which specific version of libmongoc do you have installed? 3.1.0 requires libmongoc 1.5 or later, so you might be missing those symbols because you have an old version. See the mongoc releases page to get updated source.

Comment by Rustam Abdullaev [ 06/Feb/17 ]

Seems to be caused by this code in libbson / bson-macros.h:

#ifdef _MSC_VER
#ifdef BSON_COMPILATION
#define BSON_API __declspec(dllexport)
#else
#define BSON_API __declspec(dllimport)
#endif

I think that BSON_COMPILATION was defined before, and that's why it kind of worked (at least I don't know what happens with functions declared dllexport in a static lib).

But obviously that is not the solution. There should be a way to specify BSON_STATIC and #define BSON_API as empty.

Generated at Wed Feb 07 21:14:01 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.