Developing Windows Applications by Mykola Dudar

Helping Developers Build Applications for Windows using Visual Studio.

Embed manifest with makefiles in VS2005

Embed manifest with makefiles in VS2005

Rate This
  • Comments 7

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.

Attachment: makefile.inc and makefile.targ.inc.zip
  • With VC 2005 the native libraries such as the CRT, MFC, and ATL can now be installed as Side by Side...
  • 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

Page 1 of 1 (7 items)