Android: fix debugging with qbs

If the default libs path doesn't exist (which is the case for qbs) then
try to get the abis using the current project node data method using
the Android::Constants::ANDROID_ABIS flag.

Because in multiplex (multi arch) mode dynamic libraries are compiled in
different products, library paths must be gathered from those
sibling products using the "dependencies" json array.

Change-Id: I9409a6a12fd9f304f427ed7868a7060c8f985a0b
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Raphaël Cotty
2020-11-27 19:39:20 +01:00
parent f239fa8676
commit e8e2aa8c7f
4 changed files with 69 additions and 4 deletions

View File

@@ -372,6 +372,11 @@ static QString preferredAbi(const QStringList &appAbis, const Target *target)
QString AndroidManager::apkDevicePreferredAbi(const Target *target)
{
auto libsPath = dirPath(target).pathAppended("libs");
if (!libsPath.exists()) {
if (const ProjectNode *node = currentProjectNode(target))
return preferredAbi(node->data(Android::Constants::ANDROID_ABIS).toStringList(),
target);
}
QStringList apkAbis;
for (const auto &abi : QDir{libsPath.toString()}.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
if (!QDir{libsPath.pathAppended(abi).toString()}.entryList(QStringList("*.so"), QDir::Files | QDir::NoDotAndDotDot).isEmpty())

View File

@@ -151,6 +151,33 @@ QString QbsProductNode::getBuildKey(const QJsonObject &product)
+ product.value("multiplex-configuration-id").toString();
}
bool QbsProductNode::isAggregated() const
{
return m_productData.value("is-multiplexed").toBool()
&& m_productData.value("multiplex-configuration-id").toString().isEmpty();
}
const QList<const QbsProductNode*> QbsProductNode::aggregatedProducts() const
{
if (!isAggregated())
return {};
const ProjectNode *parentNode = managingProject();
QTC_ASSERT(parentNode != nullptr && parentNode != this, return {});
QSet<QString> dependencies;
for (const auto &a : m_productData.value("dependencies").toArray())
dependencies << a.toString();
QList<const QbsProductNode*> qbsProducts;
parentNode->forEachProjectNode([&qbsProducts, dependencies](const ProjectNode *node) {
if (const auto qbsChildNode = dynamic_cast<const QbsProductNode *>(node)) {
if (dependencies.contains(qbsChildNode->fullDisplayName()))
qbsProducts << qbsChildNode;
}
});
return qbsProducts;
}
QVariant QbsProductNode::data(Id role) const
{
if (role == Android::Constants::AndroidDeploySettingsFile) {
@@ -164,10 +191,16 @@ QVariant QbsProductNode::data(Id role) const
if (role == Android::Constants::AndroidSoLibPath) {
QStringList ret{m_productData.value("build-directory").toString()};
forAllArtifacts(m_productData, ArtifactType::Generated, [&ret](const QJsonObject &artifact) {
if (artifact.value("file-tags").toArray().contains("dynamiclibrary"))
ret << QFileInfo(artifact.value("file-path").toString()).path();
});
if (!isAggregated()) {
forAllArtifacts(m_productData, ArtifactType::Generated,
[&ret](const QJsonObject &artifact) {
if (artifact.value("file-tags").toArray().contains("dynamiclibrary"))
ret << QFileInfo(artifact.value("file-path").toString()).path();
});
} else {
for (const auto &a : aggregatedProducts())
ret += a->data(Android::Constants::AndroidSoLibPath).toStringList();
}
ret.removeDuplicates();
return ret;
}
@@ -188,6 +221,28 @@ QVariant QbsProductNode::data(Id role) const
return m_productData.value("module-properties").toObject()
.value("Qt.core.enableKeywords").toBool();
if (role == Android::Constants::ANDROID_ABIS) {
// Try using qbs.architectures
QStringList qbsAbis;
QMap<QString, QString> archToAbi {
{"armv7a", ProjectExplorer::Constants::ANDROID_ABI_ARMEABI_V7A},
{"arm64", ProjectExplorer::Constants::ANDROID_ABI_ARM64_V8A},
{"x86", ProjectExplorer::Constants::ANDROID_ABI_X86},
{"x86_64", ProjectExplorer::Constants::ANDROID_ABI_X86_64}};
for (const auto &a : m_productData.value("module-properties").toObject()
.value(Constants::QBS_ARCHITECTURES).toArray()) {
if (archToAbi.contains(a.toString()))
qbsAbis << archToAbi[a.toString()];
}
if (!qbsAbis.empty())
return qbsAbis;
// Try using qbs.architecture
QString architecture = m_productData.value("module-properties").toObject()
.value(Constants::QBS_ARCHITECTURE).toString();
if (archToAbi.contains(architecture))
qbsAbis << archToAbi[architecture];
return qbsAbis;
}
return {};
}

View File

@@ -65,6 +65,9 @@ public:
static QString getBuildKey(const QJsonObject &product);
bool isAggregated() const;
const QList<const QbsProductNode*> aggregatedProducts() const;
const QJsonObject productData() const { return m_productData; }
QJsonObject mainGroup() const;
QVariant data(Utils::Id role) const override;

View File

@@ -376,6 +376,8 @@ RunEnvironmentResult QbsSession::getRunEnvironment(
void QbsSession::insertRequestedModuleProperties(QJsonObject &request)
{
request.insert("module-properties", QJsonArray::fromStringList({
"qbs.architecture",
"qbs.architectures",
"cpp.commonCompilerFlags",
"cpp.compilerVersionMajor",
"cpp.compilerVersionMinor",