(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
0 Responses to “How to embed a manifest into a dll with mingw tools only”