summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-06-12 14:52:32 +0200
committerJani Heikkinen <jani.heikkinen@theqtcompany.com>2015-06-14 06:17:35 +0000
commit6c8954b07807e31dbc8967ba6d92d4d022073087 (patch)
tree96e599ebb501571be3d8c56a401edea4f0e866e3
parent3f69aa732d22603d88f98728b51b76888f062c94 (diff)
downloadqttools-6c8954b07807e31dbc8967ba6d92d4d022073087.tar.gz
windeployqt: Detect -release -force-debug-info MSVC builds as release.
Factor out detection logic into a template for 32/64bit. When a debug entry is detected, detect release if the library positively uses the release runtime dll. Task-number: QTBUG-46629 Change-Id: Ic34c2e3850e7f1945086da87867934c502026a2e Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
-rw-r--r--src/windeployqt/utils.cpp91
1 files changed, 62 insertions, 29 deletions
diff --git a/src/windeployqt/utils.cpp b/src/windeployqt/utils.cpp
index 081c9c475..a331bac9e 100644
--- a/src/windeployqt/utils.cpp
+++ b/src/windeployqt/utils.cpp
@@ -35,6 +35,8 @@
#include "elfreader.h"
#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QTemporaryFile>
@@ -723,6 +725,46 @@ inline QStringList readImportSections(const ImageNtHeader *ntHeaders, const void
return result;
}
+// Check for MSCV runtime (MSVCP120D.dll/MSVCP120.dll).
+enum MsvcDebugRuntimeResult { MsvcDebugRuntime, MsvcReleaseRuntime, NoMsvcRuntime };
+
+static inline MsvcDebugRuntimeResult checkMsvcDebugRuntime(const QStringList &dependentLibraries)
+{
+ foreach (const QString &lib, dependentLibraries) {
+ if (lib.startsWith(QLatin1String("MSVCR"), Qt::CaseInsensitive)
+ || lib.startsWith(QLatin1String("MSVCP"), Qt::CaseInsensitive)) {
+ return lib.endsWith(QLatin1String("D.dll"), Qt::CaseInsensitive)
+ ? MsvcDebugRuntime : MsvcReleaseRuntime;
+ }
+ }
+ return NoMsvcRuntime;
+}
+
+template <class ImageNtHeader>
+inline void determineDebugAndDependentLibs(const ImageNtHeader *nth, const void *fileMemory,
+ bool isMinGW,
+ QStringList *dependentLibrariesIn,
+ bool *isDebugIn, QString *errorMessage)
+{
+ const bool hasDebugEntry = nth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ QStringList dependentLibraries;
+ if (dependentLibrariesIn || (isDebugIn && hasDebugEntry && !isMinGW))
+ dependentLibraries = readImportSections(nth, fileMemory, errorMessage);
+
+ if (dependentLibrariesIn)
+ *dependentLibrariesIn = dependentLibraries;
+ if (isDebugIn) {
+ if (isMinGW) {
+ // Use logic that's used e.g. in objdump / pfd library
+ *isDebugIn = !(nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
+ } else {
+ // When an MSVC debug entry is present, check whether the debug runtime
+ // is actually used to detect -release / -force-debug-info builds.
+ *isDebugIn = hasDebugEntry && checkMsvcDebugRuntime(dependentLibraries) != MsvcReleaseRuntime;
+ }
+ }
+}
+
// Read a PE executable and determine dependent libraries, word size
// and debug flags.
bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage,
@@ -769,40 +811,31 @@ bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage
const unsigned wordSize = ntHeaderWordSize(ntHeaders);
if (wordSizeIn)
*wordSizeIn = wordSize;
- bool debug = false;
if (wordSize == 32) {
- const IMAGE_NT_HEADERS32 *ntHeaders32 = reinterpret_cast<const IMAGE_NT_HEADERS32 *>(ntHeaders);
-
- if (!isMinGW) {
- debug = ntHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
- } else {
- // Use logic that's used e.g. in objdump / pfd library
- debug = !(ntHeaders32->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
- }
-
- if (dependentLibrariesIn)
- *dependentLibrariesIn = readImportSections(ntHeaders32, fileMemory, errorMessage);
-
+ determineDebugAndDependentLibs(reinterpret_cast<const IMAGE_NT_HEADERS32 *>(ntHeaders),
+ fileMemory, isMinGW, dependentLibrariesIn, isDebugIn, errorMessage);
} else {
- const IMAGE_NT_HEADERS64 *ntHeaders64 = reinterpret_cast<const IMAGE_NT_HEADERS64 *>(ntHeaders);
-
- if (!isMinGW) {
- debug = ntHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
- } else {
- // Use logic that's used e.g. in objdump / pfd library
- debug = !(ntHeaders64->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
- }
-
- if (dependentLibrariesIn)
- *dependentLibrariesIn = readImportSections(ntHeaders64, fileMemory, errorMessage);
+ determineDebugAndDependentLibs(reinterpret_cast<const IMAGE_NT_HEADERS64 *>(ntHeaders),
+ fileMemory, isMinGW, dependentLibrariesIn, isDebugIn, errorMessage);
}
- if (isDebugIn)
- *isDebugIn = debug;
result = true;
- if (optVerboseLevel > 1)
- std::wcout << __FUNCTION__ << ": " << peExecutableFileName
- << ' ' << wordSize << " bit, debug: " << debug << '\n';
+ if (optVerboseLevel > 1) {
+ std::wcout << __FUNCTION__ << ": " << QDir::toNativeSeparators(peExecutableFileName)
+ << ' ' << wordSize << " bit";
+ if (isMinGW)
+ std::wcout << ", MinGW";
+ if (dependentLibrariesIn) {
+ std::wcout << ", dependent libraries: ";
+ if (optVerboseLevel > 2)
+ std::wcout << dependentLibrariesIn->join(QLatin1Char(' '));
+ else
+ std::wcout << dependentLibrariesIn->size();
+ }
+ if (isDebugIn)
+ std::wcout << (*isDebugIn ? ", debug" : ", release");
+ std::wcout << '\n';
+ }
} while (false);
if (fileMemory)