How to embed a manifest into a dll with mingw tools only

(DISCLAIMER: I am not a windows guy; all the discussion here is how I understand things from various sources).

With Visual Studio 2005, MS introduced a mechanism called side by side assemblies and C/C++ isolated applications. Assembly is the MS term which encompasses usual dll, as well as .Net modules implemented in CLR, the .Net bytecode (e.g. anything programmed in C#). The idea is to provide a mechanism to deal with the well known dll hell, because there was no proper versioning scheme with dll in windows. You can read more here:

Why should you care as a python developer ? Concretely, starting from VS 2005, if you build a python extension with the mingw compiler, it will link against a runtime which is not available system-wise (such as in C:\Windows\system32 by default), causing a runtime error when loading the extension (msvcr80.dll not found). A simple way to reproduce the result is to have a small dll, and try to link it to a simple executable with the ms runtime:

# This works:
gcc -shared hello.c -o hello.dll
gcc main.c hello.dll -o main.exe
# This does not:
gcc -shared hello.c -o hello.dll
gcc main.c hello.dll -o main.exe -lmsvcr90

If you build the 2nd way, explicitely linking the msvcr90, you will get a dll not found error when running the executable, because the dll is not in the system paths (and should not be; the dll is not redistributable). Starting from VS 2005, the only way to refer to VS libraries is to use manifest, which are xml files embedded in the binary. Those manifest are automatically generated by the MS compiler. Assuming you already have the manifest, how can you generate a binary using it without using MS compilers ?

Build the object of the dll:

    gcc -c hello.c

    Have a hello.rc file which refers to the manifest file  (2 seems to refer to dll, vs 1 for exe, but I am not sure):

      #include "winuser.h"
      2 RT_MANIFEST hello.dll.manifest

      Build the .res file, which will embed the xml file into the resource file (.res)

        windres --input hello.rc --output hello.res --output-format=coff

        Link the whole thing together:

          gcc -shared -o hello.dll hello.o hello.res -lmsvcr90

          Now, executing main.exe should be possible. There is still the problem of generating the manifest file. Since in our case, the problem is mainly with the MSVC runtime, to stay compatible with the python.org binary, we may just reuse the same manifest all the time ?

          A few more links on the topic:

          http://www.ddj.com/windows/184406482

          http://msdn.microsoft.com/en-us/library/ms235591(VS.80).aspx

          http://www.codeproject.com/KB/COM/regsvr42.aspx

          About these ads

          10 responses to “How to embed a manifest into a dll with mingw tools only

          1. at http://jesusnjim.com/code/mingw.html I give a batch file that you can download for windows that should build an optional manifest into an executable.

            lately though, windres is ruining the executable and I can’t figure out what is going on.

            a sample xml file looks like:

            show disk free space and usage in SI units with graph or in bytes

            and you don’t want to change away from asInvoker or uiAccess=false, since I have read this gives you one-click installation possibilities. here, the program’s name is df and the version is 2.8: I am not sure if you must force the version numbering system to be in 0.0.0.0 format because I don’t have vista or 7 yet.

          2. I discovered code is not executable in the gcc 4.4.0 version of mingw, at least I have not been able to succcessfully install the compiler and generate usable executables. however, code is usable with the 5.1.6 installer.

          3. just out of curiosity, why did you use -lmsvcrt90 again in your “example without msvcrt90 dll use”?

            is this intentional, or is it a copy and paste error or oversight?

            since I can’t distribute that dll with my programs, I don’t need to include anything related to it in the commandline do I?

          4. now I understand – the msvcrt90 library+DLL is ONLY required if you are compiling for use with python. otherwise, if you are looking for a straight plain 64-bit monolithic EXE with mingw, do

            c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\bin\windres.exe –input=printflush64.manifest.rc –input-format=rc –
            tput=printflush64.manifest.res –output-format=coff

            c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\bin\g++.exe -Wall -W -O -mwindows -s -fstack-check -IC:/libpq/;c:/
            pq/server/libpq/;c:/mingw-w32-bin_i686-mingw_20091224_sezero/mingw64-w32/include -Lc:/libpq/;c:/mingw-w32-bin_i686-mingw_20091224_sezero/mingw64-w32/lib -o printflush64.exe printflush.cpp c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\i686-w64-mingw32\lib\libwinspool.a printflush64.manifest.res c:\mingw-w32-bin_i686-mingw_20091224_se
            o\mingw64-w32\lib\gcc\i686-w64-mingw32\4.4.3\libgcc.a

            to generate a 32-bit monolithic exe with mingw, do

            c:\mingw\bin\windres.exe –input=printflush.manifest.rc –input-format=rc –output=printflush.manifest.res –output-format=coff

            c:\mingw\bin\g++.exe -Wall -W -O -mwindows -s -fstack-check -IC:/libpq/;c:/libpq/server/libpq/;c:/mingw/include -Lc:/libpq/;c
            ingw/lib -o printflush.exe printflush.cpp c:\mingw\lib\libwinspool.a printflush.manifest.res

          5. I discovered it is a REQUIREMENT to use the version number format given in the examples by Microsoft: 0.0.0.0 – if you do not use 4 numbers separated by dots, you will end up with an executable that will not even execute even on Windows XP.

            So If you are getting strange error messages when you generate your code using a manifest, this could be why.

            btw, the current version of mingw-w64 does not seem to generate a proper 64-bit EXE (all the 64bit EXE’s do not execute on my 32-bit OS – just say it’s an invalid EXE). this may be remedied in the future.

          6. Adam Goode

            It’s not too hard to cook up a manifest file, for either an exe or dll:

            http://msdn.microsoft.com/en-us/library/aa374191(VS.85).aspx

          7. Pingback: Anselm’s notes » Blog Archive » MSVCR90.DLL and MinGW

          8. Pingback: 吵闹的 lupdate - Tomatoeskit Blog

          9. I know this if off topic but I’m looking into starting my own weblog and was wondering what all is needed to get setup? I’m assuming having a blog
            like yours would cost a pretty penny? I’m not very web smart so I’m
            not 100% certain. Any recommendations or advice would be greatly
            appreciated. Appreciate it

          Leave a Reply

          Fill in your details below or click an icon to log in:

          WordPress.com Logo

          You are commenting using your WordPress.com account. Log Out / Change )

          Twitter picture

          You are commenting using your Twitter account. Log Out / Change )

          Facebook photo

          You are commenting using your Facebook account. Log Out / Change )

          Google+ photo

          You are commenting using your Google+ account. Log Out / Change )

          Connecting to %s

          September 2008
          M T W T F S S
          « Aug   Oct »
          1234567
          891011121314
          15161718192021
          22232425262728
          2930  

          Enter your email address to subscribe to this blog and receive notifications of new posts by email.

          Join 11 other followers

          Follow

          Get every new post delivered to your Inbox.

          %d bloggers like this: