Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using MinGW to build a Windows DLL that depends on Visual Studio CRT (msvcr110.dll) NOT on Windows CRT (msvcrt.dll)

I am trying to build a DLL using MinGW for Windows. I know that by default building using MinGW introduces a dependency on msvcrt.dll that ships with Windows. However, I want my DLL not to have a dependency on msvcrt.dll. Instead I want my DLL's C Runtime dependency to be satisfied using the msvcr110.dll (the Visual Studio 2012 CRT).

The reason why I need to do this is because the source code I am trying to build uses some C99 features that are not available in the VC11 compiler so it has to be built using MinGW. At the same time a DLL having a dependency on msvcrt.dll is disallowed in a Windows 8 Store application (which is what I am trying to build). Instead if a DLL has a dependency on msvcr110.dll, it is allowed in Windows Store.

So my only option is to build using MinGW but still link to msvcr110.dll.

How can I achieve this?

like image 841
Raman Sharma Avatar asked Apr 04 '13 21:04

Raman Sharma


1 Answers

I encourage you to download and install the latest MinGW-w64 not only because it is bleeding-edge, but it also contains the import library libmsvcr110.a to link against. Then try the following:

specs.msvcr110


%rename cpp msvcrXX_cpp

%rename cc1plus msvcrXX_cc1plus

*cpp:
%(msvcrXX_cpp) -D__MSVCRT_VERSION__=0x1100 -D__USE_MINGW_ACCESS

*cc1plus:
%(msvcrXX_cc1plus) -D__MSVCRT_VERSION__=0x1100 -D__USE_MINGW_ACCESS

*libgcc:
%{mthreads:-lmingwthrd} -lmingw32 %{shared-libgcc:-lgcc_s} -lgcc -lmoldname110 -lmingwex -lmsvcr110

libmoldname110.a


As several of you rightfully noticed, there is indeed no libmoldname110.a supplied out-of-the-box (and there are good reasons for this). Nevertheless, as usual, nobody stops you from building one on your own. To do that, you'd first need to obtain <mingw-w64-source-dir>/mingw-w64-crt/lib64/moldname-msvcrt.def, and then utilize (the sweet) dlltool as follows:

$ dlltool -k -U --as=as --def=moldname-msvcrt.def --dllname=msvcr110.dll --output-lib=libmoldname110.a

NOTE:
Unfortunately, at the moment, I don't have a chance to test this exactly myself. Hence, please, report your experience in comments so that we can jointly come up with a final solution.

test.rc


#include <winuser.h>

// Choose:
1 RT_MANIFEST msvcr110.manifest // if linking executable
2 RT_MANIFEST msvcr110.manifest // if linking DLL

msvcr110.manifest


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC110.CRT" version="11.0.51106.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">
        <file name="msvcr110.dll" />
        <file name="msvcp110.dll" />
        <file name="msvcm110.dll" />
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Look at Application Manifests for more information.

Build


$ windres -i test.rc -o test.rc.o --output-format=coff
$ gcc -specs=specs.msvcr110 -o test test.c test.rc.o

Recommendation


Although Microsoft Visual C Runtime is included on most platforms, there are many different versions of it, some of which are buggy or/and break backward compatibility. Thus, it is always a good idea to distribute the version of msvcr*.dll that you know works for sure with your application.

like image 192
Alexander Shukaev Avatar answered Sep 30 '22 14:09

Alexander Shukaev