Migrated from VC++ 2008 Express to Visual Studio 2015: Now getting linking errors...

Started by
10 comments, last by Sean_Seanston 8 years, 6 months ago

I migrated a VC++ 2008 project to Visual Studio 2015 and now I'm having linking errors with unresolved externals...

I'm using the Unofficial OpenGL SDK, so I put that in the same place where I used to have it when it worked (before I upgraded from Vista), then made sure all the includes were the same (the include directories are a little different in the new version but they all seem to be there correctly for includes and libraries now as far as I can see).

I had to change some code to work with C++11, specifically not specifying the types with make_pair, so I'm not sure if it may be that something else has changed and that's what's causing this or if some settings have just been lost with the migration or what...

When I try to build, it gives me tons of warnings and errors, mostly for glimgD.lib but also a few for glfwD.lib. Not sure if the warnings really matter or if they're indicative of some error-causing problem.

The warnings take the form of:


1>glimgD.lib(ImageFormat.obj) : warning LNK4049: locally defined symbol ?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ (public: char const * __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::c_str(void)const ) imported

Whereas the corresponding errors look like:


1>glimgD.lib(StbLoader.obj) : error LNK2019: unresolved external symbol "__declspec(dllimport) class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl std::operator+<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 &,char const *)" (__imp_??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@PBD@Z) referenced in function "public: __thiscall glimg::loaders::stb::UnableToLoadException::UnableToLoadException(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??0UnableToLoadException@stb@loaders@glimg@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)

All the include and library directories seem to be there in Properties, and the libs in Additional Dependencies seem to be visible and correct... in fact, it seems to be reading the .lib and not being able to find something that's referenced inside if I'm reading it right?

I took screenshots of the project's properties when it was working (though they shouldn't have changed with the migration anyway, ideally) and it seems like everything is like it's meant to be. Does it look like some kind of version incompatibility or have I probably just missed something?

Advertisement

Have you tryed to clean the build.

I guess those are static libraries built with the 2008 version of the standard library or something like that, or possibly that they or your project are linking to the DLL version of the runtime while the other is linking to the static version. Try looking for new versions from their respective websites built for VS2015.

Or if you have the code for that library rebuild it with VS2015

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

I guess those are static libraries built with the 2008 version of the standard library or something like that, or possibly that they or your project are linking to the DLL version of the runtime while the other is linking to the static version. Try looking for new versions from their respective websites built for VS2015.


Pretty much this. Although I would strongly suggest building the libraries yourself if at all possible. Being dependent on other people to build libraries for you gets extremely annoying and fails completely the moment you need something special which breaks the ABI.

I had to change some code to work with C++11, specifically not specifying the types with make_pair, so I'm not sure if it may be that something else has changed and that's what's causing this or if some settings have just been lost with the migration or what...


This has nothing really to do with C++11. It was never a good idea to specify the types with std::make_pair, the whole point of std::make_pair has always been that you don't need to do it since template argument deduction does it for you. If you want to specify the types explicitly it would have always been a easier to just construct an explicit std::pair<First, Second>().

That said, newer MSVCs appear to be a bit quirky in this case because explicit template arguments in std::make_pair actually break it. I don't think I have ever seen that with any other compiler though.
For general educational purposes:

Visual C++ usually breaks its C++ library ABI with every release. Essentially, this means that if you have a function exported from a library that uses any std::* types (string, vector, etc.) then you probably can't mix compiler versions.

libstdc++ (GCC) and libc++ (Clang) do the same things, just not nearly as often. libstdc++ is going to be breaking the default std::string ABI with its next major release for instance if I recall correctly (their std::string is not C++11-compliant, so they have to; you can already opt-in to the new ABI, but it's not yet default).

This is just the price one pays for the convenient abstractions of C++. If you're making a library, only ever use C types or your own unchanging C++ types, and be sure to explicitly set the calling convention (__stdcall, __cdecl, __fastcall, etc.) for every function. If you do ship a library compiled for Windows, be sure to mark which compiler it's for and consider shipping versions for each. e.g., our ThirdParty/ module directory in Perforce here has a lot of libraries with subfolders named things roughly like x86_vc10/, x86_vc12/, x64_vc12/, x64_gcc4_linux/, etc. And that isn't even including the debug, release, hybrid, etc. flavors that most of the libraries have.

There are a ton of other compiler options that also affect compatibility, so it's definitely a good idea to just compile what you can on your own. We've run into all kinds of crazy bugs with things like SIMD compiler options in Havok or wchar_t compatibility options in Scaleform, and those are just the two that I had to deal with personally.

Sean Middleditch – Game Systems Engineer – Join my team!

Have you tryed to clean the build.

Yeah, I thought of that but nothing.


I guess those are static libraries built with the 2008 version of the standard library or something like that, or possibly that they or your project are linking to the DLL version of the runtime while the other is linking to the static version. Try looking for new versions from their respective websites built for VS2015.


Or if you have the code for that library rebuild it with VS2015

I had a look and sure enough... I did have to build them for VS2008 some time ago, I just forgot. So I guess that's probably the problem...

HOWEVER, it seems the Unofficial OpenGL SDK only has support for VS2008 and VS2010... though I think I saw something when I googled about building for 2010 working for VS2013... so perhaps it also works for 2015, I'll try.

Strange... looks like the SDK hasn't been updated for a long time, despite it seeming to be quite popular. Assuming 0.5.2 is the latest version, but that's the one linked from the sourceforge page so I'm assuming it is.


This has nothing really to do with C++11. It was never a good idea to specify the types with std::make_pair, the whole point of std::make_pair has always been that you don't need to do it since template argument deduction does it for you.

Interesting... could've sworn it didn't work otherwise. Unless I was confusing it with something similar, like std::pair probably. Oh well.

Trying the VS2010 build now...

...

Works!

Excellent. I think I just assumed the glsdk folder had come that way rather than having to build it. Maybe there isn't any new version because the 2010 one works, I dunno.

Thanks all.

Try to open vs2015 and in project/properties/Configuration Properties/General try changing the "Platform Toolset" property into Microsoft Visual Studio 2015 first, then lesser.

This topic is closed to new replies.

Advertisement