Hi,
Building OSG 3.2.1 DICOM plug-in on a Windows XP x64 PC with Visual
Studio 2010 fails at link with the following error:
67>osgDB.lib(osg100-osgDB.dll) : error LNK2005: "public: void __cdecl
std::basic_ifstream<char,struct std::char_traits<char> >::`vbase
destructor'(void)"
(??_D?$basic_ifstream@DU?$char_traits@D@std@@@std@@QEAAXXZ) already
defined in dcmimgle.lib(didispfn.obj)
67>osgDB.lib(osg100-osgDB.dll) : error LNK2005: "public: __cdecl
std::basic_ifstream<char,struct std::char_traits<char>
>::basic_ifstream<char,struct std::char_traits<char> >(char const
*,int,int)" (??0?$basic_ifstream@DU?$char_traits@D@std@@@std@@QEAA@PEBDHH@Z)
already defined in dcmimgle.lib(didispfn.obj)
67> Creating library
C:/OpenSceneGraph/OpenSceneGraph-3.2.1/build/lib/osgPlugins-3.2.1/osgdb_dicom.lib
and object
C:/OpenSceneGraph/OpenSceneGraph-3.2.1/build/lib/osgPlugins-3.2.1/osgdb_dicom.exp
67>C:\OpenSceneGraph\OpenSceneGraph-3.2.1\build\bin\osgPlugins-3.2.1\osgdb_dicom.dll
: fatal error LNK1169: one or more multiply defined symbols found
This error was reported 3 years ago, without much interest [1].
Contrarily to what's regularly erroneously stated here and there, this
error has _nothing_ to deal with CRT configuration mismatch (the
dreaded /MT[d] vs. /MD[d] compiler settings). In such situation, you
generally get a warning about trying to add /NODEFAULTLIB:MSVCRT flag.
This _isn't_ the case here and I've double-checked that both my OSG
and DCMTK builds are using the same settings. And indeed, it's
identical: /MD[d].
This error has to deal with mixing both osgDB {i|o}fstream with STL
ones, as correctly explained in [2] and [3].
There seems to be a consensus as considering this issue a Visual
Studio 2010/2012 (what about 2013?) bug [4] and a well known
work-around is to pass /FORCE:MULTIPLY to the linker. Simply doing so
in the osgdb_dicom.vcxproj project file is obviously lost each time
CMake is invoked. A cleaner solution would be to add this flag through
the CMAKE_SHARED_LINKER_FLAGS of osgdb_dicom's CMakeLists.txt file, as
in VirtualPlanetBuilder [5]. I've thus updated osgdb_dicom's
CMakeLists.txt file to read as:
IF (WIN32)
SET(TARGET_EXTERNAL_LIBRARIES wsock32.lib)
=================> I've added
IF(MSVC)
IF(${MSVC_VERSION} STREQUAL "1600")
# Overcome Visual Studio 2010 error LNK2005:
basic_ifstream symbols already defined in dcmingle.lib (didispfn.obj)
SET(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} /FORCE:MULTIPLE")
ENDIF()
ENDIF()
=================> End of work-around
ENDIF()
However, it seem's that the default CMAKE_SHARED_LINKER_FLAGS
/machine:x64 is overriding customization, as osgdb_dicom linker
settings only shows /machine:x64. I've checked that the updated
CMakeLists.txt file was taken into account using an output message.
Am I missing something obvious here and is there a way to prevent such
an override? Or alternatively, is there a work-around for the Visual
Studio 2010 work-around?
Thanks,
Émeric
[1] http://forum.openscenegraph.org/viewtopic.php?t=8570
[2] http://forum.openscenegraph.org/viewtopic.php?t=8099
[3]
http://stackoverflow.com/questions/23885275/lnk2005-already-defined-linker-behaves-strange
[4]
http://social.msdn.microsoft.com/Forums/vstudio/en-US/191de00a-53c9-4bd9-9cb6-e844eb224ca2/lnk2005-when-using-stdostringstream?forum=vclanguage
[5]
http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2011-September/253865.html
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org