diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp index ea0ad8fe7d7693d9c014086bd604dcabb76f8efb..3589955063716f2fc0dbfc1d66ebfb8a0a2c99dd 100644 --- a/src/plugins/projectexplorer/abi.cpp +++ b/src/plugins/projectexplorer/abi.cpp @@ -34,11 +34,11 @@ #include "abi.h" #include <QtCore/QCoreApplication> +#include <QtCore/QDebug> #include <QtCore/QFile> #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QSysInfo> -#include <QtCore/QDebug> namespace ProjectExplorer { @@ -63,6 +63,48 @@ static Abi macAbiForCpu(quint32 type) { } } +static QList<Abi> parseCoffHeader(const QByteArray &data) +{ + QList<Abi> result; + if (data.size() < 20) + return result; + + Abi::Architecture arch = Abi::UnknownArchitecture; + Abi::OSFlavor flavor = Abi::UnknownFlavor; + int width = 0; + + // Get machine field from COFF file header + quint16 machine = (data.at(1) << 8) + data.at(0); + switch (machine) { + case 0x8664: // x86_64 + arch = Abi::X86Architecture; + width = 64; + break; + case 0x014c: // i386 + arch = Abi::X86Architecture; + width = 32; + break; + case 0x0200: // ia64 + arch = Abi::ItaniumArchitecture; + width = 64; + break; + } + + if (data.size() >= 68) { + // Get Major and Minor Image Version from optional header fields + quint32 image = (data.at(67) << 24) + (data.at(66) << 16) + (data.at(65) << 8) + data.at(64); + if (image == 1) // Image is 1 for mingw and higher for MSVC (4.something in some encoding) + flavor = Abi::WindowsMSysFlavor; + else + flavor = Abi::WindowsMsvcFlavor; + } + + if (arch != Abi::UnknownArchitecture && width != 0) + result.append(Abi(arch, Abi::WindowsOS, flavor, Abi::PEFormat, width)); + + return result; +} + static QList<Abi> abiOf(const QByteArray &data) { QList<Abi> result; @@ -119,39 +161,8 @@ static QList<Abi> abiOf(const QByteArray &data) // Windows PE // Windows can have its magic bytes everywhere... int pePos = data.indexOf(QByteArray("PE\0\0", 4)); - if (pePos >= 0 && pePos + 72 < data.size()) { - Abi::Architecture arch = Abi::UnknownArchitecture; - Abi::OSFlavor flavor = Abi::UnknownFlavor; - int width = 0; - - // Get machine field from COFF file header - quint16 machine = (data.at(pePos + 5) << 8) + data.at(pePos + 4); - switch (machine) { - case 0x8664: // x86_64 - arch = Abi::X86Architecture; - width = 64; - break; - case 0x014c: // i386 - arch = Abi::X86Architecture; - width = 32; - break; - case 0x0200: // ia64 - arch = Abi::ItaniumArchitecture; - width = 64; - break; - } - - // Get Major and Minor Image Version from optional header fields - quint32 image = (data.at(pePos + 71) << 24) + (data.at(pePos + 70) << 16) - + (data.at(pePos + 69) << 8) + data.at(pePos + 68); - if (image == 1) // Image is 1 for mingw and 4.something for MSVC - flavor = Abi::WindowsMSysFlavor; - else - flavor = Abi::WindowsMsvcFlavor; - - if (arch != Abi::UnknownArchitecture && flavor != Abi::UnknownFlavor && width != 0) - result.append(Abi(arch, Abi::WindowsOS, flavor, Abi::PEFormat, width)); - } + if (pePos >= 0) + result = parseCoffHeader(data.mid(pePos + 4)); } return result; } @@ -454,6 +465,8 @@ QList<Abi> Abi::abisOfBinary(const QString &path) if (!f.exists()) return result; + bool windowsStatic = path.endsWith(QLatin1String(".lib")); + f.open(QFile::ReadOnly); QByteArray data = f.read(1024); if (data.size() >= 67 @@ -467,7 +480,7 @@ QList<Abi> Abi::abisOfBinary(const QString &path) quint64 offset = 8; while (!data.isEmpty()) { - if (data.at(58) != 0x60 || data.at(59) != 0x0a) { + if ((data.at(58) != 0x60 || data.at(59) != 0x0a)) { qWarning() << path << ": Thought it was an ar-file, but it is not!"; break; } @@ -478,13 +491,18 @@ QList<Abi> Abi::abisOfBinary(const QString &path) fileNameOffset = fileName.mid(3).toInt(); const QString fileLength = QString::fromAscii(data.mid(48, 10)); - data = data.mid(60 + fileNameOffset); + int toSkip = 60 + fileNameOffset; offset += fileLength.toInt() + 60 /* header */; - result = abiOf(data); + if (windowsStatic) { + if (fileName == QLatin1String("/0 ")) + result = parseCoffHeader(data.mid(toSkip, 20)); + } else { + result = abiOf(data.mid(toSkip)); + } if (!result.isEmpty()) break; - f.seek(offset); + f.seek(offset + (offset % 2)); // ar is 2 byte alligned data = f.read(1024); } } else { diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 3b086563eef6d2a5755e312304074b15427565b8..0aba0c2571e341c8ced0f04412422be57c747332 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -1589,9 +1589,10 @@ QString QtVersion::qtCorePath() const { QList<QDir> dirs; dirs << QDir(libraryInstallPath()) << QDir(versionInfo().value(QLatin1String("QT_INSTALL_BINS"))); + + QFileInfoList staticLibs; foreach (const QDir &d, dirs) { QFileInfoList infoList = d.entryInfoList(); - QFileInfoList staticLibs; foreach (const QFileInfo &info, infoList) { const QString file = info.fileName(); if (info.isDir() @@ -1605,7 +1606,7 @@ QString QtVersion::qtCorePath() const if (file.startsWith(QLatin1String("libQtCore")) || file.startsWith(QLatin1String("QtCore"))) { // Only handle static libs if we can not find dynamic ones: - if (file.endsWith(".a")) + if (file.endsWith(".a") || file.endsWith(".lib")) staticLibs.append(info); else if (file.endsWith(QLatin1String(".dll")) || file.endsWith(QString::fromLatin1(".so.") + qtVersionString())) @@ -1613,10 +1614,10 @@ QString QtVersion::qtCorePath() const } } } - // Return path to first static library found: - if (!staticLibs.isEmpty()) - return staticLibs.at(0).absoluteFilePath(); } + // Return path to first static library found: + if (!staticLibs.isEmpty()) + return staticLibs.at(0).absoluteFilePath(); return QString(); }