This blog is about developing Windows applications using Visual Studio. All postings on this weblog are provided "AS IS" with no warranties, and confer no rights. Use of any samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm
Your host Nikola Dudar is a Program Manager in Windows division of Microsoft Corporation. He has been working on Windows Web Services API during Windows 7 and various additions to Visual C++ during VS2005 and VS2008. More details are in LinkedIn profile under Nikola's formal name Mykola Dudar.
If you are interested in program management and project management, check out my other blog at http://www.pmsnack.com/ where I collect best practices and other topics interesting to program and project managers.
To send feedback, comments or requests for new posts, please use the contact form.
It is pointed out to me that MSDN example on how to embed manifest is focused on changes into one makefile. If you have several makefiles, then it is too much work to change all of them. While our doc writing team is triaging bug for an update to MSDN example, let me briefly describe how how to change this sample if you have many makefiles.
But before I would like to mention that direct embedding of manifest into binary using mt.exe, for example, following steps described here breaks incremental linking and edit and continue. If you change final binary generated by the linker with mt.exe, on the next change to source code the linker will do a full link instead of just linking in objects for modified source to the existing binary. So if you do care about incremental linking, you need embed manifest as a resource.
Anyway, so let's say you have a 100 of makefiles and you need to update all of them to embed manifest. Assuming your original makefiles similar to ones described in MSDN example, you need to do the following :
1) Create makefile.inc (see below, also attached to this post).
2) Create makefile.targ.inc (see below, , also attached to this post).
3) Include makefile.inc and makefile.targ.inc into existing makefiles (see below)
4) Add two lines into existing makefiles for link and clean steps (see below)
Now these steps in more details:
1) Create a makefile.inc which will be included in other files later on. Here is the file (copying lines from MSDN sample):
####################################################################################
# makefile.inc Include this file into existing makefile at the very top
# Step 1. Adding _VC_MANIFEST_INC to specify which build is incremental (1 - incremental)
# Step 2. Adding _VC_MANIFEST_BASENAME used to specify name of a temporary resource file
!if "$(DEBUG)" == "1"
CPPFLAGS=$(CPPFLAGS) /MDd
LFLAGS=$(LFLAGS) /INCREMENTAL
_VC_MANIFEST_INC=1
_VC_MANIFEST_BASENAME=__VC80.Debug
!else
CPPFLAGS=$(CPPFLAGS) /MD
_VC_MANIFEST_INC=0
_VC_MANIFEST_BASENAME=__VC80
!endif
# Step 3. Specifying name of temporary resource file used only in incremental builds
!if "$(_VC_MANIFEST_INC)" == "1"
_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res
_VC_MANIFEST_AUTO_RES=
#Step 4. Adding _VC_MANIFEST_EMBED_EXE - command to embedd manifest to EXE
#MT_SPECIAL_RETURN=1090650113
#MT_SPECIAL_SWITCH=-notify_resource_update
MT_SPECIAL_RETURN=0
MT_SPECIAL_SWITCH=
_VC_MANIFEST_EMBED_EXE= \
if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \
if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \
rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \
link $** /out:$@ $(LFLAGS)
if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1
#####################################################################################Step 5. Adding _VC_MANIFEST_EMBED_DLL - command to embedd manifest into DLL####################################################################################
MT_SPECIAL_RETURN=1090650113MT_SPECIAL_SWITCH=-notify_update
_VC_MANIFEST_EMBED_DLL= \if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \link $** /out:$@ $(LFLAGS)
_VC_MANIFEST_EMBED_DLL= \if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2
# Step 6. Adding _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily
_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \
$(_VC_MANIFEST_BASENAME).auto.rc \
$(_VC_MANIFEST_BASENAME).auto.manifest
_VC_MANIFEST_CLEAN=
# End of makefile.inc
2) Create a makefile.targ.inc which will be included in existing makefileslater on. Here is the file (copying lines from MSDN sample):
# makefile.targ.inc - include this at the very bottom of the existing makefile
# Step 7. Adding commands to generate initial empty manifest file, RC file
# that references it and for generating the .res file
$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc
$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest
type <<$@
#include <winuser.h>
1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest"
<< KEEP
$(_VC_MANIFEST_BASENAME).auto.manifest :
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
</assembly>
# end of makefile.targ.inc
3) Include makefile.inc and makefile.targ.inc into existing makefiles
#include makefile.inc. Add full path if necessary
!include makefile.inc
MyApplication.exe : MyApplication.obj
MyApplication.obj : MyApplication.cpp
clean :
del MyApplication.obj MyApplication.exe
#include makefile.targ.inc. Add full path if necessary
!include makefile.targ.inc
4) Add two lines (in red) into existing makefiles for link step (for EXEs)
$(_VC_MANIFEST_EMBED_EXE)
$(_VC_MANIFEST_CLEAN)
For DLLs, you have to do similar change. Here is a changed makefile for a DLL using makefile from MSDN sample:
LFLAGS=$(LFLAGS) /DLL /INCREMENTAL
LFLAGS=$(LFLAGS) /DLL
MyLibrary.dll : MyLibrary.obj
$(_VC_MANIFEST_EMBED_DLL)
MyLibrary.obj : MyLibrary.cpp
del MyLibrary.obj MyLibrary.dll
This should do it. Please beware of formatting changes when I convert makefiles from TXT to HTML on this page. This is why I am attaching both makefile.inc and makefile.targ.inc to this post also.
Thanks to Sridhar and Zach for pointing out problem with MSDN sample and providing sample code for the change.
[06/30/2006] Thanks to Bern McCarty for pointing out that MSDN sample has been changed and my reference to it for definition of _VC_MANIFEST_EMBED_DLL is not valid anymore. I have updated the sample and makefiles in the attached zip.
Hi Nikola,
Nice post, saved my day when I needed to embed manifests in DLLs created from makefiles.
Note however that http://msdn2.microsoft.com/en-us/library/ms235591(vs.80).aspx has slightly more information: it does add the following info:
QUOTE
Two approaches
There are two ways to embed the manifest inside an application or library.
If you are not doing an incremental build you can directly embed the manifest using a command line similar to the following as a post-build step:
mt.exe –manifest MyApp.exe.manifest -outputresource:MyApp.exe;1
or
mt.exe –manifest MyLibrary.dll.manifest -outputresource:MyLibrary.dll;2
(1 for an EXE, 2 for a DLL.)
If you are doing an increment build, directly editing the resource as shown above will disable incremental building and cause a full rebuild; therefore a different approach should be taken:
Link the binary to generate the MyApp.exe.manifest file.
Convert the manifest to a resource file.
Re-link (incrementally) to embed the manifest resource into the binary.
The following examples show how to change makefiles to incorporate both techniques.
UNQUOTE
HTH
Hi,
I am not surprised that MSDN example has more information. My post is from the time when MSDN example was not even written up. Example described in this post eventually ended up as a starting point for the topic on MSDN, however as you have noticed MSDN has more information about that.
Nikola
hi
if anyone can tell me how to create and embed the manifest file for dll where i am using the iexplore for calling the dll
thanx in advance.
I have been trying to work through manifest related issues with VC2005 and Longhorn for hours today. I have to say this is one of the more frustrating experiences I'd had to deal with in years.
I'm not sure what's really been solved with this manifest concept -- it just seems like over thinking a very straightforward solution which has worked for me and the vast majority of everyone else in the civilized world. THE FILESYSTEM SEARCH PATH.
I'm sure there are some very bright people at Microsoft but so far none have found a way to improve on *nix's simple and elegant way of installing programs and shared objects using links. Unbelievable.
I found that I get the following error: No explanation at all, just the error:
Build: Line 118 in makeexe.mak: error exit 31 from command:
"mt.exe –manifest x1.exe.manifest -outputresource:x1.exe;"
Does anyone know why?
(This is just using the simple MSDN-post way and is not at all a reflection on any of the information on this page.)
I also posted this quesiton with more elaborations at:
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/ae4db922-c418-48bf-ba30-0b54afe7437e/
This includes an attempt of adding 1 after the semi-colon, which may be necessary but was not sufficient, and a discussion of sub-directory issues.
Also, if anyone out there knows a good tutorial for interfacing Makefiles with Visual Studio (or on makefiles in general) that would be a welcome post as well.
Thanks