forked from qt-creator/qt-creator
Switch QNX tool chains from hard-coded to detected ABIs
Move the target detection code from the QnxConfiguration class into a separate function that can be used by the QnxConfiguration code and the QnxToolChain code. Move some resetToolChain calls after setSdpPath calls. QNX ABI detection depends on the SDP path. Change-Id: I7417a5a1064a77edfb113d9d0010f1e061b81ca6 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -267,7 +267,6 @@ QVariant QnxConfiguration::createDebugger(const Target &target)
|
||||
QnxToolChain *QnxConfiguration::createToolChain(const Target &target)
|
||||
{
|
||||
QnxToolChain *toolChain = new QnxToolChain(ToolChain::AutoDetection);
|
||||
toolChain->resetToolChain(qccCompilerPath());
|
||||
toolChain->setLanguage(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
||||
toolChain->setTargetAbi(target.m_abi);
|
||||
toolChain->setDisplayName(
|
||||
@@ -277,6 +276,7 @@ QnxToolChain *QnxConfiguration::createToolChain(const Target &target)
|
||||
.arg(displayName())
|
||||
.arg(target.shortDescription()));
|
||||
toolChain->setSdpPath(sdpPath().toString());
|
||||
toolChain->resetToolChain(qccCompilerPath());
|
||||
ToolChainManager::registerToolChain(toolChain);
|
||||
return toolChain;
|
||||
}
|
||||
@@ -414,26 +414,9 @@ const QnxConfiguration::Target *QnxConfiguration::findTargetByDebuggerPath(
|
||||
void QnxConfiguration::updateTargets()
|
||||
{
|
||||
m_targets.clear();
|
||||
|
||||
QDir targetsDir(m_qnxTarget.toString());
|
||||
QStringList targetNames = targetsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
foreach (const QString &targetName, targetNames) {
|
||||
FileName targetPath = FileName(m_qnxTarget).appendPath(targetName);
|
||||
FileName libc = FileName(targetPath).appendPath("lib/libc.so");
|
||||
if (libc.exists()) {
|
||||
QList<Abi> abis = Abi::abisOfBinary(libc);
|
||||
if (abis.count() > 0) {
|
||||
if (abis.count() > 1)
|
||||
qWarning() << libc << "has more than one ABI ... processing all";
|
||||
|
||||
foreach (const Abi &abi, abis)
|
||||
m_targets.append(Target(abi, targetPath));
|
||||
} else {
|
||||
qWarning() << libc << "has no ABIs ... discarded";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<QnxTarget> targets = QnxUtils::findTargets(m_qnxTarget);
|
||||
for (const auto &target : targets)
|
||||
m_targets.append(Target(target.m_abi, target.m_path));
|
||||
}
|
||||
|
||||
void QnxConfiguration::assignDebuggersToTargets()
|
||||
|
@@ -103,7 +103,7 @@ private:
|
||||
class Target
|
||||
{
|
||||
public:
|
||||
Target(const ProjectExplorer::Abi &abi, Utils::FileName &path)
|
||||
Target(const ProjectExplorer::Abi &abi, const Utils::FileName &path)
|
||||
: m_abi(abi), m_path(path)
|
||||
{
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include "qnxutils.h"
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <QFormLayout>
|
||||
@@ -43,15 +43,32 @@ namespace Internal {
|
||||
|
||||
static const char CompilerSdpPath[] = "Qnx.QnxToolChain.NDKPath";
|
||||
|
||||
static const QList<Abi> qccSupportedAbis()
|
||||
static QList<Abi> detectTargetAbis(const FileName &sdpPath)
|
||||
{
|
||||
QList<Abi> abis;
|
||||
abis << Abi(Abi::ArmArchitecture, Abi::LinuxOS, Abi::GenericLinuxFlavor, Abi::ElfFormat, 32);
|
||||
abis << Abi(Abi::ArmArchitecture, Abi::LinuxOS, Abi::GenericLinuxFlavor, Abi::ElfFormat, 64);
|
||||
abis << Abi(Abi::X86Architecture, Abi::LinuxOS, Abi::GenericLinuxFlavor, Abi::ElfFormat, 32);
|
||||
abis << Abi(Abi::X86Architecture, Abi::LinuxOS, Abi::GenericLinuxFlavor, Abi::ElfFormat, 64);
|
||||
QList<Abi> result;
|
||||
FileName qnxTarget;
|
||||
|
||||
return abis;
|
||||
if (!sdpPath.fileName().isEmpty()) {
|
||||
QList<Utils::EnvironmentItem> environment = QnxUtils::qnxEnvironment(sdpPath.toString());
|
||||
foreach (const Utils::EnvironmentItem &item, environment) {
|
||||
if (item.name == QLatin1Literal("QNX_TARGET"))
|
||||
qnxTarget = FileName::fromString(item.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (qnxTarget.isEmpty())
|
||||
return result;
|
||||
|
||||
QList<QnxTarget> targets = QnxUtils::findTargets(qnxTarget);
|
||||
for (const auto &target : targets) {
|
||||
if (!result.contains(target.m_abi))
|
||||
result.append(target.m_abi);
|
||||
}
|
||||
|
||||
Utils::sort(result,
|
||||
[](const Abi &arg1, const Abi &arg2) { return arg1.toString() < arg2.toString(); });
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void setQnxEnvironment(Environment &env, const QList<EnvironmentItem> &qnxEnv)
|
||||
@@ -133,10 +150,9 @@ void QnxToolChain::setSdpPath(const QString &sdpPath)
|
||||
toolChainUpdated();
|
||||
}
|
||||
|
||||
// qcc doesn't support a "-dumpmachine" option to get supported abis
|
||||
GccToolChain::DetectedAbisResult QnxToolChain::detectSupportedAbis() const
|
||||
{
|
||||
return qccSupportedAbis();
|
||||
return detectTargetAbis(FileName::fromString(m_sdpPath));
|
||||
}
|
||||
|
||||
// Qcc is a multi-compiler driver, and most of the gcc options can be accomplished by using the -Wp, and -Wc
|
||||
@@ -227,8 +243,9 @@ QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc)
|
||||
m_sdpPath->setPath(tc->sdpPath());
|
||||
m_sdpPath->setEnabled(!tc->isAutoDetected());
|
||||
|
||||
m_abiWidget->setAbis(qccSupportedAbis(), tc->targetAbi());
|
||||
m_abiWidget->setEnabled(!tc->isAutoDetected());
|
||||
QList<Abi> abiList = detectTargetAbis(m_sdpPath->fileName());
|
||||
m_abiWidget->setAbis(abiList, tc->targetAbi());
|
||||
m_abiWidget->setEnabled(!tc->isAutoDetected() && !abiList.isEmpty());
|
||||
|
||||
m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand);
|
||||
//: SDP refers to 'Software Development Platform'.
|
||||
@@ -236,7 +253,8 @@ QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc)
|
||||
m_mainLayout->addRow(tr("&ABI:"), m_abiWidget);
|
||||
|
||||
connect(m_compilerCommand, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty);
|
||||
connect(m_sdpPath, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty);
|
||||
connect(m_sdpPath, &PathChooser::rawPathChanged,
|
||||
this, &QnxToolChainConfigWidget::handleSdpPathChange);
|
||||
connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty);
|
||||
}
|
||||
|
||||
@@ -248,10 +266,10 @@ void QnxToolChainConfigWidget::applyImpl()
|
||||
QnxToolChain *tc = static_cast<QnxToolChain *>(toolChain());
|
||||
Q_ASSERT(tc);
|
||||
QString displayName = tc->displayName();
|
||||
tc->resetToolChain(m_compilerCommand->fileName());
|
||||
tc->setDisplayName(displayName); // reset display name
|
||||
tc->setSdpPath(m_sdpPath->fileName().toString());
|
||||
tc->setTargetAbi(m_abiWidget->currentAbi());
|
||||
tc->resetToolChain(m_compilerCommand->fileName());
|
||||
}
|
||||
|
||||
void QnxToolChainConfigWidget::discardImpl()
|
||||
@@ -276,5 +294,24 @@ bool QnxToolChainConfigWidget::isDirtyImpl() const
|
||||
|| m_abiWidget->currentAbi() != tc->targetAbi();
|
||||
}
|
||||
|
||||
void QnxToolChainConfigWidget::handleSdpPathChange()
|
||||
{
|
||||
Abi currentAbi = m_abiWidget->currentAbi();
|
||||
bool customAbi = m_abiWidget->isCustomAbi();
|
||||
QList<Abi> abiList = detectTargetAbis(m_sdpPath->fileName());
|
||||
|
||||
m_abiWidget->setEnabled(!abiList.isEmpty());
|
||||
|
||||
// Find a good ABI for the new compiler:
|
||||
Abi newAbi;
|
||||
if (customAbi)
|
||||
newAbi = currentAbi;
|
||||
else if (abiList.contains(currentAbi))
|
||||
newAbi = currentAbi;
|
||||
|
||||
m_abiWidget->setAbis(abiList, newAbi);
|
||||
emit dirty();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qnx
|
||||
|
@@ -99,6 +99,8 @@ private:
|
||||
bool isDirtyImpl() const override;
|
||||
void makeReadOnlyImpl() override { }
|
||||
|
||||
void handleSdpPathChange();
|
||||
|
||||
Utils::PathChooser *m_compilerCommand;
|
||||
Utils::PathChooser *m_sdpPath;
|
||||
ProjectExplorer::AbiWidget *m_abiWidget;
|
||||
|
@@ -26,11 +26,14 @@
|
||||
#include "qnxutils.h"
|
||||
#include "qnxqtversion.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/synchronousprocess.h>
|
||||
#include <utils/temporaryfile.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QDomDocument>
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
@@ -227,3 +230,31 @@ QList<Utils::EnvironmentItem> QnxUtils::qnxEnvironment(const QString &sdpPath)
|
||||
{
|
||||
return qnxEnvironmentFromEnvFile(envFilePath(sdpPath));
|
||||
}
|
||||
|
||||
QList<QnxTarget> QnxUtils::findTargets(const Utils::FileName &basePath)
|
||||
{
|
||||
using namespace Utils;
|
||||
QList<QnxTarget> result;
|
||||
|
||||
QDirIterator iterator(basePath.toString());
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
FileName libc = FileName::fromString(iterator.filePath()).appendPath("lib/libc.so");
|
||||
if (libc.exists()) {
|
||||
auto abis = Abi::abisOfBinary(libc);
|
||||
if (abis.isEmpty()) {
|
||||
qWarning() << libc << "has no ABIs ... discarded";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (abis.count() > 1)
|
||||
qWarning() << libc << "has more than one ABI ... processing all";
|
||||
|
||||
FileName path = FileName::fromString(iterator.filePath());
|
||||
for (auto abi : abis)
|
||||
result.append(QnxTarget(path, abi));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "qnxconstants.h"
|
||||
|
||||
#include <projectexplorer/abi.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/fileutils.h>
|
||||
@@ -53,6 +54,17 @@ public:
|
||||
&& !target.isEmpty() && !version.isEmpty() && !installationXmlFilePath.isEmpty(); }
|
||||
};
|
||||
|
||||
class QnxTarget
|
||||
{
|
||||
public:
|
||||
QnxTarget(const Utils::FileName &path, const ProjectExplorer::Abi &abi) :
|
||||
m_path(path), m_abi(abi)
|
||||
{
|
||||
}
|
||||
Utils::FileName m_path;
|
||||
ProjectExplorer::Abi m_abi;
|
||||
};
|
||||
|
||||
class QnxUtils
|
||||
{
|
||||
public:
|
||||
@@ -64,6 +76,7 @@ public:
|
||||
static QString defaultTargetVersion(const QString &sdpPath);
|
||||
static QList<ConfigInstallInformation> installedConfigs(const QString &configPath = QString());
|
||||
static QList<Utils::EnvironmentItem> qnxEnvironment(const QString &sdpPath);
|
||||
static QList<QnxTarget> findTargets(const Utils::FileName &basePath);
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
Reference in New Issue
Block a user