VS2022: WINDOWS_EXPORT_ALL_SYMBOLS results in link errors (multiply defined symbols) when the dll is used together with CLR dll
I have a managed C++ (CLR) wrapper for a C++ library. CMake generates Visual Studio project for the C++ library and then I use it in a solution that includes the wrapped and the C++ library. The wrapper links with the C++ library.
In order to automatically create def file and import library previously (in Visual Studio 2013) I used a very convenient feature "WINDOWS_EXPORT_ALL_SYMBOLS" and it was working just fine. With VS2022 I cannot build the wrapper project due to link errors related to multiply defined symbols, all of them are somehow related to exceptions. The C++ library itself builds ok from the VS project generated by CMake.
I prepared a minimal solution that reproduces the problem. In this minimal project the build log in VS looks like this:
Rebuild started... 1>------ Rebuild All started: Project: cpplib, Configuration: Debug x64 ------ 1>Building Custom Rule C:/Projects/MyProj/CppLibPlusClrTest/cpplib/CMakeLists.txt 1>cpp_lib_main.cpp 1>Auto build dll exports 1> Creating library C:/Projects/MyProj/CppLibPlusClrTest/cpplib/build/Debug/cpplib.lib and object C:/Projects/MyProj/CppLibPlusClrTest/cpplib/build/Debug/cpplib.exp 1>cpplib.vcxproj -> C:\Projects\MyProj\CppLibPlusClrTest\cpplib\build\Debug\cpplib.dll 2>------ Rebuild All started: Project: clrlib_VS2022, Configuration: Debug x64 ------ 2>clr_lib_main.cpp 2>.NETFramework,Version=4.8.AssemblyAttributes.cpp 2>Generating Code... 2>clr_lib_main.obj : MSIL module encountered; incremental linking is disabled for MSIL; performing full link 2>MSVCRTD.lib(throw_bad_alloc.obj) : error LNK2005: "public: __cdecl std::bad_alloc::bad_alloc(class std::bad_alloc const &)" (??0bad_alloc@std@@QEAA@AEBV01@@Z) already defined in cpplib.lib(cpplib.dll) 2>MSVCRTD.lib(throw_bad_alloc.obj) : error LNK2005: "public: __cdecl std::exception::exception(class std::exception const &)" (??0exception@std@@QEAA@AEBV01@@Z) already defined in cpplib.lib(cpplib.dll) 2>MSVCRTD.lib(throw_bad_alloc.obj) : error LNK2005: "public: virtual char const * __cdecl std::exception::what(void)const " (?what@exception@std@@UEBAPEBDXZ) already defined in cpplib.lib(cpplib.dll) 2>C:\Projects\MyProj\CppLibPlusClrTest\x64\Debug\clrlib_VS2022.dll : fatal error LNK1169: one or more multiply defined symbols found 2>Done building project "clrlib_VS2022.vcxproj" -- FAILED. ========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========
The problem goes away if I do either of the following:
- comment out "throw std::bad_alloc()" in the C++ library
- disable CLR support in the wrapper project
- use VS2013 with its toolchain (on another PC).
- edit the exports.def file to remove the problematic symbols and disable pre-link event in the project that automatically creates the def file.
Note, in my real project I cannot disable CLR or use the old toolchain. I can only imagine that I somehow automatically process the exports.def... The library is also quite big to put "declspecs" in all the sources, so WINDOWS_EXPORT_ALL_SYMBOLS would be very handy.
Steps to duplicate:
- Unpack the attached archive CppLibPlusClrTest.zip .
- Open VS2022 developer command prompt, cd to CppLibPlusClrTest\cpplib, run create_project_VS2022.cmd to create VS project
- Open solution CppLibPlusClrTest\CppLibPlusClr_VS2022.sln with VS2022. You should see two projects in the solution: "clrlib_2022" (that is the wrapper) and "cpplib" (that is the project created with CMake).
- Try to build the solution.
- Observe the errors in build log.
In case anyone wants to try the same with VS2013 or maybe later version below 2022 I also created a solution and project files for VS2013 (they have VS2013 postfix in the names).
My guess is that CMake puts not needed symbols into the def file, so they become exported and clash with the symbols from some internal libraries required by CLR. Apart from the only function "foo" that is defined in the lib there are also several additional symbols. I attach the def file. exports.def
Am I doing something wrong? Please recommend how to overcome this problem in VS2022.