Android: Check for broken gdb on mac

Task-number: QTCREATORBUG-12636

Change-Id: Ib41db2607fef6291c1464e5ce2ea626fd86b3025
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
Daniel Teske
2014-07-23 11:54:36 +02:00
parent 99baab0429
commit 06bb01249b
3 changed files with 333 additions and 173 deletions

View File

@@ -49,6 +49,8 @@
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <QProcess> #include <QProcess>
#include <QTimer>
#include <QTime>
#include <QDesktopServices> #include <QDesktopServices>
#include <QFileDialog> #include <QFileDialog>
@@ -170,11 +172,16 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
m_ui->downloadAntToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost()); m_ui->downloadAntToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost());
m_ui->downloadOpenJDKToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost()); m_ui->downloadOpenJDKToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost());
connect(m_ui->gdbWarningLabel, SIGNAL(linkActivated(QString)),
this, SLOT(showGdbWarningDialog()));
check(All); check(All);
applyToUi(All); applyToUi(All);
connect(&m_futureWatcher, SIGNAL(finished()), connect(&m_futureWatcher, SIGNAL(finished()),
this, SLOT(avdAdded())); this, SLOT(avdAdded()));
connect(&m_checkGdbWatcher, SIGNAL(finished()),
this, SLOT(checkGdbFinished()));
} }
AndroidSettingsWidget::~AndroidSettingsWidget() AndroidSettingsWidget::~AndroidSettingsWidget()
@@ -183,6 +190,41 @@ AndroidSettingsWidget::~AndroidSettingsWidget()
m_futureWatcher.waitForFinished(); m_futureWatcher.waitForFinished();
} }
// NOTE: Will be run via QFuture
static QPair<QString, bool> checkGdbForBrokenPython(const QString &path)
{
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(path, false); // Took too long, abort
}
output.clear();
proc.write("python import struct\n");
proc.write("quit\n");
while (proc.waitForFinished(300)) {
if (timer.elapsed() > 9 * 1000)
return qMakePair(path, false); // Took too long, abort
}
proc.waitForFinished();
output = proc.readAll();
bool error = output.contains("_PyObject_Free") || output.contains("_PyExc_IOError");
return qMakePair(path, error);
}
void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode) void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
{ {
if (mode & Sdk) { if (mode & Sdk) {
@@ -214,6 +256,23 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
= AndroidToolChainFactory::toolchainPathsForNdk(m_androidConfig.ndkLocation()); = AndroidToolChainFactory::toolchainPathsForNdk(m_androidConfig.ndkLocation());
m_ndkCompilerCount = compilerPaths.count(); m_ndkCompilerCount = compilerPaths.count();
// Check for a gdb with a broken python
if (Utils::HostOsInfo::isMacHost()) {
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 = AndroidConfigurations::currentConfig().gdbPath(ati.architecture, ati.version);
if (gdbPath.toFileInfo().exists()) {
m_ui->gdbWarningIconLabel->setVisible(false);
m_ui->gdbWarningLabel->setVisible(false);
m_checkGdbWatcher.setFuture(QtConcurrent::run(&checkGdbForBrokenPython, gdbPath.toString()));
m_gdbCheckPath = gdbPath.toString();
break;
}
}
}
// See if we have qt versions for those toolchains // See if we have qt versions for those toolchains
QSet<ProjectExplorer::Abi::Architecture> toolchainsForArch; QSet<ProjectExplorer::Abi::Architecture> toolchainsForArch;
@@ -508,6 +567,25 @@ void AndroidSettingsWidget::createKitToggled()
m_androidConfig.setAutomaticKitCreation(m_ui->CreateKitCheckBox->isChecked()); m_androidConfig.setAutomaticKitCreation(m_ui->CreateKitCheckBox->isChecked());
} }
void AndroidSettingsWidget::checkGdbFinished()
{
QPair<QString, bool> result = m_checkGdbWatcher.future().result();
if (result.first != m_gdbCheckPath) // 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() void AndroidSettingsWidget::manageAVD()
{ {
QProcess *avdProcess = new QProcess(); QProcess *avdProcess = new QProcess();

View File

@@ -92,6 +92,9 @@ private slots:
void manageAVD(); void manageAVD();
void createKitToggled(); void createKitToggled();
void checkGdbFinished();
void showGdbWarningDialog();
private: private:
enum Mode { Sdk = 1, Ndk = 2, Java = 4, All = Sdk | Ndk | Java }; enum Mode { Sdk = 1, Ndk = 2, Java = 4, All = Sdk | Ndk | Java };
enum State { NotSet = 0, Okay = 1, Error = 2 }; enum State { NotSet = 0, Okay = 1, Error = 2 };
@@ -111,6 +114,8 @@ private:
AndroidConfig m_androidConfig; AndroidConfig m_androidConfig;
AvdModel m_AVDModel; AvdModel m_AVDModel;
QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher; QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher;
QFutureWatcher<QPair<QString, bool>> m_checkGdbWatcher;
QString m_gdbCheckPath;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -6,45 +6,34 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>573</width> <width>843</width>
<height>429</height> <height>625</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Android Configuration</string> <string>Android Configuration</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0,0"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="2" column="0">
<widget class="QLabel" name="OpenJDKLocationLabel"> <widget class="QLabel" name="SDKLocationLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>JDK location:</string> <string>Android SDK location:</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1" colspan="2"> <item row="10" column="1">
<widget class="Utils::PathChooser" name="OpenJDKLocationPathChooser" native="true"/> <widget class="Utils::PathChooser" name="AntLocationPathChooser" native="true"/>
</item> </item>
<item row="0" column="3"> <item row="1" column="1">
<widget class="QToolButton" name="downloadOpenJDKToolButton">
<property name="toolTip">
<string>Download JDK</string>
</property>
<property name="icon">
<iconset resource="android.qrc">
<normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_5"> <layout class="QHBoxLayout" name="horizontalLayout_5">
<item> <item>
<widget class="QLabel" name="jdkWarningIconLabel"> <widget class="QLabel" name="jdkWarningIconLabel">
@@ -58,7 +47,7 @@
<string/> <string/>
</property> </property>
<property name="pixmap"> <property name="pixmap">
<pixmap>:/core/images/warning.png</pixmap> <pixmap resource="../coreplugin/core.qrc">:/core/images/warning.png</pixmap>
</property> </property>
</widget> </widget>
</item> </item>
@@ -80,37 +69,7 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="0"> <item row="3" column="1">
<widget class="QLabel" name="SDKLocationLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Android SDK location:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="downloadSDKToolButton">
<property name="toolTip">
<string>Download Android SDK</string>
</property>
<property name="icon">
<iconset resource="android.qrc">
<normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<item> <item>
<widget class="QLabel" name="sdkWarningIconLabel"> <widget class="QLabel" name="sdkWarningIconLabel">
@@ -146,29 +105,13 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="4" column="0"> <item row="0" column="1">
<widget class="QLabel" name="NDKLocationLabel"> <widget class="Utils::PathChooser" name="OpenJDKLocationPathChooser" native="true"/>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Android NDK location:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item> </item>
<item row="4" column="1" colspan="2"> <item row="10" column="2">
<widget class="Utils::PathChooser" name="NDKLocationPathChooser" native="true"/> <widget class="QToolButton" name="downloadAntToolButton">
</item>
<item row="4" column="3">
<widget class="QToolButton" name="downloadNDKToolButton">
<property name="toolTip"> <property name="toolTip">
<string>Download Android NDK</string> <string>Download Ant</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="android.qrc"> <iconset resource="android.qrc">
@@ -176,98 +119,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1" colspan="3"> <item row="10" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="ndkWarningIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../coreplugin/core.qrc">:/core/images/error.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="toolchainFoundLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="1" colspan="3">
<widget class="QCheckBox" name="CreateKitCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatically create kits for Android tool chains</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="kitWarningIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../coreplugin/core.qrc">:/core/images/warning.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="kitWarningLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="8" column="0">
<widget class="QLabel" name="AntLocationLabel"> <widget class="QLabel" name="AntLocationLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -283,13 +135,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1" colspan="2"> <item row="2" column="2">
<widget class="Utils::PathChooser" name="AntLocationPathChooser" native="true"/> <widget class="QToolButton" name="downloadSDKToolButton">
</item>
<item row="8" column="3">
<widget class="QToolButton" name="downloadAntToolButton">
<property name="toolTip"> <property name="toolTip">
<string>Download Ant</string> <string>Download Android SDK</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="android.qrc"> <iconset resource="android.qrc">
@@ -297,7 +146,18 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0" colspan="4"> <item row="4" column="2">
<widget class="QToolButton" name="downloadNDKToolButton">
<property name="toolTip">
<string>Download Android NDK</string>
</property>
<property name="icon">
<iconset resource="android.qrc">
<normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QFrame" name="AVDManagerFrame"> <widget class="QFrame" name="AVDManagerFrame">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
@@ -416,6 +276,182 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="OpenJDKLocationLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>JDK location:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="ndkWarningIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../coreplugin/core.qrc">:/core/images/error.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="toolchainFoundLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="NDKLocationLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Android NDK location:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Utils::PathChooser" name="NDKLocationPathChooser" native="true"/>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="downloadOpenJDKToolButton">
<property name="toolTip">
<string>Download JDK</string>
</property>
<property name="icon">
<iconset resource="android.qrc">
<normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="CreateKitCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatically create kits for Android tool chains</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="kitWarningIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../coreplugin/core.qrc">:/core/images/warning.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="kitWarningLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="gdbWarningIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../coreplugin/core.qrc">:/core/images/error.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="gdbWarningLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;a href=&quot;xx&quot;&gt;The GDB in the NDK appears to have broken python support.&lt;/a&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>
@@ -428,6 +464,7 @@
</customwidgets> </customwidgets>
<resources> <resources>
<include location="android.qrc"/> <include location="android.qrc"/>
<include location="../coreplugin/core.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>
@@ -627,24 +664,64 @@
<signal>clicked()</signal> <signal>clicked()</signal>
<receiver>AndroidSettingsWidget</receiver> <receiver>AndroidSettingsWidget</receiver>
<slot>openSDKDownloadUrl()</slot> <slot>openSDKDownloadUrl()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection> </connection>
<connection> <connection>
<sender>downloadNDKToolButton</sender> <sender>downloadNDKToolButton</sender>
<signal>clicked()</signal> <signal>clicked()</signal>
<receiver>AndroidSettingsWidget</receiver> <receiver>AndroidSettingsWidget</receiver>
<slot>openNDKDownloadUrl()</slot> <slot>openNDKDownloadUrl()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection> </connection>
<connection> <connection>
<sender>downloadAntToolButton</sender> <sender>downloadAntToolButton</sender>
<signal>clicked()</signal> <signal>clicked()</signal>
<receiver>AndroidSettingsWidget</receiver> <receiver>AndroidSettingsWidget</receiver>
<slot>openAntDownloadUrl()</slot> <slot>openAntDownloadUrl()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection> </connection>
<connection> <connection>
<sender>downloadOpenJDKToolButton</sender> <sender>downloadOpenJDKToolButton</sender>
<signal>clicked()</signal> <signal>clicked()</signal>
<receiver>AndroidSettingsWidget</receiver> <receiver>AndroidSettingsWidget</receiver>
<slot>openOpenJDKDownloadUrl()</slot> <slot>openOpenJDKDownloadUrl()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection> </connection>
</connections> </connections>
<slots> <slots>