qmake: use the manifest embedding feature of the MSVC linker

Since VS 2012 the linker supports the /MANIFEST:embed option, which can
be used to embed the automatically generated manifest without calling
mt.exe. Using this feature simplifies our generated makefiles, esp. in
the case of incremental linking.

Task-number: QTBUG-37363
Change-Id: I2c2d8d2abf36c1b9e7b41bc15244344aab8f5b6e
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
This commit is contained in:
Joerg Bornemann 2014-03-12 18:21:52 +01:00 committed by The Qt Project
parent 3217582405
commit 83de197a57
2 changed files with 23 additions and 6 deletions

View File

@ -514,18 +514,23 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t)
const QString target = var("DEST_TARGET"); const QString target = var("DEST_TARGET");
QString manifest = project->first("QMAKE_MANIFEST").toQString(); QString manifest = project->first("QMAKE_MANIFEST").toQString();
QString extraLFlags; QString extraLFlags;
const bool linkerSupportsEmbedding = (msvcVersion() >= 1200);
if (manifest.isEmpty()) { if (manifest.isEmpty()) {
generateManifest = true; generateManifest = true;
manifest = escapeFilePath(target + ".embed.manifest"); if (linkerSupportsEmbedding) {
extraLFlags = "/MANIFEST /MANIFESTFILE:" + manifest; extraLFlags = "/MANIFEST:embed";
project->values("QMAKE_CLEAN") << manifest; } else {
manifest = escapeFilePath(target + ".embed.manifest");
extraLFlags += "/MANIFEST /MANIFESTFILE:" + manifest;
project->values("QMAKE_CLEAN") << manifest;
}
} else { } else {
manifest = escapeFilePath(fileFixify(manifest)); manifest = escapeFilePath(fileFixify(manifest));
} }
const QString resourceId = (templateName == "app") ? "1" : "2"; const QString resourceId = (templateName == "app") ? "1" : "2";
const bool incrementalLinking = project->values("QMAKE_LFLAGS").toQStringList().filter(QRegExp("(/|-)INCREMENTAL:NO")).isEmpty(); const bool incrementalLinking = project->values("QMAKE_LFLAGS").toQStringList().filter(QRegExp("(/|-)INCREMENTAL:NO")).isEmpty();
if (incrementalLinking) { if (incrementalLinking && !linkerSupportsEmbedding) {
// Link a resource that contains the manifest without modifying the exe/dll after linking. // Link a resource that contains the manifest without modifying the exe/dll after linking.
QString manifest_rc = escapeFilePath(target + "_manifest.rc"); QString manifest_rc = escapeFilePath(target + "_manifest.rc");
@ -558,8 +563,10 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t)
// directly embed the manifest in the executable after linking // directly embed the manifest in the executable after linking
t << "\n\t"; t << "\n\t";
writeLinkCommand(t, extraLFlags); writeLinkCommand(t, extraLFlags);
t << "\n\tmt.exe /nologo /manifest " << manifest if (!linkerSupportsEmbedding) {
<< " /outputresource:$(DESTDIR_TARGET);" << resourceId; t << "\n\tmt.exe /nologo /manifest " << manifest
<< " /outputresource:$(DESTDIR_TARGET);" << resourceId;
}
} }
} else { } else {
t << "\n\t"; t << "\n\t";
@ -590,4 +597,13 @@ void NmakeMakefileGenerator::writeLinkCommand(QTextStream &t, const QString &ext
t << "\n<<"; t << "\n<<";
} }
int NmakeMakefileGenerator::msvcVersion() const
{
const int fallbackVersion = 800; // Visual Studio 2005
const QString ver = project->first(ProKey("MSVC_VER")).toQString();
bool ok;
float f = ver.toFloat(&ok);
return ok ? int(f * 100) : fallbackVersion;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -54,6 +54,7 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator
void writeImplicitRulesPart(QTextStream &t); void writeImplicitRulesPart(QTextStream &t);
void writeBuildRulesPart(QTextStream &t); void writeBuildRulesPart(QTextStream &t);
void writeLinkCommand(QTextStream &t, const QString &extraFlags = QString(), const QString &extraInlineFileContent = QString()); void writeLinkCommand(QTextStream &t, const QString &extraFlags = QString(), const QString &extraInlineFileContent = QString());
int msvcVersion() const;
void init(); void init();
protected: protected: