Details
-
Bug
-
Resolution: Done
-
P4: Low
-
5.2.1
-
None
-
Windows, Qt 5.2.1 static, Qt Creator, MSVC2012
-
83de197a57ff6c3e5bbad26bd871981285384fcb
Description
I was attempting to keep my release build directory free of intermediate/generated files and noticed a disparity between Visual Studio and Qt Creator, using the same .pro.
For Visual Studio, the default embed_manifest_exe works perfectly. The relevant log bit appears like so:
/MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='' processorArchitecture=''"
With no .manifest file left alongside the exe.
For Qt Creator, despite its name, embed_manifest_exe does not use /MANIFEST:embed. It instead appends /MANIFEST /MANIFESTFILE:<filename> to the end of $(LINKER) $(LFLAGS) and runs mt.exe. This prevents you from changing it for one; and secondly, adding /MANIFEST:embed manually will cause a linker error:
QMAKE_LFLAGS += /MANIFEST:embed /MANIFESTUAC
Causes the following Makefile and resultant linker output:
Makefile.Release:
LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /MANIFEST:embed /MANIFESTUAC
...
$(LINKER) $(LFLAGS) /MANIFEST /MANIFESTFILE:<EXE_PATH>.embed.manifest /OUT:$(DESTDIR_TARGET)
Linker output:
LINK : warning LNK4075: ignoring '/MANIFESTFILE' due to '/MANIFEST:EMBED' specification
...
mt.exe /nologo /manifest <EXE_PATH>.embed.manifest /outputresource:<EXE_PATH>;1
The build then fails because the .embed.manifest does not exist.
To replicate the behavior of Visual Studio, you must do the following:
CONFIG -= embed_manifest_exe
QMAKE_LFLAGS += /MANIFEST:embed /MANIFESTUAC
Furthermore, this configuration causes Visual Studio to no longer embed the manifest at all. It causes the following to be added to .vcxproj:
<EmbedManifest>false</EmbedManifest>
And /MANIFEST:embed is completely ignored in QMAKE_LFLAGS. It then calls mt.exe (when it did not before) like so:
mt.exe /nologo /verbose /out:<EXE_PATH>.manifest /manifest <INTERMEDIATE_PATH><EXE_NAME>.intermediate.manifest
(The paths are unimportant... I have different obj/moc/etc dirs defined)
Note there is no /outputresource as with Qt Creator.
So, in summary:
Qt Creator:
CONFIG -= embed_manifest_exe
QMAKE_LFLAGS += /MANIFEST:embed /MANIFESTUAC
VS:
CONFIG *= embed_manifest_exe
Do the exact same thing, and only then. I have verified the manifest gets embedded into the EXE in both cases.
And:
CONFIG *= embed_manifest_exe
QMAKE_LFLAGS += /MANIFEST:embed /MANIFESTUAC
Breaks in Qt Creator.
I somewhat hackishly differentiate between Qt creator and Visual Studio by comparing PWD/OUT_PWD and assuming Qt will always use a shadow build (a poor assumption) and can target them separately, or more sanely:
QMAKE_POST_LINK += del *.manifest
(Edit: Fixed formatting)