chillitom
chillitom

Reputation: 25686

Linking static libs built with VS2008 from a VS2012 project? Are they compatible?

I have a bunch of static .lib files including mysqlclient.lib, v8_base.lib and mysqlpp.lib that I link into my project, these were all built using Visual Studio 2008, they are built using the /MT runtime library option.

I've just tried upgrading to VS2012 and the code compiles fine but when the project get linked I get the following errors (over 500 errors in total):

Error   47  error LNK2019: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ) referenced in function "public: void __thiscall std::ios_base::clear(int,bool)" (?clear@ios_base@std@@QAEXH_N@Z)  D:\server\mysqlpp.lib(dbdriver.obj) server
Error   48  error LNK2001: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ)   D:\server\mysqlpp.lib(datetime.obj) server
Error   49  error LNK2001: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ)   D:\server\mysqlpp.lib(stadapter.obj)    server
Error   50  error LNK2001: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ)   D:\server\mysqlpp.lib(sqlstream.obj)    server
Error   51  error LNK2001: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ)   D:\server\mysqlpp.lib(connection.obj)   server
Error   52  error LNK2001: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ)   D:\server\mysqlpp.lib(mystring.obj) server
Error   53  error LNK2001: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ)   D:\server\mysqlpp.lib(row.obj)  server
Error   54  error LNK2001: unresolved external symbol "public: __thiscall std::_Mutex::~_Mutex(void)" (??1_Mutex@std@@QAE@XZ)   D:\server\mysqlpp.lib(query.obj)    server
Error   55  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(dbdriver.obj) server
Error   56  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(datetime.obj) server
Error   57  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(stadapter.obj)    server
Error   58  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(sqlstream.obj)    server
Error   59  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(connection.obj)   server
Error   60  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(mystring.obj) server
Error   61  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(row.obj)  server
Error   62  error LNK2001: unresolved external symbol "long const std::_BADOFF" (?_BADOFF@std@@3JB) D:\server\mysqlpp.lib(query.obj)    server
Error   63  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(qparms.obj)   server
Error   64  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(sqlstream.obj)    server
Error   65  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(options.obj)  server
Error   66  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(field_types.obj)  server
Error   67  error LNK2019: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) referenced in function "public: char __thiscall mysqlpp::SQLTypeAdapter::at(unsigned int)const " (?at@SQLTypeAdapter@mysqlpp@@QBEDI@Z)  D:\server\mysqlpp.lib(stadapter.obj)    server
Error   68  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(manip.obj)    server
Error   69  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(null.obj) server
Error   70  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(datetime.obj) server
Error   71  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(type_info.obj)    server
Error   72  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(vallist.obj)  server
Error   73  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(field_names.obj)  server
Error   74  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(query.obj)    server
Error   75  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(dbdriver.obj) server
Error   76  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(tcp_connection.obj)   server
Error   77  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(uds_connection.obj)   server
Error   78  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(connection.obj)   server
Error   79  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(mystring.obj) server
Error   80  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(row.obj)  server
Error   81  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xran(void)" (?_Xran@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(result.obj)   server
Error   82  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(null.obj) server
Error   83  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(qparms.obj)   server
Error   84  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(sqlstream.obj)    server
Error   85  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(field_types.obj)  server
Error   86  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(stadapter.obj)    server
Error   87  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(manip.obj)    server
Error   88  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(utility.obj)  server
Error   89  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(datetime.obj) server
Error   90  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(type_info.obj)    server
Error   91  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(vallist.obj)  server
Error   92  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(field_names.obj)  server
Error   93  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(query.obj)    server
Error   94  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(dbdriver.obj) server
Error   95  error LNK2001: unresolved external symbol "public: static void __cdecl std::_String_base::_Xlen(void)" (?_Xlen@_String_base@std@@SAXXZ) D:\server\mysqlpp.lib(tcp_connection.obj)   server

Do the runtime symbols defined by VS2012's standard libraries differ from those suplied with VS2008?

Upvotes: 3

Views: 6678

Answers (2)

Alatun
Alatun

Reputation: 121

MS is sometimes changing the implementation of standard library functions. I just had to fix a similar problem, where the calling convention of std::_String_base::_Xran () and Xlen had been switched from thiscall to cdecl. You must find out, what happened between the different versions. Then it is possible to fix this by wrappers that export functions with the required calling convention and name decoration and redirect to the new implementation.

#include <string>

namespace std2008
{
class _String_base_2008
{ 
    public:
        __declspec(dllexport) void _Xlen2008(void) const; 
        __declspec(dllexport) void _Xran2008(void) const; 
};
};

void std2008::_String_base_2008::_Xran2008 () const
{
    std::_String_base::_Xran ();
}

void std2008::_String_base_2008::_Xlen2008 () const
{
    std::_String_base::_Xlen ();
}

Save this code as "compat.cpp" and compile with

cl /D_DLL_EXPORT /EHsc /LD compat.cpp /link

Now lets examine the lib file, that has been created:

dumpbin /exports compat.lib

In my case it looks like this:

Dump of file compat.lib

File Type: LIBRARY

     Exports

       ordinal    name

                  ?_Xlen2008@_String_base_2008@std2008@@QBEXXZ (public: void __thiscall std2008::_String_base_2008::_Xlen2008(void)const )
                  ?_Xran2008@_String_base_2008@std2008@@QBEXXZ (public: void __thiscall std2008::_String_base_2008::_Xran2008(void)const )

When looking at the linker errors about missing symbols, you see the decoration that is required. In your case its "?_Xran@_String_base@std@@SAXXZ" and "?_Xlen@_String_base@std@@SAXXZ"

The last step is to tell the linker to create a library that maps the standard decorated names to a another name using the symbols from your linker error and the names taken from dumpbin.

cl /EHsc /LD compat.cpp /link /export:_Xran@_String_base@std@@SAXXZ=?_Xran2008@_String_base_2008@std2008@@QBEXXZ /export:?_Xlen@_String_base@std@@SAXXZ=?_Xlen2008@_String_base_2008@std2008@@QBEXXZ

Similar redirectors must be done for all functions that the linker complains about.

Now add the "compat.lib" library as additional library to your project and now it should link successfully.

Upvotes: 0

0xC0000022L
0xC0000022L

Reputation: 21319

The issue you are seeing is due to differences in the STL and other libraries that come as part of C++. You can try the following linker switch:

/NODEFAULTLIB[:library]

when building it on the VS2008 side, if you cannot do that, though, you're out of luck. Basically what you'd have to do is to get rid of the standard libraries and thus delegate the task of resolving them to the linker that is later using the resulting static .lib.

I should add that you also need to make sure that you only use features that the recipient libraries know about.

Upvotes: 2

Related Questions