다음을 통해 공유


Embed manifest with makefiles in VS2005

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

!else

_VC_MANIFEST_AUTO_RES=

!endif

####################################################################################

#Step 4. Adding _VC_MANIFEST_EMBED_EXE - command to embedd manifest to EXE

####################################################################################

!if "$(_VC_MANIFEST_INC)" == "1"

#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)

!else

_VC_MANIFEST_EMBED_EXE= \

if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1

!endif

####################################################################################
#Step 5. Adding _VC_MANIFEST_EMBED_DLL - command to embedd manifest into DLL
####################################################################################

 

!if "$(_VC_MANIFEST_INC)" == "1"

MT_SPECIAL_RETURN=1090650113
MT_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)

!else

_VC_MANIFEST_EMBED_DLL= \
if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2

!endif

####################################################################################

# Step 6. Adding _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily

####################################################################################

 

!if "$(_VC_MANIFEST_INC)" == "1"

_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \

    $(_VC_MANIFEST_BASENAME).auto.rc \

    $(_VC_MANIFEST_BASENAME).auto.manifest

!else

_VC_MANIFEST_CLEAN=

!endif

# 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 :

                type <<$@

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>

<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>

</assembly>

<< KEEP

# 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

!if "$(DEBUG)" == "1"

CPPFLAGS=$(CPPFLAGS) /MDd

LFLAGS=$(LFLAGS) /INCREMENTAL

!else

CPPFLAGS=$(CPPFLAGS) /MD

!endif

MyApplication.exe : MyApplication.obj

                link $** /out:$@ $(LFLAGS)

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)

####################################################################################

#include makefile.inc. Add full path if necessary

!include makefile.inc

!if "$(DEBUG)" == "1"

CPPFLAGS=$(CPPFLAGS) /MDd

LFLAGS=$(LFLAGS) /INCREMENTAL

!else

CPPFLAGS=$(CPPFLAGS) /MD

!endif

MyApplication.exe : MyApplication.obj

                link $** /out:$@ $(LFLAGS)

                $(_VC_MANIFEST_EMBED_EXE)

MyApplication.obj : MyApplication.cpp

clean :

                del MyApplication.obj MyApplication.exe

                $(_VC_MANIFEST_CLEAN)

####################################################################################

#include makefile.targ.inc. Add full path if necessary

!include makefile.targ.inc

 

For DLLs, you have to do similar change. Here is a changed makefile for a DLL using makefile from MSDN sample:

####################################################################################

#include makefile.inc. Add full path if necessary

!include makefile.inc

!if "$(DEBUG)" == "1"

CPPFLAGS=$(CPPFLAGS) /MDd

LFLAGS=$(LFLAGS) /DLL /INCREMENTAL

!else

CPPFLAGS=$(CPPFLAGS) /MD

LFLAGS=$(LFLAGS) /DLL

!endif

MyLibrary.dll : MyLibrary.obj

                link $** /out:$@ $(LFLAGS)

                $(_VC_MANIFEST_EMBED_DLL)

MyLibrary.obj : MyLibrary.cpp

clean :

                del MyLibrary.obj MyLibrary.dll

                $(_VC_MANIFEST_CLEAN)

####################################################################################

#include makefile.targ.inc. Add full path if necessary

!include makefile.targ.inc

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.

makefile.inc and makefile.targ.inc.zip

Comments

  • Anonymous
    May 21, 2006
    With VC 2005 the native libraries such as the CRT, MFC, and ATL can now be installed as Side by Side...

  • Anonymous
    January 15, 2007
    The comment has been removed

  • Anonymous
    January 16, 2007
    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

  • Anonymous
    July 10, 2007
    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.

  • Anonymous
    August 02, 2007
    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.  

  • Anonymous
    January 10, 2008
    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.

  • Anonymous
    December 31, 2008
    The comment has been removed