forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.2'
Change-Id: If9b3a860d7efb561bb710d49396d6bbe13809aa1
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -68,6 +68,7 @@ private:
|
||||
void handleChmodFinished(int exitStatus);
|
||||
void handleStdOutData();
|
||||
void handleStdErrData();
|
||||
void handleReadChannelFinished();
|
||||
|
||||
void checkDeploymentNeeded(const ProjectExplorer::DeployableFile &file) const;
|
||||
void setFinished();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user