Well, time flies fast. It was two month since my last post here. One may ask what I was doing all this time. Answer is simple – working. 🙂 Seriously, VC++ program management team has spent a lot of time in preparing and then running VC++ Tour in Europe. There is long slides deck with information on all features coming in VC++ 2005 and several demos for most frequently asked features. Take a look on official page for this trip for more information http://msdn.microsoft.com/visualc/community/Tour2005/ . Also during our stop in Norway, my laptop was ambushed by Pepsi. It was seriously damaged and for the rest of the trip I was only able to check my emails from internet cafes. However very soon I started to have issues with remote connectivity, and that was the end of e-life for me. Anyway, it is the second week I am back in my office and hopefully I will post more regularly now.
So if you use VS2005 Beta 2 (yes, yes, it is available now, go ahead and download it if you have not done this already), you may have already noticed a message saying “Embedding manifest…” when you are building you project. You may also notice that linking starts second time sometimes after this message. You may ask yourself, what is going on and why we link twice. Actually 2nd link starts only if incremental linking or edit-and-continue is enabled. By default Visual Studio tryes embedding manifest for each project, unless users explicitly changes Manifest Tool -> Input and Output -> Embed Manifest property in Project Properties dialog. If the user selects to not embed manifest, manifest is generated as an external file and saved in the same directory where the final binary is. If the user chooses to embed the manifest, IDE embeds final manifests using the following process:
1. After the user code is compiled to object files, the linker collects dependent assembly information and while linking the final binary it generates an intermediate manifest that is used later to generate the final manifest.
2. After the intermediate manifest and linking are finished, the manifest tool will be executed to merge a final manifest.
3. If neither incremental linking nor edit-and-continue are enabled, mt.exe embeds the final manifest into the binary. If incremental linking or edit-and-continue is enabled, mt.exe save it as an external file. And project system is going to start second incremental linking to embed this external file.
4. Project build system then detects whether the manifest generated by the manifest tool contains different information then the manifest already embedded in the binary.
5. If the manifest embedded in the binary is different from the manifest generated by the manifest tool or binary does not contain an embedded manifest, IDE will invoke the linker one more time to embed the external manifest file inside the binary as a resource.
6. If the manifest embedded in the binary is the same as the manifest generated by the manifest tool, the build will continue to the next build steps.
So why does IDE need steps 4-6? The issue here is that in order for incremental linking to work, no changes should be made to the binary after it was linked by the linker. If mt.exe embeds manifest after the linker, the on the next incremental link, the linker detects the change and spins the full build. But if IDE creates a resource file with the final manifest and ask the linker to link this resource with the already built binary, for the linker this is a simple and very quick job to do. Moreover after resource is embedded, the binary is still correctly formed for the next incremental link. Nice trick by IDE, isn’t it?
Manifest is embedded inside the final binary as a text resource and it can be viewed by opening the final binary as a file in Visual Studio. Just open this binary in IDE and you see binary resource. Export it and you can now view it with any text editor. Actually this is the first step when I need to debug why this binary does not load.
So the fair question is what someone does to existing makefiles? Well, I have posted a sample where I have shown how to change a makefiles used to build both EXE and DLL. You may find it here How to embed manifest inside C/C++ program using makefiles.
Questions? Please feel free to post any comments below, I will try replying asap.