From 83de197a57ff6c3e5bbad26bd871981285384fcb Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 12 Mar 2014 18:21:52 +0100 Subject: 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 Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_nmake.cpp | 28 ++++++++++++++++++++++------ qmake/generators/win32/msvc_nmake.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'qmake') diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index b8a564968d..52511b2008 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -514,18 +514,23 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) const QString target = var("DEST_TARGET"); QString manifest = project->first("QMAKE_MANIFEST").toQString(); QString extraLFlags; + const bool linkerSupportsEmbedding = (msvcVersion() >= 1200); if (manifest.isEmpty()) { generateManifest = true; - manifest = escapeFilePath(target + ".embed.manifest"); - extraLFlags = "/MANIFEST /MANIFESTFILE:" + manifest; - project->values("QMAKE_CLEAN") << manifest; + if (linkerSupportsEmbedding) { + extraLFlags = "/MANIFEST:embed"; + } else { + manifest = escapeFilePath(target + ".embed.manifest"); + extraLFlags += "/MANIFEST /MANIFESTFILE:" + manifest; + project->values("QMAKE_CLEAN") << manifest; + } } else { manifest = escapeFilePath(fileFixify(manifest)); } const QString resourceId = (templateName == "app") ? "1" : "2"; 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. 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 t << "\n\t"; writeLinkCommand(t, extraLFlags); - t << "\n\tmt.exe /nologo /manifest " << manifest - << " /outputresource:$(DESTDIR_TARGET);" << resourceId; + if (!linkerSupportsEmbedding) { + t << "\n\tmt.exe /nologo /manifest " << manifest + << " /outputresource:$(DESTDIR_TARGET);" << resourceId; + } } } else { t << "\n\t"; @@ -590,4 +597,13 @@ void NmakeMakefileGenerator::writeLinkCommand(QTextStream &t, const QString &ext 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 diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 4d3c69bdd6..8d8f5360e0 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -54,6 +54,7 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator void writeImplicitRulesPart(QTextStream &t); void writeBuildRulesPart(QTextStream &t); void writeLinkCommand(QTextStream &t, const QString &extraFlags = QString(), const QString &extraInlineFileContent = QString()); + int msvcVersion() const; void init(); protected: -- cgit v1.2.3