diff options
Diffstat (limited to 'src/plugins/android/androidconfigurations.cpp')
-rw-r--r-- | src/plugins/android/androidconfigurations.cpp | 135 |
1 files changed, 73 insertions, 62 deletions
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 292fe361da..87f2d8b60e 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -27,7 +27,6 @@ #include "androidconstants.h" #include "androidtoolchain.h" #include "androiddevice.h" -#include "androidgdbserverkitinformation.h" #include "androidmanager.h" #include "androidqtversion.h" #include "androiddevicedialog.h" @@ -140,7 +139,7 @@ namespace { SynchronousProcess proc; proc.setProcessChannelMode(QProcess::MergedChannels); proc.setTimeoutS(30); - SynchronousProcessResponse response = proc.runBlocking(executable, QStringList(shell)); + SynchronousProcessResponse response = proc.runBlocking({executable, {shell}}); if (response.result != SynchronousProcessResponse::Finished) return true; return !response.allOutput().contains("x86-64"); @@ -364,11 +363,9 @@ FilePath AndroidConfig::aaptToolPath() const return aaptToolPath.pathAppended(toolPath); } -FilePath AndroidConfig::clangPath() const +FilePath AndroidConfig::toolchainPath() const { - const FilePath clangPath = m_ndkLocation.pathAppended("toolchains/llvm/prebuilt/"); - const FilePath oldNdkClangPath = m_ndkLocation.pathAppended("toolchains/llvm-3.6/prebuilt/"); - const QVector<FilePath> clangSearchPaths{clangPath, oldNdkClangPath}; + const FilePath toolchainPath = m_ndkLocation.pathAppended("toolchains/llvm/prebuilt/"); // detect toolchain host QStringList hostPatterns; @@ -385,18 +382,23 @@ FilePath AndroidConfig::clangPath() const default: /* unknown host */ return FilePath(); } - for (const FilePath &path : clangSearchPaths) { - QDirIterator iter(path.toString(), hostPatterns, QDir::Dirs); - if (iter.hasNext()) { - iter.next(); - return path.pathAppended(iter.fileName()) - .pathAppended(HostOsInfo::withExecutableSuffix("bin/clang")); - } + QDirIterator iter(toolchainPath.toString(), hostPatterns, QDir::Dirs); + if (iter.hasNext()) { + iter.next(); + return toolchainPath.pathAppended(iter.fileName()); } return {}; } +FilePath AndroidConfig::clangPath() const +{ + const FilePath path = toolchainPath(); + if (path.isEmpty()) + return {}; + return path.pathAppended(HostOsInfo::withExecutableSuffix("bin/clang")); +} + FilePath AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi) const { const FilePath path = m_ndkLocation.pathAppended( @@ -429,20 +431,20 @@ FilePath AndroidConfig::keytoolPath() const QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(QString *error) const { - return connectedDevices(adbToolPath().toString(), error); + return connectedDevices(adbToolPath(), error); } -QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const QString &adbToolPath, QString *error) +QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const FilePath &adbToolPath, QString *error) { QVector<AndroidDeviceInfo> devices; SynchronousProcess adbProc; adbProc.setTimeoutS(30); - SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, QStringList("devices")); + CommandLine cmd{adbToolPath, {"devices"}}; + SynchronousProcessResponse response = adbProc.runBlocking(cmd); if (response.result != SynchronousProcessResponse::Finished) { if (error) - *error = QApplication::translate("AndroidConfiguration", - "Could not run: %1") - .arg(adbToolPath + QLatin1String(" devices")); + *error = QApplication::translate("AndroidConfiguration", "Could not run: %1") + .arg(cmd.toUserOutput()); return devices; } QStringList adbDevs = response.allOutput().split('\n', QString::SkipEmptyParts); @@ -485,7 +487,7 @@ QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const QString &adbToo if (devices.isEmpty() && error) *error = QApplication::translate("AndroidConfiguration", "No devices found in output of: %1") - .arg(adbToolPath + QLatin1String(" devices")); + .arg(cmd.toUserOutput()); return devices; } @@ -501,33 +503,33 @@ bool AndroidConfig::isConnected(const QString &serialNumber) const bool AndroidConfig::isBootToQt(const QString &device) const { - return isBootToQt(adbToolPath().toString(), device); + return isBootToQt(adbToolPath(), device); } -bool AndroidConfig::isBootToQt(const QString &adbToolPath, const QString &device) +bool AndroidConfig::isBootToQt(const FilePath &adbToolPath, const QString &device) { // workaround for '????????????' serial numbers - QStringList arguments = AndroidDeviceInfo::adbSelector(device); - arguments << QLatin1String("shell") - << QLatin1String("ls -l /system/bin/appcontroller || ls -l /usr/bin/appcontroller && echo Boot2Qt"); + CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device)); + cmd.addArg("shell"); + cmd.addArg("ls -l /system/bin/appcontroller || ls -l /usr/bin/appcontroller && echo Boot2Qt"); SynchronousProcess adbProc; adbProc.setTimeoutS(10); - SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments); + SynchronousProcessResponse response = adbProc.runBlocking(cmd); return response.result == SynchronousProcessResponse::Finished && response.allOutput().contains(QLatin1String("Boot2Qt")); } -QString AndroidConfig::getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property) +QString AndroidConfig::getDeviceProperty(const FilePath &adbToolPath, const QString &device, const QString &property) { // workaround for '????????????' serial numbers - QStringList arguments = AndroidDeviceInfo::adbSelector(device); - arguments << QLatin1String("shell") << QLatin1String("getprop") << property; + CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device)); + cmd.addArgs({"shell", "getprop", property}); SynchronousProcess adbProc; adbProc.setTimeoutS(10); - SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments); + SynchronousProcessResponse response = adbProc.runBlocking(cmd); if (response.result != SynchronousProcessResponse::Finished) return QString(); @@ -536,12 +538,12 @@ QString AndroidConfig::getDeviceProperty(const QString &adbToolPath, const QStri int AndroidConfig::getSDKVersion(const QString &device) const { - return getSDKVersion(adbToolPath().toString(), device); + return getSDKVersion(adbToolPath(), device); } -int AndroidConfig::getSDKVersion(const QString &adbToolPath, const QString &device) +int AndroidConfig::getSDKVersion(const FilePath &adbToolPath, const QString &device) { - QString tmp = getDeviceProperty(adbToolPath, device, QLatin1String("ro.build.version.sdk")); + QString tmp = getDeviceProperty(adbToolPath, device, "ro.build.version.sdk"); if (tmp.isEmpty()) return -1; return tmp.trimmed().toInt(); @@ -612,7 +614,7 @@ QString AndroidConfig::getProductModel(const QString &device) const if (m_serialNumberToDeviceName.contains(device)) return m_serialNumberToDeviceName.value(device); - QString model = getDeviceProperty(adbToolPath().toString(), device, QLatin1String("ro.product.model")).trimmed(); + QString model = getDeviceProperty(adbToolPath(), device, "ro.product.model").trimmed(); if (model.isEmpty()) return device; @@ -623,18 +625,18 @@ QString AndroidConfig::getProductModel(const QString &device) const QStringList AndroidConfig::getAbis(const QString &device) const { - return getAbis(adbToolPath().toString(), device); + return getAbis(adbToolPath(), device); } -QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &device) +QStringList AndroidConfig::getAbis(const FilePath &adbToolPath, const QString &device) { QStringList result; // First try via ro.product.cpu.abilist QStringList arguments = AndroidDeviceInfo::adbSelector(device); - arguments << QLatin1String("shell") << QLatin1String("getprop") << QLatin1String("ro.product.cpu.abilist"); + arguments << "shell" << "getprop" << "ro.product.cpu.abilist"; SynchronousProcess adbProc; adbProc.setTimeoutS(10); - SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments); + SynchronousProcessResponse response = adbProc.runBlocking({adbToolPath, arguments}); if (response.result != SynchronousProcessResponse::Finished) return result; @@ -656,7 +658,7 @@ QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &de SynchronousProcess abiProc; abiProc.setTimeoutS(10); - SynchronousProcessResponse abiResponse = abiProc.runBlocking(adbToolPath, arguments); + SynchronousProcessResponse abiResponse = abiProc.runBlocking({adbToolPath, arguments}); if (abiResponse.result != SynchronousProcessResponse::Finished) return result; @@ -733,22 +735,26 @@ FilePath AndroidConfig::ndkLocation() const return m_ndkLocation; } -static inline QString gdbServerArch(const Abi &abi) +static inline QString gdbServerArch(const QString &androidAbi) { - switch (abi.architecture()) { - case Abi::X86Architecture: - return abi.wordWidth() == 64 ? QString{"x86_64"} : QString{"x86"}; - case Abi::ArmArchitecture: - return abi.wordWidth() == 64 ? QString{"arm64"} : QString{"arm"}; - default: return {}; - }; + if (androidAbi == "arm64-v8a") { + return QString("arm64"); + } else if (androidAbi == "armeabi-v7a") { + return QString("arm"); + } else if (androidAbi == "x86_64") { + return QString("x86_64"); + } else if (androidAbi == "x86") { + return QString("x86"); + } else { + return {}; + } } -FilePath AndroidConfig::gdbServer(const ProjectExplorer::Abi &abi) const +FilePath AndroidConfig::gdbServer(const QString &androidAbi) const { const FilePath path = AndroidConfigurations::currentConfig().ndkLocation() .pathAppended(QString("prebuilt/android-%1/gdbserver/gdbserver") - .arg(gdbServerArch(abi))); + .arg(gdbServerArch(androidAbi))); if (path.exists()) return path; return {}; @@ -875,16 +881,21 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs) } AndroidDeviceInfo AndroidConfigurations::showDeviceDialog(Project *project, - int apiLevel, const QString &abi) + int apiLevel, const QStringList &abis) { - QString serialNumber = defaultDevice(project, abi); - AndroidDeviceDialog dialog(apiLevel, abi, serialNumber, Core::ICore::mainWindow()); + QString serialNumber; + for (const QString &abi : abis) { + serialNumber = defaultDevice(project, abi); + if (!serialNumber.isEmpty()) + break; + } + AndroidDeviceDialog dialog(apiLevel, abis, serialNumber, Core::ICore::mainWindow()); AndroidDeviceInfo info = dialog.device(); if (dialog.saveDeviceSelection() && info.isValid()) { const QString serialNumber = info.type == AndroidDeviceInfo::Hardware ? info.serialNumber : info.avdname; if (!serialNumber.isEmpty()) - AndroidConfigurations::setDefaultDevice(project, abi, serialNumber); + AndroidConfigurations::setDefaultDevice(project, AndroidManager::devicePreferredAbi(info.cpuAbi, abis), serialNumber); } return info; } @@ -918,7 +929,7 @@ static bool matchToolChain(const ToolChain *atc, const ToolChain *btc) if (!atc || !btc) return false; - if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_ID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_ID) + if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID) return false; auto aatc = static_cast<const AndroidToolChain *>(atc); @@ -930,7 +941,7 @@ void AndroidConfigurations::registerNewToolChains() { const QList<ToolChain *> existingAndroidToolChains = ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, - Core::Id(Constants::ANDROID_TOOLCHAIN_ID))); + Core::Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); const QList<ToolChain *> newToolchains = AndroidToolChainFactory::autodetectToolChainsForNdk(existingAndroidToolChains); foreach (ToolChain *tc, newToolchains) @@ -939,7 +950,7 @@ void AndroidConfigurations::registerNewToolChains() void AndroidConfigurations::removeOldToolChains() { - foreach (ToolChain *tc, ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_ID)))) { + foreach (ToolChain *tc, ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_TYPEID)))) { if (!tc->isValid()) ToolChainManager::deregisterToolChain(tc); } @@ -947,7 +958,7 @@ void AndroidConfigurations::removeOldToolChains() static QVariant findOrRegisterDebugger(ToolChain *tc) { - const FilePath command = tc->suggestedDebugger(); + const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi()); // check if the debugger is already registered, but ignoring the display name const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command); if (existing && existing->engineType() == Debugger::GdbEngineType && existing->isAutoDetected() @@ -955,7 +966,7 @@ static QVariant findOrRegisterDebugger(ToolChain *tc) return existing->id(); // debugger not found, register a new one Debugger::DebuggerItem debugger; - debugger.setCommand(tc->suggestedDebugger()); + debugger.setCommand(command); debugger.setEngineType(Debugger::GdbEngineType); debugger.setUnexpandedDisplayName( AndroidConfigurations::tr("Android Debugger for %1").arg(tc->displayName())); @@ -1016,7 +1027,7 @@ void AndroidConfigurations::updateAutomaticKitList() const QList<ToolChain *> toolchains = ToolChainManager::toolChains([](const ToolChain *tc) { return tc->isAutoDetected() && tc->isValid() - && tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID; + && tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID; }); for (ToolChain *tc : toolchains) { if (tc->language() != Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID)) @@ -1049,10 +1060,9 @@ void AndroidConfigurations::updateAutomaticKitList() QtSupport::QtKitAspect::setQtVersion(k, qt); DeviceKitAspect::setDevice(k, device); Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc)); - AndroidGdbServerKitAspect::setGdbSever(k, currentConfig().gdbServer(tc->targetAbi())); k->makeSticky(); k->setUnexpandedDisplayName(tr("Android for %1 (Clang %2)") - .arg(static_cast<const AndroidQtVersion *>(qt)->targetArch()) + .arg(static_cast<const AndroidQtVersion *>(qt)->androidAbis().join(",")) .arg(qt->displayName())); k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation().toString()); k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); @@ -1187,7 +1197,8 @@ void AndroidConfigurations::load() SynchronousProcess proc; proc.setTimeoutS(2); proc.setProcessChannelMode(QProcess::MergedChannels); - SynchronousProcessResponse response = proc.runBlocking(javaHomeExec.absoluteFilePath(), QStringList()); + SynchronousProcessResponse response = + proc.runBlocking({javaHomeExec.absoluteFilePath(), {}}); if (response.result == SynchronousProcessResponse::Finished) { const QString &javaHome = response.allOutput().trimmed(); if (!javaHome.isEmpty() && QFileInfo::exists(javaHome)) |