简体   繁体   中英

"LNK2005 DLLMain already defined ..." conflict in Linker using MSVC

I have a C++ project which up to now had no problems compiling and linking but due to a recent computer crash I had to re-install everything including Visual Studio and all my VCPKG packages. (I am using VS 2022 Preview, and was before.)

My project uses many STATICALLY linked libraries including Intel's TBB and Armadillo (which depends on OPENBLAS, amongst other things). However, it should be noted that OPENBLAS and TBB both still require a DLL to be linked even if the project uses static linking.

Now I am compiling the same project with the same Project Properties that worked before and am constantly getting the LNK2005 error stating that:

DllMain already defined in openblas.lib(memory.c.obj)..... tbb_debug.lib(tbb_main.obj)

If I switch the linking order all that happens is the error changes to

DllMain already defined in tbb_debug.lib(tbb_main.obj).... openblas.lib(memory.c.obj)

[Note: It is the same problem linking in Release and Debug configurations.]

Now what I cannot figure is why this even happens. Surely it is normal for projects to depend on more than one imported DLL. And it is quite normal for DLLs to export their DllMain entry point function.

With the PC crash I have been forced to upgrade everything to the absolute latest versions and I wonder if this has introduced the problem somewhere.

Is this a bug in MSVC that considers two DllMain functions from two different DLLs as conflicting?

If this is a real conflict, can someone explain to me how this does not happen more often to people building large projects using third party DLLs?

I have tried everything including a fresh install of VCPKG but nothing helps.

The only option I have found to get this to complete the linking is to use the /FORCE:MULTIPLE option, which I really do not like as it could be creating a flawed executable.

Any advice here would really be appreciated.

OK - I figured out a solution that does not require /FORCE:MULTIPLE

It seems either both or one of OPENBLAS and TBB cannot be built statically even though both packages compile fine with the triplet x64-windows-static .

What I did was create my own triplet called x64-windows-mixed to both statically and dynamically link the libraries. Default is static and it uses dynamic only for TBB and OPENBLAS.

Here is the code for the new triplet I created:

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)

if (${PORT} MATCHES "tbb")
   set(VCPKG_LIBRARY_LINKAGE dynamic)
endif()

if (${PORT} MATCHES "openblas")
   set(VCPKG_LIBRARY_LINKAGE dynamic)
endif()

After creating this "mixed" triplet, you will need to vcpkg install xxxx:x64-windows-mixed all the libraries you need to use with it and define the new triplet in the VCPKG section of the Project Properties page in the

This allows the compilation of the statically compiled project but also dynamically links OPENBLAS and TBB.

Refer to the VCPKG documentation https://vcpkg.readthedocs.io/en/latest/users/triplets/#per-port-customization

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM