Merge remote-tracking branch 'origin/4.2'

Change-Id: If9b3a860d7efb561bb710d49396d6bbe13809aa1
This commit is contained in:
Eike Ziller
2017-01-12 10:54:21 +01:00
6 changed files with 168 additions and 11 deletions

View File

@@ -709,6 +709,10 @@ TargetGroupItemPrivate::TargetGroupItemPrivate(TargetGroupItem *q, Project *proj
TargetGroupItemPrivate::~TargetGroupItemPrivate()
{
disconnect();
delete m_noKitLabel;
delete m_configurePage;
delete m_configuredPage;
}
QVariant TargetGroupItem::data(int column, int role) const

View File

@@ -86,8 +86,6 @@ namespace Internal {
// --------------------------------------------------------------------
static const char CONFIG_CPP_MODULE[] = "cpp";
static const char CONFIG_CXXFLAGS[] = "cxxFlags";
static const char CONFIG_CFLAGS[] = "cFlags";
static const char CONFIG_DEFINES[] = "defines";
static const char CONFIG_INCLUDEPATHS[] = "includePaths";
static const char CONFIG_SYSTEM_INCLUDEPATHS[] = "systemIncludePaths";

View File

@@ -47,7 +47,6 @@
#include <utils/runextensions.h>
#include <utils/synchronousprocess.h>
#include <utils/winutils.h>
#include <utils/algorithm.h>
#include <QDir>
#include <QUrl>
@@ -55,7 +54,9 @@
#include <QFuture>
#include <QCoreApplication>
#include <QProcess>
#include <QRegExp>
#include <QRegularExpression>
#include <algorithm>
using namespace Core;
using namespace QtSupport;
@@ -1519,10 +1520,11 @@ FileName BaseQtVersion::mkspecFromVersionInfo(const QHash<QString, QString> &ver
if (temp.size() == 2) {
QString possibleFullPath = QString::fromLocal8Bit(temp.at(1).trimmed().constData());
if (possibleFullPath.contains(QLatin1Char('$'))) { // QTBUG-28792
const QRegExp rex(QLatin1String("\\binclude\\(([^)]+)/qmake\\.conf\\)"));
if (rex.indexIn(QString::fromLocal8Bit(f2.readAll())) != -1) {
const QRegularExpression rex(QLatin1String("\\binclude\\(([^)]+)/qmake\\.conf\\)"));
const QRegularExpressionMatch match = rex.match(QString::fromLocal8Bit(f2.readAll()));
if (match.hasMatch()) {
possibleFullPath = mkspecFullPath.toString() + QLatin1Char('/')
+ rex.cap(1);
+ match.captured(1);
}
}
// We sometimes get a mix of different slash styles here...
@@ -1739,12 +1741,147 @@ FileNameList BaseQtVersion::qtCorePaths(const QHash<QString,QString> &versionInf
return dynamicLibs;
}
static QByteArray scanQtBinaryForBuildString(const FileName &library)
{
QFile lib(library.toString());
QByteArray buildString;
if (lib.open(QIODevice::ReadOnly)) {
const QByteArray startNeedle = "Qt ";
const QByteArray buildNeedle = " build; by ";
const size_t oneMiB = 1024 * 1024;
const size_t keepSpace = 4096;
const size_t bufferSize = oneMiB + keepSpace;
QByteArray buffer(bufferSize, '\0');
char *const readStart = buffer.data() + keepSpace;
auto readStartIt = buffer.begin() + keepSpace;
const auto copyStartIt = readStartIt + (oneMiB - keepSpace);
while (!lib.atEnd()) {
const int read = lib.read(readStart, static_cast<int>(oneMiB));
const auto readEndIt = readStart + read;
auto currentIt = readStartIt;
forever {
const auto qtFoundIt = std::search(currentIt, readEndIt,
startNeedle.begin(), startNeedle.end());
if (qtFoundIt == readEndIt)
break;
currentIt = qtFoundIt + 1;
// Found "Qt ", now find the next '\0'.
const auto nullFoundIt = std::find(qtFoundIt, readEndIt, '\0');
if (nullFoundIt == readEndIt)
break;
// String much too long?
const size_t len = std::distance(qtFoundIt, nullFoundIt);
if (len > keepSpace)
continue;
// Does it contain " build; by "?
const auto buildByFoundIt = std::search(qtFoundIt, nullFoundIt,
buildNeedle.begin(), buildNeedle.end());
if (buildByFoundIt == nullFoundIt)
continue;
buildString = QByteArray(qtFoundIt, len);
break;
}
if (!buildString.isEmpty() || readEndIt != buffer.constEnd())
break;
std::move(copyStartIt, readEndIt, buffer.begin()); // Copy last section to front.
}
}
return buildString;
}
static Abi refineAbiFromBuildString(const QByteArray &buildString, const Abi &probableAbi)
{
if (buildString.isEmpty()
|| buildString.count() > 4096)
return Abi();
const QRegularExpression buildStringMatcher("^Qt "
"([\\d\\.a-zA-Z]*) " // Qt version
"\\("
"([a-z\\d_]*)-" // CPU
"(big|little)_endian-"
"([a-z]+(?:32|64))" // pointer information
"(?:-(qreal|))?" // extra information like -qreal
"(?:-([^-]+))? " // ABI information
"(shared|static) (?:\\(dynamic\\) )?"
"(debug|release)"
" build; by "
"(.*)" // compiler with extra info
"\\)$");
QTC_ASSERT(buildStringMatcher.isValid(), qWarning() << buildStringMatcher.errorString());
const QRegularExpressionMatch match = buildStringMatcher.match(QString::fromUtf8(buildString));
QTC_ASSERT(match.hasMatch(), return Abi());
// const QString qtVersion = match.captured(1);
// const QString cpu = match.captured(2);
// const bool littleEndian = (match.captured(3) == "little");
// const QString pointer = match.captured(4);
// const QString extra = match.captured(5);
// const QString abiString = match.captured(6);
// const QString linkage = match.captured(7);
// const QString buildType = match.captured(8);
const QString compiler = match.captured(9);
Abi::Architecture arch = probableAbi.architecture();
Abi::OS os = probableAbi.os();
Abi::OSFlavor flavor = probableAbi.osFlavor();
Abi::BinaryFormat format = probableAbi.binaryFormat();
unsigned char wordWidth = probableAbi.wordWidth();
if (compiler.startsWith("GCC ") && os == Abi::WindowsOS) {
flavor = Abi::WindowsMSysFlavor;
} else if (compiler.startsWith("MSVC 2005") && os == Abi::WindowsOS) {
flavor = Abi::WindowsMsvc2005Flavor;
} else if (compiler.startsWith("MSVC 2008") && os == Abi::WindowsOS) {
flavor = Abi::WindowsMsvc2008Flavor;
} else if (compiler.startsWith("MSVC 2010") && os == Abi::WindowsOS) {
flavor = Abi::WindowsMsvc2010Flavor;
} else if (compiler.startsWith("MSVC 2012") && os == Abi::WindowsOS) {
flavor = Abi::WindowsMsvc2012Flavor;
} else if (compiler.startsWith("MSVC 2015") && os == Abi::WindowsOS) {
flavor = Abi::WindowsMsvc2015Flavor;
} else if (compiler.startsWith("MSVC 2017") && os == Abi::WindowsOS) {
flavor = Abi::WindowsMsvc2017Flavor;
}
return Abi(arch, os, flavor, format, wordWidth);
}
static Abi scanQtBinaryForBuildStringAndRefineAbi(const FileName &library,
const Abi &probableAbi)
{
static QHash<Utils::FileName, Abi> results;
if (!results.contains(library)) {
const QByteArray buildString = scanQtBinaryForBuildString(library);
results.insert(library, refineAbiFromBuildString(buildString, probableAbi));
}
return results.value(library);
}
QList<Abi> BaseQtVersion::qtAbisFromLibrary(const FileNameList &coreLibraries)
{
QList<Abi> res;
foreach (const FileName &library, coreLibraries)
foreach (const Abi &abi, Abi::abisOfBinary(library))
if (!res.contains(abi))
res.append(abi);
foreach (const FileName &library, coreLibraries) {
for (Abi abi : Abi::abisOfBinary(library)) {
Abi tmp = abi;
if (abi.osFlavor() == Abi::UnknownFlavor)
tmp = scanQtBinaryForBuildStringAndRefineAbi(library, abi);
if (!res.contains(tmp))
res.append(tmp);
}
}
return res;
}

View File

@@ -191,6 +191,8 @@ void GenericDirectUploadService::handleUploadFinished(SftpJobId jobId, const QSt
this, &GenericDirectUploadService::handleStdOutData);
connect(d->chmodProc.data(), &SshRemoteProcess::readyReadStandardError,
this, &GenericDirectUploadService::handleStdErrData);
connect(d->chmodProc.data(), &SshRemoteProcess::readChannelFinished,
this, &GenericDirectUploadService::handleReadChannelFinished);
d->chmodProc->start();
} else {
uploadNextFile();
@@ -275,6 +277,8 @@ void GenericDirectUploadService::handleMkdirFinished(int exitStatus)
this, &GenericDirectUploadService::handleStdOutData);
connect(d->lnProc.data(), &SshRemoteProcess::readyReadStandardError,
this, &GenericDirectUploadService::handleStdErrData);
connect(d->lnProc.data(), &SshRemoteProcess::readChannelFinished,
this, &GenericDirectUploadService::handleReadChannelFinished);
d->lnProc->start();
} else {
const SftpJobId job = d->uploader->uploadFile(df.localFilePath().toString(),
@@ -310,6 +314,13 @@ void GenericDirectUploadService::handleStdErrData()
emit stdErrData(QString::fromUtf8(process->readAllStandardError()));
}
void GenericDirectUploadService::handleReadChannelFinished()
{
SshRemoteProcess * const process = qobject_cast<SshRemoteProcess *>(sender());
if (process && process->atEnd())
process->close();
}
void GenericDirectUploadService::stopDeployment()
{
QTC_ASSERT(d->state == InitializingSftp || d->state == Uploading, setFinished(); return);
@@ -383,6 +394,8 @@ void GenericDirectUploadService::uploadNextFile()
this, &GenericDirectUploadService::handleStdOutData);
connect(d->mkdirProc.data(), &SshRemoteProcess::readyReadStandardError,
this, &GenericDirectUploadService::handleStdErrData);
connect(d->mkdirProc.data(), &SshRemoteProcess::readChannelFinished,
this, &GenericDirectUploadService::handleReadChannelFinished);
emit progressMessage(tr("Uploading file \"%1\"...")
.arg(df.localFilePath().toUserOutput()));
d->mkdirProc->start();

View File

@@ -68,6 +68,7 @@ private:
void handleChmodFinished(int exitStatus);
void handleStdOutData();
void handleStdErrData();
void handleReadChannelFinished();
void checkDeploymentNeeded(const ProjectExplorer::DeployableFile &file) const;
void setFinished();

View File

@@ -443,6 +443,10 @@ void BookmarkWidget::setup()
treeView->setDropIndicatorShown(true);
treeView->viewport()->installEventFilter(this);
treeView->setContextMenuPolicy(Qt::CustomContextMenu);
// work around crash on Windows with drag & drop
// in combination with proxy model and ResizeToContents section resize mode
treeView->header()->setSectionResizeMode(QHeaderView::Stretch);
connect(treeView, &TreeView::expanded, this, &BookmarkWidget::expand);
connect(treeView, &TreeView::collapsed, this, &BookmarkWidget::expand);