diff options
Diffstat (limited to 'src/plugins/android/androidsettingswidget.cpp')
-rw-r--r-- | src/plugins/android/androidsettingswidget.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index 4fc6d78ec7..7243f99de5 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -49,6 +49,8 @@ #include <QFile> #include <QTextStream> #include <QProcess> +#include <QTimer> +#include <QTime> #include <QDesktopServices> #include <QFileDialog> @@ -134,6 +136,9 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent) { m_ui->setupUi(this); + connect(&m_checkGdbWatcher, SIGNAL(finished()), + this, SLOT(checkGdbFinished())); + m_ui->SDKLocationPathChooser->setFileName(m_androidConfig.sdkLocation()); m_ui->SDKLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK folder")); m_ui->NDKLocationPathChooser->setFileName(m_androidConfig.ndkLocation()); @@ -170,6 +175,9 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent) m_ui->downloadAntToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost()); m_ui->downloadOpenJDKToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost()); + connect(m_ui->gdbWarningLabel, SIGNAL(linkActivated(QString)), + this, SLOT(showGdbWarningDialog())); + check(All); applyToUi(All); @@ -183,6 +191,50 @@ AndroidSettingsWidget::~AndroidSettingsWidget() m_futureWatcher.waitForFinished(); } +// NOTE: Will be run via QFuture +static QPair<QStringList, bool> checkGdbForBrokenPython(const QStringList &paths) +{ + foreach (const QString &path, paths) { + QTime timer; + timer.start(); + QProcess proc; + proc.setProcessChannelMode(QProcess::MergedChannels); + proc.start(path); + proc.waitForStarted(); + + QByteArray output; + while (proc.waitForReadyRead(300)) { + output += proc.readAll(); + if (output.contains("(gdb)")) + break; + if (timer.elapsed() > 7 * 1000) + return qMakePair(paths, true); // Took too long, abort + } + + output.clear(); + + proc.write("python import string\n"); + proc.write("python print(string.ascii_uppercase)\n"); + proc.write("python import struct\n"); + proc.write("quit\n"); + while (proc.waitForFinished(300)) { + if (timer.elapsed() > 9 * 1000) + return qMakePair(paths, true); // Took too long, abort + } + proc.waitForFinished(); + + output = proc.readAll(); + + bool error = output.contains("_PyObject_Free") + || output.contains("_PyExc_IOError") + || output.contains("_sysconfigdata_nd ") + || !output.contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (error) + return qMakePair(paths, error); + } + return qMakePair(paths, false); +} + void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode) { if (mode & Sdk) { @@ -198,6 +250,8 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode) Utils::FileName platformPath = m_androidConfig.ndkLocation(); Utils::FileName toolChainPath = m_androidConfig.ndkLocation(); Utils::FileName sourcesPath = m_androidConfig.ndkLocation(); + m_ui->gdbWarningIconLabel->setVisible(false); + m_ui->gdbWarningLabel->setVisible(false); if (m_androidConfig.ndkLocation().isEmpty()) { m_ndkState = NotSet; } else if (!platformPath.appendPath(QLatin1String("platforms")).toFileInfo().exists() @@ -214,6 +268,21 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode) = AndroidToolChainFactory::toolchainPathsForNdk(m_androidConfig.ndkLocation()); m_ndkCompilerCount = compilerPaths.count(); + // Check for a gdb with a broken python + QStringList gdbPaths; + foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) { + // we only check the arm gdbs, that's indicative enough + if (ati.architecture != ProjectExplorer::Abi::ArmArchitecture) + continue; + Utils::FileName gdbPath = m_androidConfig.gdbPath(ati.architecture, ati.version); + if (gdbPath.toFileInfo().exists()) + gdbPaths << gdbPath.toString(); + } + + if (!gdbPaths.isEmpty()) { + m_checkGdbWatcher.setFuture(QtConcurrent::run(&checkGdbForBrokenPython, gdbPaths)); + m_gdbCheckPaths = gdbPaths; + } // See if we have qt versions for those toolchains QSet<ProjectExplorer::Abi::Architecture> toolchainsForArch; @@ -508,6 +577,25 @@ void AndroidSettingsWidget::createKitToggled() m_androidConfig.setAutomaticKitCreation(m_ui->CreateKitCheckBox->isChecked()); } +void AndroidSettingsWidget::checkGdbFinished() +{ + QPair<QStringList, bool> result = m_checkGdbWatcher.future().result(); + if (result.first != m_gdbCheckPaths) // no longer relevant + return; + m_ui->gdbWarningIconLabel->setVisible(result.second); + m_ui->gdbWarningLabel->setVisible(result.second); +} + +void AndroidSettingsWidget::showGdbWarningDialog() +{ + QMessageBox::warning(this, + tr("Unsupported GDB"), + tr("The GDB inside this NDK seems to not support Python. " + "The Qt Project offers fixed GDB builds at: " + "<a href=\"http://download.qt-project.org/official_releases/gdb/osx/\">" + "http://download.qt-project.org/official_releases/gdb/osx/</a>")); +} + void AndroidSettingsWidget::manageAVD() { QProcess *avdProcess = new QProcess(); |