I'm trying to link the microsoft (VS2013) port for the caffe deep learning framework against MKL instead of the default OpenBlas library. MKL support with preprocessor-switched includes is already built-in, so I hoped to only link against the correct files (as indicated by MKL Link Line Advisor) and be done. Partially, it works.
The solution structure is as follows:
The static lib libcaffe is used by a caffe executable project (compiles, links and runs correctly using both OpenBlas and MKL). Additionally, there is my custom DLL that acts as a wrapper for libcaffe. It compiles, links and runs correctly using OpenBlas.
However, when I try to link against MKL, I get lots of linker errors LNK2038 reporting a conflict between MT_StaticRelease and MD_DynamicRelease (in one of my object files). In debug mode, I get many additional linker errors of the type
libcpmt.lib(xlocale.obj) : error LNK2005: "public: __thiscall std::locale::id::id(unsigned int)" (??0id@locale@std@@QAE@I@Z) is already defined in msvcprtd.lib(MSVCP120D.dll)
From what I read here https://msdn.microsoft.com/en-us/library/jj889284(v=vs.120).aspx this error is due to a library (in this case, MKL) and my DLL project using different run time libraries. This error persists regardless of whether I try to link against MKL statically (which Is what I would prefer so I don't have to ship several very large DLLs, i.e. link against mkl_intel_c.lib;mkl_core.lib;mkl_sequential.lib;) or dynamically (link against mkl_intel_c_dll.lib;mkl_core_dll.lib;mkl_sequential_dll.lib). I tried setting all required projects to link against the MT_StaticRelease runtime, but this also produces errors, because a different required library insists on the MD_Dynamic runtime switch.
Linking does work when I link against mkl_rt.lib.
Is this behavior intentional? How can I work around this if I want to link statically?
Thanks and greetings,
MKL is large and complex. A simple test program compiled with /MT and linked with MKL_RT may be a 20 kB EXE, and the same program can turn into an 80 MB EXE when you switch to all static libraries. Thus, it may be worth it for you to reassess whether to refer your users to the free MKL redistributables download or ship a bloated EXE.
You can produce a linker map file or run dumpbin to find out which of your OBJ files has a dependency on the DLL libraries.
Thanks for your answer!
My problem is less about exe size or shipping convenience. I currently can't link against a static version of the MKL (regardless of whether it is useful to do so or not; and from my past experience with Intel IPP, it is VERY useful for our specific application).
Any comments from intel?
There is not enough information in your report to suggest exactly what to do, because we do not know which of the OBJ files or libraries introduced a dependency on MSVCP120D, as the linker error message says. The build-log file would provide that information.
If you have some libraries that are not convenient to rebuild from source, you may need to add linker options of the type /nodefaultlib:MSVCP120D.lib, etc. This will work if, for every pair of matching libraries (e.g., MSVCRTxxx.lib and LIBCMT.lib), the static library contains compatible equivalents of all the symbols that your application takess from the default (dynamic) library. With some versions of Visual C/MS SDK, this was not true.
The problems with debug vs release are really not my main issue, they're more of an aside I should have left out of my original post.
My main problem is that in release mode, I can't link statically to MKL, since MKL release appears to be statically linked against the C runtime. I could accomodate that by also linking my project statically against the C runtime, but this does not work since all other libraries I use link dynamically to the C runtime library.
This problem persists even when I try to link MKL dynamically (non-single DLL), which in my opinion is incorrect on MKL's part. When I link against the single-DLL dynamic MKL variant, it works (but I have to ship or otherwise distribute a large amount of DLLs I never use or intend to use).
We have used the Intel IPP library for a long time, and have a long and successful history of linking to it statically (better-pruned dependency trees, ship only code for the target architecture, overall less to distribute, ...). For now I'm happy my project links and runs at all, but I'm baffled by the MKL behaving so differently from the IPP.
I could accomodate that by also linking my project statically against the C runtime, but this does not work since all other libraries I use link dynamically to the C runtime library.
That is the essence of the problem. Can you ask the suppliers of those libraries to supply you with versions that use only the static C RTL?
How about use /nodefaultlib:libcpmt.lib or /nodefaultlib:msvcprtd.lib to fix the problem?
I suppose if you link MKL static library, then it should only depend on libcpmt.lib. and the MSVCP120D.dll is from MD_DynamicRelease (in one of my object files).
So what you're saying is we as a software supplier cannot ship a dll containing MKL code that dynamically links to the CRT, since you no longer ship a version of the library that can be statically linked into our dll without also statically linking the c runtime libraries?
Also /nodefaultlib:libcpmt.lib or /nodefaultlib:msvcprtd.lib does not fix the problem.
This is a big problem for us, thanks, Simon