[CMake] Making and using static and shared libraries on Windows with Visual Studio

Roger Leigh rleigh at codelibre.net
Thu Jul 30 08:45:23 EDT 2015


Hi folks,

This might not be a problem with CMake, it's probably due to my lack of 
familiarity with Windows either in CMakeLists.txt or in the code itself. 
  I have a large C++ codebase which uses CMake to build on 
Linux/Unix/MacOS X.  I'm currently porting it to use a superbuild 
infrastructure to build on Windows.  The superbuild works fine, but I'm 
running into odd linking errors.

I've tried to create a minimal testcase to demonstrate the problem. 
This is here: https://github.com/rleigh-dundee/dlltest
(test-vs201n.bat will run cmake and the builds automatically)

This creates a few libraries which contain classes using std::string or 
std::vector<std::string> and then links them into test programs.  It's 
really trivial, and works fine on non-Windows systems, but fails when 
linking static libs on Windows.

With Windows, I see this:

            Shared  Static
   VS2012   Fail    Fail
   VS2013   Works    Fail
   VS2015   Warns   Fail

VS2012 has problems parsing the code, which looks like a VS2012 bug 
needing workaround, and the VS2015 DLL warning looks like some change in 
the internal implementation details of string and vector.  What's 
concerning me is that I'm getting link errors along the lines of:

c.lib(c.obj) : error LNK2019: unresolved external symbol "public: static 
unsigned __int64 const std:: basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> >::npos 
(?npos@?$basic_string at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@2_KB) referenced 
in function "class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> > * __cdecl 
std::_Uninit_copy<class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> > const *,class 
std::basic_string<char,struct std::char_traits<char>,class 
std::allocator<char> > *,class std::allocator<
class std::basic_string<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 *,class 
std::basic_string<char,struct std::char_traits<char>,class 
std::allocator<char> > const *,class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> > *,struct 
std::_Wrap_alloc<class std::allocator<class 
std::basic_string<char,struct std::char_traits<char>,class 
std::allocator<char> > > > &,struct std::_Nonscalar_ptr_iterator_tag)" 
(??$_Uninit_copy at PEBV?$basic_string at DU?$char_traits 
@D at std@@V?$allocator at D@2@@std@@PEAV12 at V?$allocator at V?$basic_string at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@@2@@std@@YAPEAV?$basic_string at DU?$char_traits at D@std@@V?$allocator at D@2@@0 at PEBV10@0PEAV10 at AEAU?$_Wrap_alloc at V?$allocator at V?$basic_string at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@@std@@@0 at U_Nonscalar_ptr_iterator_tag@0@@Z) 
[C:\Users\rleigh\libtest\2013s\testc.vcxproj]
c.lib(c2.obj) : error LNK2001: unresolved external symbol "public: 
static unsigned __int64 const std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> >::npos" 
(?npos@?$basic_string at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@2_KB) [C:\Users\rleigh\libtest\2013s\testc.vcxproj]

The odd thing: this only occurs for libraries "c" and "d" using 
std::vector<std::string> while libraries "a" and "b" using std::string 
work just fine--I'm not sure what exactly is using npos unless it's part 
of the vector default construction of string.

Could any CMake users with Windows expertise possibly suggest what I'm 
doing wrong or missing here, either in the CMake logic or in the code. 
I thought I had all the template instantiations right for DLL export, 
but thought static libraries would Just Work!


Many thanks,
Roger


More information about the CMake mailing list