Commit 6a6f3d2a authored by Guillermo A. Amaral's avatar Guillermo A. Amaral

Add support for 64-bit NDKs to Android Plugin.

Currently the Android plugin only checks for the linux-x86 prebuilds in the
64-bit Android NDK (and mingw-and-ndk), this means Qt Creator goes bonkers
because it can't find the toolchain and debugger for the kits it
auto-detects/creates.

A work around is to symlink linux-x86_64 to linux-x86 in every toolchain.

Change-Id: I04522b65ef48b6090a9f6925e8e3420ad1d333ee
Reviewed-by: default avatarPaul Olav Tvete <paul.tvete@digia.com>
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
parent 8139d43c
...@@ -81,6 +81,7 @@ namespace { ...@@ -81,6 +81,7 @@ namespace {
const QLatin1String KeystoreLocationKey("KeystoreLocation"); const QLatin1String KeystoreLocationKey("KeystoreLocation");
const QLatin1String AutomaticKitCreationKey("AutomatiKitCreation"); const QLatin1String AutomaticKitCreationKey("AutomatiKitCreation");
const QLatin1String PartitionSizeKey("PartitionSize"); const QLatin1String PartitionSizeKey("PartitionSize");
const QLatin1String ToolchainHostKey("ToolchainHost");
const QLatin1String ArmToolchainPrefix("arm-linux-androideabi"); const QLatin1String ArmToolchainPrefix("arm-linux-androideabi");
const QLatin1String X86ToolchainPrefix("x86"); const QLatin1String X86ToolchainPrefix("x86");
const QLatin1String MipsToolchainPrefix("mipsel-linux-android"); const QLatin1String MipsToolchainPrefix("mipsel-linux-android");
...@@ -152,6 +153,7 @@ AndroidConfig::AndroidConfig(const QSettings &settings) ...@@ -152,6 +153,7 @@ AndroidConfig::AndroidConfig(const QSettings &settings)
antLocation = FileName::fromString(settings.value(AntLocationKey).toString()); antLocation = FileName::fromString(settings.value(AntLocationKey).toString());
openJDKLocation = FileName::fromString(settings.value(OpenJDKLocationKey).toString()); openJDKLocation = FileName::fromString(settings.value(OpenJDKLocationKey).toString());
keystoreLocation = FileName::fromString(settings.value(KeystoreLocationKey).toString()); keystoreLocation = FileName::fromString(settings.value(KeystoreLocationKey).toString());
toolchainHost = settings.value(ToolchainHostKey).toString();
automaticKitCreation = settings.value(AutomaticKitCreationKey, true).toBool(); automaticKitCreation = settings.value(AutomaticKitCreationKey, true).toBool();
PersistentSettingsReader reader; PersistentSettingsReader reader;
...@@ -163,6 +165,7 @@ AndroidConfig::AndroidConfig(const QSettings &settings) ...@@ -163,6 +165,7 @@ AndroidConfig::AndroidConfig(const QSettings &settings)
antLocation = FileName::fromString(reader.restoreValue(AntLocationKey).toString()); antLocation = FileName::fromString(reader.restoreValue(AntLocationKey).toString());
openJDKLocation = FileName::fromString(reader.restoreValue(OpenJDKLocationKey).toString()); openJDKLocation = FileName::fromString(reader.restoreValue(OpenJDKLocationKey).toString());
keystoreLocation = FileName::fromString(reader.restoreValue(KeystoreLocationKey).toString()); keystoreLocation = FileName::fromString(reader.restoreValue(KeystoreLocationKey).toString());
toolchainHost = reader.restoreValue(ToolchainHostKey).toString();
QVariant v = reader.restoreValue(AutomaticKitCreationKey); QVariant v = reader.restoreValue(AutomaticKitCreationKey);
if (v.isValid()) if (v.isValid())
automaticKitCreation = v.toBool(); automaticKitCreation = v.toBool();
...@@ -190,11 +193,16 @@ void AndroidConfig::save(QSettings &settings) const ...@@ -190,11 +193,16 @@ void AndroidConfig::save(QSettings &settings) const
settings.setValue(KeystoreLocationKey, keystoreLocation.toString()); settings.setValue(KeystoreLocationKey, keystoreLocation.toString());
settings.setValue(PartitionSizeKey, partitionSize); settings.setValue(PartitionSizeKey, partitionSize);
settings.setValue(AutomaticKitCreationKey, automaticKitCreation); settings.setValue(AutomaticKitCreationKey, automaticKitCreation);
settings.setValue(ToolchainHostKey, toolchainHost);
} }
void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs) void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
{ {
m_config = devConfigs; m_config = devConfigs;
if (m_config.toolchainHost.isEmpty())
detectToolchainHost();
save(); save();
updateAvailablePlatforms(); updateAvailablePlatforms();
updateAutomaticKitList(); updateAutomaticKitList();
...@@ -277,7 +285,7 @@ FileName AndroidConfigurations::toolPath(Abi::Architecture architecture, const Q ...@@ -277,7 +285,7 @@ FileName AndroidConfigurations::toolPath(Abi::Architecture architecture, const Q
return path.appendPath(QString::fromLatin1("toolchains/%1-%2/prebuilt/%3/bin/%4") return path.appendPath(QString::fromLatin1("toolchains/%1-%2/prebuilt/%3/bin/%4")
.arg(toolchainPrefix(architecture)) .arg(toolchainPrefix(architecture))
.arg(ndkToolChainVersion) .arg(ndkToolChainVersion)
.arg(ToolchainHost) .arg(m_config.toolchainHost)
.arg(toolsPrefix(architecture))); .arg(toolsPrefix(architecture)));
} }
...@@ -291,6 +299,11 @@ FileName AndroidConfigurations::readelfPath(Abi::Architecture architecture, cons ...@@ -291,6 +299,11 @@ FileName AndroidConfigurations::readelfPath(Abi::Architecture architecture, cons
return toolPath(architecture, ndkToolChainVersion).append(QLatin1String("-readelf" QTC_HOST_EXE_SUFFIX)); return toolPath(architecture, ndkToolChainVersion).append(QLatin1String("-readelf" QTC_HOST_EXE_SUFFIX));
} }
FileName AndroidConfigurations::gccPath(Abi::Architecture architecture, const QString &ndkToolChainVersion) const
{
return toolPath(architecture, ndkToolChainVersion).append(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX));
}
FileName AndroidConfigurations::gdbPath(Abi::Architecture architecture, const QString &ndkToolChainVersion) const FileName AndroidConfigurations::gdbPath(Abi::Architecture architecture, const QString &ndkToolChainVersion) const
{ {
return toolPath(architecture, ndkToolChainVersion).append(QLatin1String("-gdb" QTC_HOST_EXE_SUFFIX)); return toolPath(architecture, ndkToolChainVersion).append(QLatin1String("-gdb" QTC_HOST_EXE_SUFFIX));
...@@ -301,6 +314,30 @@ FileName AndroidConfigurations::openJDKPath() const ...@@ -301,6 +314,30 @@ FileName AndroidConfigurations::openJDKPath() const
return m_config.openJDKLocation; return m_config.openJDKLocation;
} }
void AndroidConfigurations::detectToolchainHost()
{
QStringList hostPatterns;
switch (HostOsInfo::hostOs()) {
case HostOsInfo::HostOsLinux:
hostPatterns << QLatin1String("linux*");
break;
case HostOsInfo::HostOsWindows:
hostPatterns << QLatin1String("windows*");
break;
case HostOsInfo::HostOsMac:
hostPatterns << QLatin1String("darwin*");
break;
default: /* unknown host */ return;
}
FileName path = m_config.ndkLocation;
QDirIterator it(path.appendPath(QLatin1String("prebuilt")).toString(), hostPatterns, QDir::Dirs);
if (it.hasNext()) {
it.next();
m_config.toolchainHost = it.fileName();
}
}
FileName AndroidConfigurations::openJDKBinPath() const FileName AndroidConfigurations::openJDKBinPath() const
{ {
FileName path = m_config.openJDKLocation; FileName path = m_config.openJDKLocation;
......
...@@ -42,21 +42,6 @@ QT_END_NAMESPACE ...@@ -42,21 +42,6 @@ QT_END_NAMESPACE
namespace Android { namespace Android {
namespace Internal { namespace Internal {
#ifdef Q_OS_LINUX
const QLatin1String ToolchainHost("linux-x86");
#else
# ifdef Q_OS_DARWIN
const QLatin1String ToolchainHost("darwin-x86");
# else
# ifdef Q_OS_WIN32
const QLatin1String ToolchainHost("windows");
# else
# warning No Android supported OSs found
const QLatin1String ToolchainHost("linux-x86");
# endif
# endif
#endif
class AndroidConfig class AndroidConfig
{ {
public: public:
...@@ -69,6 +54,7 @@ public: ...@@ -69,6 +54,7 @@ public:
Utils::FileName antLocation; Utils::FileName antLocation;
Utils::FileName openJDKLocation; Utils::FileName openJDKLocation;
Utils::FileName keystoreLocation; Utils::FileName keystoreLocation;
QString toolchainHost;
unsigned partitionSize; unsigned partitionSize;
bool automaticKitCreation; bool automaticKitCreation;
}; };
...@@ -95,6 +81,7 @@ public: ...@@ -95,6 +81,7 @@ public:
Utils::FileName androidToolPath() const; Utils::FileName androidToolPath() const;
Utils::FileName antToolPath() const; Utils::FileName antToolPath() const;
Utils::FileName emulatorToolPath() const; 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 gdbPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const;
Utils::FileName openJDKPath() const; Utils::FileName openJDKPath() const;
Utils::FileName keytoolPath() const; Utils::FileName keytoolPath() const;
...@@ -124,6 +111,7 @@ public slots: ...@@ -124,6 +111,7 @@ public slots:
private: private:
Utils::FileName toolPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const; Utils::FileName toolPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const;
Utils::FileName openJDKBinPath() const; Utils::FileName openJDKBinPath() const;
void detectToolchainHost();
AndroidConfigurations(QObject *parent); AndroidConfigurations(QObject *parent);
void load(); void load();
......
...@@ -103,13 +103,8 @@ QList<ProjectExplorer::Abi> AndroidQtVersion::detectQtAbis() const ...@@ -103,13 +103,8 @@ QList<ProjectExplorer::Abi> AndroidQtVersion::detectQtAbis() const
void AndroidQtVersion::addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const void AndroidQtVersion::addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const
{ {
QString ndk_host = QLatin1String(
Utils::HostOsInfo::isLinuxHost() ? "linux-x86" :
Utils::HostOsInfo::isWindowsHost() ? "windows" :
Utils::HostOsInfo::isMacHost() ? "darwin-x86" : "");
// this env vars are used by qmake mkspecs to generate makefiles (check QTDIR/mkspecs/android-g++/qmake.conf for more info) // this env vars are used by qmake mkspecs to generate makefiles (check QTDIR/mkspecs/android-g++/qmake.conf for more info)
env.set(QLatin1String("ANDROID_NDK_HOST"), ndk_host); env.set(QLatin1String("ANDROID_NDK_HOST"), AndroidConfigurations::instance().config().toolchainHost);
env.set(QLatin1String("ANDROID_NDK_ROOT"), AndroidConfigurations::instance().config().ndkLocation.toUserOutput()); env.set(QLatin1String("ANDROID_NDK_ROOT"), AndroidConfigurations::instance().config().ndkLocation.toUserOutput());
Qt4Project *qt4pro = qobject_cast<Qt4ProjectManager::Qt4Project *>(ProjectExplorerPlugin::instance()->currentProject()); Qt4Project *qt4pro = qobject_cast<Qt4ProjectManager::Qt4Project *>(ProjectExplorerPlugin::instance()->currentProject());
......
...@@ -286,6 +286,7 @@ void AndroidSettingsWidget::sdkLocationEditingFinished() ...@@ -286,6 +286,7 @@ void AndroidSettingsWidget::sdkLocationEditingFinished()
void AndroidSettingsWidget::ndkLocationEditingFinished() void AndroidSettingsWidget::ndkLocationEditingFinished()
{ {
Utils::FileName location = Utils::FileName::fromUserInput(m_ui->NDKLocationLineEdit->text()); Utils::FileName location = Utils::FileName::fromUserInput(m_ui->NDKLocationLineEdit->text());
m_androidConfig.toolchainHost.clear(); // force toolchain host detection
if (!checkNDK(location)) if (!checkNDK(location))
return; return;
saveSettings(true); saveSettings(true);
......
...@@ -111,21 +111,7 @@ void AndroidToolChain::addToEnvironment(Environment &env) const ...@@ -111,21 +111,7 @@ void AndroidToolChain::addToEnvironment(Environment &env) const
// TODO this vars should be configurable in projects -> build tab // TODO this vars should be configurable in projects -> build tab
// TODO invalidate all .pro files !!! // TODO invalidate all .pro files !!!
QString ndkHost; env.set(QLatin1String("ANDROID_NDK_HOST"), AndroidConfigurations::instance().config().toolchainHost);
switch (HostOsInfo::hostOs()) {
case HostOsInfo::HostOsLinux:
ndkHost = QLatin1String("linux-x86");
break;
case HostOsInfo::HostOsWindows:
ndkHost = QLatin1String("windows");
break;
case HostOsInfo::HostOsMac:
ndkHost = QLatin1String("darwin-x86");
break;
default:
break;
}
env.set(QLatin1String("ANDROID_NDK_HOST"), ndkHost);
env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_PREFIX"), AndroidConfigurations::toolchainPrefix(targetAbi().architecture())); env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_PREFIX"), AndroidConfigurations::toolchainPrefix(targetAbi().architecture()));
env.set(QLatin1String("ANDROID_NDK_TOOLS_PREFIX"), AndroidConfigurations::toolsPrefix(targetAbi().architecture())); env.set(QLatin1String("ANDROID_NDK_TOOLS_PREFIX"), AndroidConfigurations::toolsPrefix(targetAbi().architecture()));
env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_VERSION"), m_ndkToolChainVersion); env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_VERSION"), m_ndkToolChainVersion);
...@@ -302,12 +288,7 @@ QList<AndroidToolChainFactory::AndroidToolChainInformation> AndroidToolChainFact ...@@ -302,12 +288,7 @@ QList<AndroidToolChainFactory::AndroidToolChainInformation> AndroidToolChainFact
if (ati.architecture == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported if (ati.architecture == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue; continue;
// AndroidToolChain *tc = new AndroidToolChain(arch, version, true); // AndroidToolChain *tc = new AndroidToolChain(arch, version, true);
ati.compilerCommand = ndkPath; ati.compilerCommand = AndroidConfigurations::instance().gccPath(ati.architecture, ati.version);
ati.compilerCommand.appendPath(QString::fromLatin1("toolchains/%1/prebuilt/%3/bin/%4")
.arg(fileName)
.arg(ToolchainHost)
.arg(AndroidConfigurations::toolsPrefix(ati.architecture)));
ati.compilerCommand.append(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX));
// tc->setCompilerCommand(compilerPath); // tc->setCompilerCommand(compilerPath);
result.append(ati); result.append(ati);
} }
...@@ -334,12 +315,7 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const Utils:: ...@@ -334,12 +315,7 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const Utils::
if (arch == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported if (arch == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue; continue;
AndroidToolChain *tc = new AndroidToolChain(arch, version, true); AndroidToolChain *tc = new AndroidToolChain(arch, version, true);
FileName compilerPath = ndkPath; FileName compilerPath = AndroidConfigurations::instance().gccPath(arch, version);
compilerPath.appendPath(QString::fromLatin1("toolchains/%1/prebuilt/%3/bin/%4")
.arg(fileName)
.arg(ToolchainHost)
.arg(AndroidConfigurations::toolsPrefix(arch)));
compilerPath.append(QLatin1String("-gcc" QTC_HOST_EXE_SUFFIX));
tc->setCompilerCommand(compilerPath); tc->setCompilerCommand(compilerPath);
result.append(tc); result.append(tc);
} }
......
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