[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