forked from qt-creator/qt-creator
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:
@@ -372,6 +372,11 @@ static QString preferredAbi(const QStringList &appAbis, const Target *target)
|
|||||||
QString AndroidManager::apkDevicePreferredAbi(const Target *target)
|
QString AndroidManager::apkDevicePreferredAbi(const Target *target)
|
||||||
{
|
{
|
||||||
auto libsPath = dirPath(target).pathAppended("libs");
|
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;
|
QStringList apkAbis;
|
||||||
for (const auto &abi : QDir{libsPath.toString()}.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
|
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())
|
if (!QDir{libsPath.pathAppended(abi).toString()}.entryList(QStringList("*.so"), QDir::Files | QDir::NoDotAndDotDot).isEmpty())
|
||||||
|
@@ -151,6 +151,33 @@ QString QbsProductNode::getBuildKey(const QJsonObject &product)
|
|||||||
+ product.value("multiplex-configuration-id").toString();
|
+ 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
|
QVariant QbsProductNode::data(Id role) const
|
||||||
{
|
{
|
||||||
if (role == Android::Constants::AndroidDeploySettingsFile) {
|
if (role == Android::Constants::AndroidDeploySettingsFile) {
|
||||||
@@ -164,10 +191,16 @@ QVariant QbsProductNode::data(Id role) const
|
|||||||
|
|
||||||
if (role == Android::Constants::AndroidSoLibPath) {
|
if (role == Android::Constants::AndroidSoLibPath) {
|
||||||
QStringList ret{m_productData.value("build-directory").toString()};
|
QStringList ret{m_productData.value("build-directory").toString()};
|
||||||
forAllArtifacts(m_productData, ArtifactType::Generated, [&ret](const QJsonObject &artifact) {
|
if (!isAggregated()) {
|
||||||
|
forAllArtifacts(m_productData, ArtifactType::Generated,
|
||||||
|
[&ret](const QJsonObject &artifact) {
|
||||||
if (artifact.value("file-tags").toArray().contains("dynamiclibrary"))
|
if (artifact.value("file-tags").toArray().contains("dynamiclibrary"))
|
||||||
ret << QFileInfo(artifact.value("file-path").toString()).path();
|
ret << QFileInfo(artifact.value("file-path").toString()).path();
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
for (const auto &a : aggregatedProducts())
|
||||||
|
ret += a->data(Android::Constants::AndroidSoLibPath).toStringList();
|
||||||
|
}
|
||||||
ret.removeDuplicates();
|
ret.removeDuplicates();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -188,6 +221,28 @@ QVariant QbsProductNode::data(Id role) const
|
|||||||
return m_productData.value("module-properties").toObject()
|
return m_productData.value("module-properties").toObject()
|
||||||
.value("Qt.core.enableKeywords").toBool();
|
.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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,6 +65,9 @@ public:
|
|||||||
|
|
||||||
static QString getBuildKey(const QJsonObject &product);
|
static QString getBuildKey(const QJsonObject &product);
|
||||||
|
|
||||||
|
bool isAggregated() const;
|
||||||
|
const QList<const QbsProductNode*> aggregatedProducts() const;
|
||||||
|
|
||||||
const QJsonObject productData() const { return m_productData; }
|
const QJsonObject productData() const { return m_productData; }
|
||||||
QJsonObject mainGroup() const;
|
QJsonObject mainGroup() const;
|
||||||
QVariant data(Utils::Id role) const override;
|
QVariant data(Utils::Id role) const override;
|
||||||
|
@@ -376,6 +376,8 @@ RunEnvironmentResult QbsSession::getRunEnvironment(
|
|||||||
void QbsSession::insertRequestedModuleProperties(QJsonObject &request)
|
void QbsSession::insertRequestedModuleProperties(QJsonObject &request)
|
||||||
{
|
{
|
||||||
request.insert("module-properties", QJsonArray::fromStringList({
|
request.insert("module-properties", QJsonArray::fromStringList({
|
||||||
|
"qbs.architecture",
|
||||||
|
"qbs.architectures",
|
||||||
"cpp.commonCompilerFlags",
|
"cpp.commonCompilerFlags",
|
||||||
"cpp.compilerVersionMajor",
|
"cpp.compilerVersionMajor",
|
||||||
"cpp.compilerVersionMinor",
|
"cpp.compilerVersionMinor",
|
||||||
|
Reference in New Issue
Block a user