Commit cb48e485 authored by Daniel Teske's avatar Daniel Teske

Android 64bit toolchains

Change-Id: Ia2b57013b392237434ea3649c4f60a671e84ceb5
Reviewed-by: default avatarEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Reviewed-by: default avatarBogDan Vatra <bogdan@kde.org>
parent e1c426f2
......@@ -90,12 +90,25 @@ namespace {
const QLatin1String DefaultDevice("DefaultDevice");
const QLatin1String PartitionSizeKey("PartitionSize");
const QLatin1String ToolchainHostKey("ToolchainHost");
const QLatin1String ArmToolchainPrefix("arm-linux-androideabi");
const QLatin1String X86ToolchainPrefix("x86");
const QLatin1String MipsToolchainPrefix("mipsel-linux-android");
const QLatin1String AArch64ToolchainPrefix("aarch64-linux-android");
const QLatin1String X86_64ToolchainPrefix("x86_64");
const QLatin1String ArmToolsPrefix("arm-linux-androideabi");
const QLatin1String X86ToolsPrefix("i686-linux-android");
const QLatin1String MipsToolsPrefix("mipsel-linux-android");
const QLatin1String AArch64ToolsPrefix("aarch64-linux-android");
const QLatin1String X86_64ToolsPrefix("x86_64-linux-android");
const QLatin1String ArmToolsDisplayName("arm");
const QLatin1String X86ToolsDisplayName("i686");
const QLatin1String MipsToolsDisplayName("mipsel");
const QLatin1String AArch64ToolsDisplayName("aarch64");
const QLatin1String X86_64ToolsDisplayName("x86_64");
const QLatin1String Unknown("unknown");
const QLatin1String keytoolName("keytool");
const QLatin1String jarsignerName("jarsigner");
......@@ -164,23 +177,41 @@ namespace {
// AndroidConfig
//////////////////////////////////
Abi::Architecture AndroidConfig::architectureForToolChainPrefix(const QString& toolchainprefix)
{
if (toolchainprefix == ArmToolchainPrefix)
return Abi::ArmArchitecture;
if (toolchainprefix == X86ToolchainPrefix)
return Abi::X86Architecture;
if (toolchainprefix == MipsToolchainPrefix)
return Abi::MipsArchitecture;
return Abi::UnknownArchitecture;
Abi AndroidConfig::abiForToolChainPrefix(const QString &toolchainPrefix)
{
Abi::Architecture arch = Abi::UnknownArchitecture;
unsigned char wordWidth = 32;
if (toolchainPrefix == ArmToolchainPrefix) {
arch = Abi::ArmArchitecture;
} else if (toolchainPrefix == X86ToolchainPrefix) {
arch = Abi::X86Architecture;
} else if (toolchainPrefix == MipsToolchainPrefix) {
arch = Abi::MipsArchitecture;
} else if (toolchainPrefix == AArch64ToolchainPrefix) {
arch = Abi::ArmArchitecture;
wordWidth = 64;
} else if (toolchainPrefix == X86_64ToolchainPrefix) {
arch = Abi::X86Architecture;
wordWidth = 64;
}
Abi abi = ProjectExplorer::Abi(arch,
ProjectExplorer::Abi::LinuxOS,
ProjectExplorer::Abi::AndroidLinuxFlavor, ProjectExplorer::Abi::ElfFormat,
wordWidth);
return abi;
}
QLatin1String AndroidConfig::toolchainPrefix(Abi::Architecture architecture)
QLatin1String AndroidConfig::toolchainPrefix(const Abi &abi)
{
switch (architecture) {
switch (abi.architecture()) {
case Abi::ArmArchitecture:
if (abi.wordWidth() == 64)
return AArch64ToolchainPrefix;
return ArmToolchainPrefix;
case Abi::X86Architecture:
if (abi.wordWidth() == 64)
return X86_64ToolchainPrefix;
return X86ToolchainPrefix;
case Abi::MipsArchitecture:
return MipsToolchainPrefix;
......@@ -189,12 +220,16 @@ QLatin1String AndroidConfig::toolchainPrefix(Abi::Architecture architecture)
}
}
QLatin1String AndroidConfig::toolsPrefix(Abi::Architecture architecture)
QLatin1String AndroidConfig::toolsPrefix(const Abi &abi)
{
switch (architecture) {
switch (abi.architecture()) {
case Abi::ArmArchitecture:
if (abi.wordWidth() == 64)
return AArch64ToolsPrefix;
return ArmToolsPrefix;
case Abi::X86Architecture:
if (abi.wordWidth() == 64)
return X86_64ToolsPrefix;
return X86ToolsPrefix;
case Abi::MipsArchitecture:
return MipsToolsPrefix;
......@@ -203,6 +238,24 @@ QLatin1String AndroidConfig::toolsPrefix(Abi::Architecture architecture)
}
}
QLatin1String AndroidConfig::displayName(const Abi &abi)
{
switch (abi.architecture()) {
case Abi::ArmArchitecture:
if (abi.wordWidth() == 64)
return AArch64ToolsDisplayName;
return ArmToolsDisplayName;
case Abi::X86Architecture:
if (abi.wordWidth() == 64)
return X86_64ToolsDisplayName;
return X86ToolsDisplayName;
case Abi::MipsArchitecture:
return MipsToolsDisplayName;
default:
return Unknown;
}
}
void AndroidConfig::load(const QSettings &settings)
{
// user settings
......@@ -433,24 +486,24 @@ FileName AndroidConfig::emulatorToolPath() const
return path.appendPath(QLatin1String("tools/emulator" QTC_HOST_EXE_SUFFIX));
}
FileName AndroidConfig::toolPath(Abi::Architecture architecture, const QString &ndkToolChainVersion) const
FileName AndroidConfig::toolPath(const Abi &abi, const QString &ndkToolChainVersion) const
{
FileName path = m_ndkLocation;
return path.appendPath(QString::fromLatin1("toolchains/%1-%2/prebuilt/%3/bin/%4")
.arg(toolchainPrefix(architecture))
.arg(toolchainPrefix(abi))
.arg(ndkToolChainVersion)
.arg(toolchainHost())
.arg(toolsPrefix(architecture)));
.arg(toolsPrefix(abi)));
}
FileName AndroidConfig::gccPath(Abi::Architecture architecture, const QString &ndkToolChainVersion) const
FileName AndroidConfig::gccPath(const Abi &abi, const QString &ndkToolChainVersion) const
{
return toolPath(architecture, ndkToolChainVersion).appendString(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX));
return toolPath(abi, ndkToolChainVersion).appendString(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX));
}
FileName AndroidConfig::gdbPath(Abi::Architecture architecture, const QString &ndkToolChainVersion) const
FileName AndroidConfig::gdbPath(const Abi &abi, const QString &ndkToolChainVersion) const
{
return toolPath(architecture, ndkToolChainVersion).appendString(QLatin1String("-gdb" QTC_HOST_EXE_SUFFIX));
return toolPath(abi, ndkToolChainVersion).appendString(QLatin1String("-gdb" QTC_HOST_EXE_SUFFIX));
}
FileName AndroidConfig::openJDKBinPath() const
......@@ -1138,14 +1191,14 @@ void AndroidConfigurations::updateAutomaticKitList()
existingKits << k;
}
QMap<Abi::Architecture, QList<QtSupport::BaseQtVersion *> > qtVersionsForArch;
QHash<Abi, QList<QtSupport::BaseQtVersion *> > qtVersionsForArch;
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::versions()) {
if (qtVersion->type() != QLatin1String(Constants::ANDROIDQT))
continue;
QList<Abi> qtAbis = qtVersion->qtAbis();
if (qtAbis.empty())
continue;
qtVersionsForArch[qtAbis.first().architecture()].append(qtVersion);
qtVersionsForArch[qtAbis.first()].append(qtVersion);
}
DeviceManager *dm = DeviceManager::instance();
......@@ -1162,7 +1215,7 @@ void AndroidConfigurations::updateAutomaticKitList()
foreach (AndroidToolChain *tc, toolchains) {
if (tc->isSecondaryToolChain())
continue;
QList<QtSupport::BaseQtVersion *> qtVersions = qtVersionsForArch.value(tc->targetAbi().architecture());
QList<QtSupport::BaseQtVersion *> qtVersions = qtVersionsForArch.value(tc->targetAbi());
foreach (QtSupport::BaseQtVersion *qt, qtVersions) {
Kit *newKit = new Kit;
newKit->setAutoDetected(true);
......
......@@ -126,8 +126,8 @@ public:
Utils::FileName emulatorToolPath() const;
Utils::FileName gccPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const;
Utils::FileName gdbPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const;
Utils::FileName gccPath(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion) const;
Utils::FileName gdbPath(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion) const;
Utils::FileName keytoolPath() const;
......@@ -156,9 +156,10 @@ public:
QString waitForAvd(int apiLevel, const QString &cpuAbi, const QFutureInterface<bool> &fi = QFutureInterface<bool>()) const;
QString bestNdkPlatformMatch(int target) const;
static ProjectExplorer::Abi::Architecture architectureForToolChainPrefix(const QString &toolchainprefix);
static QLatin1String toolchainPrefix(ProjectExplorer::Abi::Architecture architecture);
static QLatin1String toolsPrefix(ProjectExplorer::Abi::Architecture architecture);
static ProjectExplorer::Abi abiForToolChainPrefix(const QString &toolchainPrefix);
static QLatin1String toolchainPrefix(const ProjectExplorer::Abi &abi);
static QLatin1String toolsPrefix(const ProjectExplorer::Abi &abi);
static QLatin1String displayName(const ProjectExplorer::Abi &abi);
QString getProductModel(const QString &device) const;
bool hasFinishedBooting(const QString &device) const;
......@@ -170,7 +171,7 @@ private:
static CreateAvdInfo createAVDImpl(CreateAvdInfo info, Utils::FileName androidToolPath, Utils::Environment env);
static QVector<AndroidDeviceInfo> androidVirtualDevicesImpl(const Utils::FileName &androidTool, const Utils::Environment &environment);
Utils::FileName toolPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const;
Utils::FileName toolPath(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion) const;
Utils::FileName openJDKBinPath() const;
int getSDKVersion(const QString &device) const;
QStringList getAbis(const QString &device) const;
......
......@@ -282,9 +282,9 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
QStringList gdbPaths;
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
// we only check the arm gdbs, that's indicative enough
if (ati.architecture != ProjectExplorer::Abi::ArmArchitecture)
if (ati.abi.architecture() != ProjectExplorer::Abi::ArmArchitecture)
continue;
Utils::FileName gdbPath = m_androidConfig.gdbPath(ati.architecture, ati.version);
Utils::FileName gdbPath = m_androidConfig.gdbPath(ati.abi, ati.version);
if (gdbPath.exists())
gdbPaths << gdbPath.toString();
}
......@@ -295,32 +295,29 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
}
// See if we have qt versions for those toolchains
QSet<ProjectExplorer::Abi::Architecture> toolchainsForArch;
QSet<ProjectExplorer::Abi> toolchainsForAbi;
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths)
toolchainsForArch.insert(ati.architecture);
toolchainsForAbi.insert(ati.abi);
QSet<ProjectExplorer::Abi::Architecture> qtVersionsForArch;
QSet<ProjectExplorer::Abi> qtVersionsForAbi;
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::versions()) {
if (qtVersion->type() != QLatin1String(Constants::ANDROIDQT) || qtVersion->qtAbis().isEmpty())
continue;
qtVersionsForArch.insert(qtVersion->qtAbis().first().architecture());
qtVersionsForAbi.insert(qtVersion->qtAbis().first());
}
QSet<ProjectExplorer::Abi::Architecture> missingQtArchs = toolchainsForArch.subtract(qtVersionsForArch);
QSet<ProjectExplorer::Abi> missingQtArchs = toolchainsForAbi.subtract(qtVersionsForAbi);
if (missingQtArchs.isEmpty()) {
m_ndkMissingQtArchs.clear();
} else {
if (missingQtArchs.count() == 1) {
m_ndkMissingQtArchs = tr("Qt version for architecture %1 is missing.\n"
"To add the Qt version, select Options > Build & Run > Qt Versions.")
.arg(ProjectExplorer::Abi::toString((*missingQtArchs.constBegin())));
.arg((*missingQtArchs.constBegin()).toString());
} else {
QStringList missingArchs;
foreach (ProjectExplorer::Abi::Architecture arch, missingQtArchs)
missingArchs.append(ProjectExplorer::Abi::toString(arch));
m_ndkMissingQtArchs = tr("Qt versions for architectures %1 are missing.\n"
m_ndkMissingQtArchs = tr("Qt versions for %1 architectures are missing.\n"
"To add the Qt versions, select Options > Build & Run > Qt Versions.")
.arg(missingArchs.join(QLatin1String(", ")));
.arg(missingQtArchs.size());
}
}
}
......
......@@ -64,17 +64,16 @@ using namespace Utils;
static const char ANDROID_QT_VERSION_KEY[] = "Qt4ProjectManager.Android.QtVersion";
static const char ANDROID_NDK_TC_VERION[] = "Qt4ProjectManager.Android.NDK_TC_VERION";
QMap<Abi::Architecture, QList<int> > AndroidToolChainFactory::m_newestVersionForArch;
QHash<Abi, QList<int> > AndroidToolChainFactory::m_newestVersionForAbi;
FileName AndroidToolChainFactory::m_ndkLocation;
AndroidToolChain::AndroidToolChain(Abi::Architecture arch, const QString &ndkToolChainVersion, Detection d)
AndroidToolChain::AndroidToolChain(const Abi &abi, const QString &ndkToolChainVersion, Detection d)
: GccToolChain(QLatin1String(Constants::ANDROID_TOOLCHAIN_ID), d),
m_ndkToolChainVersion(ndkToolChainVersion), m_secondaryToolChain(false)
{
Abi abi = Abi(arch, Abi::LinuxOS, Abi::AndroidLinuxFlavor, Abi::ElfFormat, 32);
setTargetAbi(abi);
setDisplayName(QString::fromLatin1("Android GCC (%1-%2)")
.arg(Abi::toString(targetAbi().architecture()))
.arg(AndroidConfig::displayName(targetAbi()))
.arg(ndkToolChainVersion));
}
......@@ -116,8 +115,8 @@ void AndroidToolChain::addToEnvironment(Environment &env) const
// TODO invalidate all .pro files !!!
env.set(QLatin1String("ANDROID_NDK_HOST"), AndroidConfigurations::currentConfig().toolchainHost());
env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_PREFIX"), AndroidConfig::toolchainPrefix(targetAbi().architecture()));
env.set(QLatin1String("ANDROID_NDK_TOOLS_PREFIX"), AndroidConfig::toolsPrefix(targetAbi().architecture()));
env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_PREFIX"), AndroidConfig::toolchainPrefix(targetAbi()));
env.set(QLatin1String("ANDROID_NDK_TOOLS_PREFIX"), AndroidConfig::toolsPrefix(targetAbi()));
env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_VERSION"), m_ndkToolChainVersion);
QString javaHome = AndroidConfigurations::currentConfig().openJDKLocation().toString();
if (!javaHome.isEmpty() && QFileInfo::exists(javaHome))
......@@ -141,7 +140,7 @@ ToolChainConfigWidget *AndroidToolChain::configurationWidget()
FileName AndroidToolChain::suggestedDebugger() const
{
return AndroidConfigurations::currentConfig().gdbPath(targetAbi().architecture(), m_ndkToolChainVersion);
return AndroidConfigurations::currentConfig().gdbPath(targetAbi(), m_ndkToolChainVersion);
}
FileName AndroidToolChain::suggestedGdbServer() const
......@@ -153,7 +152,7 @@ FileName AndroidToolChain::suggestedGdbServer() const
return path;
path = AndroidConfigurations::currentConfig().ndkLocation();
path.appendPath(QString::fromLatin1("toolchains/%1-%2/prebuilt/gdbserver")
.arg(AndroidConfig::toolchainPrefix(targetAbi().architecture()))
.arg(AndroidConfig::toolchainPrefix(targetAbi()))
.arg(m_ndkToolChainVersion));
if (path.exists())
return path;
......@@ -192,16 +191,14 @@ bool AndroidToolChain::fromMap(const QVariantMap &data)
return false;
m_ndkToolChainVersion = command.mid(index + 1);
QString platform = command.left(index);
Abi::Architecture arch = AndroidConfig::architectureForToolChainPrefix(platform);
Abi abi = Abi(arch, Abi::LinuxOS, Abi::AndroidLinuxFlavor, Abi::ElfFormat, 32);
setTargetAbi(abi);
setTargetAbi(AndroidConfig::abiForToolChainPrefix(platform));
} else {
m_ndkToolChainVersion = data.value(QLatin1String(ANDROID_NDK_TC_VERION)).toString();
}
Abi::Architecture arch = targetAbi().architecture();
Abi abi = targetAbi();
m_secondaryToolChain = AndroidToolChainFactory::versionCompareLess(AndroidToolChainFactory::versionNumberFromString(m_ndkToolChainVersion),
AndroidToolChainFactory::newestToolChainVersionForArch(arch));
AndroidToolChainFactory::newestToolChainVersionForArch(abi));
return isValid();
}
......@@ -304,11 +301,11 @@ QList<AndroidToolChainFactory::AndroidToolChainInformation> AndroidToolChainFact
AndroidToolChainInformation ati;
ati.version = fileName.mid(idx + 1);
QString platform = fileName.left(idx);
ati.architecture = AndroidConfig::architectureForToolChainPrefix(platform);
if (ati.architecture == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
ati.abi = AndroidConfig::abiForToolChainPrefix(platform);
if (ati.abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue;
// AndroidToolChain *tc = new AndroidToolChain(arch, version, true);
ati.compilerCommand = AndroidConfigurations::currentConfig().gccPath(ati.architecture, ati.version);
ati.compilerCommand = AndroidConfigurations::currentConfig().gccPath(ati.abi, ati.version);
// tc->setCompilerCommand(compilerPath);
result.append(ati);
}
......@@ -369,7 +366,7 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam
FileName path = ndkPath;
QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(),
QStringList() << QLatin1String("*"), QDir::Dirs);
QMap<Abi::Architecture, AndroidToolChain *> newestToolChainForArch;
QHash<Abi, AndroidToolChain *> newestToolChainForArch;
while (it.hasNext()) {
const QString &fileName = FileName::fromString(it.next()).fileName();
......@@ -378,34 +375,34 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam
continue;
QString version = fileName.mid(idx + 1);
QString platform = fileName.left(idx);
Abi::Architecture arch = AndroidConfig::architectureForToolChainPrefix(platform);
if (arch == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
Abi abi = AndroidConfig::abiForToolChainPrefix(platform);
if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue;
AndroidToolChain *tc = new AndroidToolChain(arch, version, ToolChain::AutoDetection);
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(arch, version);
AndroidToolChain *tc = new AndroidToolChain(abi, version, ToolChain::AutoDetection);
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, version);
tc->resetToolChain(compilerPath);
result.append(tc);
QMap<Abi::Architecture, AndroidToolChain *>::const_iterator it
= newestToolChainForArch.constFind(arch);
QHash<Abi, AndroidToolChain *>::const_iterator it
= newestToolChainForArch.constFind(abi);
if (it == newestToolChainForArch.constEnd())
newestToolChainForArch.insert(arch, tc);
newestToolChainForArch.insert(abi, tc);
else if (versionCompareLess(it.value(), tc))
newestToolChainForArch[arch] = tc;
newestToolChainForArch[abi] = tc;
}
foreach (ToolChain *tc, result) {
AndroidToolChain *atc = static_cast<AndroidToolChain *>(tc);
if (newestToolChainForArch.value(atc->targetAbi().architecture()) != atc)
if (newestToolChainForArch.value(atc->targetAbi()) != atc)
atc->setSecondaryToolChain(true);
}
return result;
}
QList<int> AndroidToolChainFactory::newestToolChainVersionForArch(Abi::Architecture arch)
QList<int> AndroidToolChainFactory::newestToolChainVersionForArch(const Abi &abi)
{
if (m_newestVersionForArch.isEmpty()
if (m_newestVersionForAbi.isEmpty()
|| m_ndkLocation != AndroidConfigurations::currentConfig().ndkLocation()) {
QRegExp versionRegExp(NDKGccVersionRegExp);
m_ndkLocation = AndroidConfigurations::currentConfig().ndkLocation();
......@@ -419,18 +416,18 @@ QList<int> AndroidToolChainFactory::newestToolChainVersionForArch(Abi::Architect
continue;
QList<int> version = versionNumberFromString(fileName.mid(idx + 1));
QString platform = fileName.left(idx);
Abi::Architecture arch = AndroidConfig::architectureForToolChainPrefix(platform);
if (arch == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
Abi abi = AndroidConfig::abiForToolChainPrefix(platform);
if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue;
QMap<Abi::Architecture, QList<int> >::const_iterator it
= m_newestVersionForArch.constFind(arch);
if (it == m_newestVersionForArch.constEnd())
m_newestVersionForArch.insert(arch, version);
QHash<Abi, QList<int> >::const_iterator it
= m_newestVersionForAbi.constFind(abi);
if (it == m_newestVersionForAbi.constEnd())
m_newestVersionForAbi.insert(abi, version);
else if (versionCompareLess(it.value(), version))
m_newestVersionForArch[arch] = version;
m_newestVersionForAbi[abi] = version;
}
}
return m_newestVersionForArch.value(arch);
return m_newestVersionForAbi.value(abi);
}
} // namespace Internal
......
......@@ -69,7 +69,7 @@ protected:
QList<ProjectExplorer::Abi> detectSupportedAbis() const;
private:
explicit AndroidToolChain(ProjectExplorer::Abi::Architecture arch, const QString &ndkToolChainVersion, Detection d);
explicit AndroidToolChain(const ProjectExplorer::Abi &abi, const QString &ndkToolChainVersion, Detection d);
AndroidToolChain();
AndroidToolChain(const AndroidToolChain &);
......@@ -110,7 +110,7 @@ public:
{
public:
Utils::FileName compilerCommand;
ProjectExplorer::Abi::Architecture architecture;
ProjectExplorer::Abi abi;
QString version;
};
......@@ -120,9 +120,9 @@ public:
static QList<int> versionNumberFromString(const QString &version);
static bool versionCompareLess(const QList<int> &a, const QList<int> &b);
static bool versionCompareLess(AndroidToolChain *atc, AndroidToolChain *btc);
static QList<int> newestToolChainVersionForArch(ProjectExplorer::Abi::Architecture arch);
static QList<int> newestToolChainVersionForArch(const ProjectExplorer::Abi &abi);
private:
static QMap<ProjectExplorer::Abi::Architecture, QList<int> > m_newestVersionForArch;
static QHash<ProjectExplorer::Abi, QList<int> > m_newestVersionForAbi;
static Utils::FileName m_ndkLocation;
};
......
......@@ -240,6 +240,9 @@ static QList<Abi> abiOf(const QByteArray &data)
case 40: // EM_ARM
result.append(Abi(Abi::ArmArchitecture, os, flavor, Abi::ElfFormat, 32));
break;
case 183: // EM_AARCH64
result.append(Abi(Abi::ArmArchitecture, os, flavor, Abi::ElfFormat, 64));
break;
case 62: // EM_X86_64
result.append(Abi(Abi::X86Architecture, os, flavor, Abi::ElfFormat, 64));
break;
......
......@@ -34,6 +34,7 @@
#include "projectexplorer_export.h"
#include <QList>
#include <QHash>
namespace Utils { class FileName; }
......@@ -150,6 +151,15 @@ private:
unsigned char m_wordWidth;
};
inline int qHash(const ProjectExplorer::Abi &abi)
{
int h = abi.architecture()
+ (abi.os() << 3)
+ (abi.osFlavor() << 6)
+ (abi.binaryFormat() << 10)
+ (abi.wordWidth() << 13);
return QT_PREPEND_NAMESPACE(qHash)(h);
}
} // namespace ProjectExplorer
#endif // PROJECTEXPLORER_ABI_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment