Android: Persist ABI selection for multi-arch builds

Change-Id: I67fe60bc5a5bd0c086d36368fec4369e4744dab8
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
hjk
2020-04-17 15:18:27 +02:00
parent 9e84724c53
commit 458ff1e967
2 changed files with 66 additions and 35 deletions

View File

@@ -72,6 +72,7 @@ using namespace Utils;
namespace { namespace {
const char QMAKE_ARGUMENTS_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeArguments"; const char QMAKE_ARGUMENTS_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeArguments";
const char QMAKE_FORCED_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeForced"; const char QMAKE_FORCED_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeForced";
const char QMAKE_SELECTED_ABIS_KEY[] = "QtProjectManager.QMakeBuildStep.SelectedAbis";
} }
QMakeStep::QMakeStep(BuildStepList *bsl, Core::Id id) QMakeStep::QMakeStep(BuildStepList *bsl, Core::Id id)
@@ -353,6 +354,16 @@ void QMakeStep::runNextCommand()
} }
} }
QStringList QMakeStep::selectedAbis() const
{
return m_selectedAbis;
}
void QMakeStep::setSelectedAbis(const QStringList &selectedAbis)
{
m_selectedAbis = selectedAbis;
}
void QMakeStep::setUserArguments(const QString &arguments) void QMakeStep::setUserArguments(const QString &arguments)
{ {
if (m_userArgs == arguments) if (m_userArgs == arguments)
@@ -466,6 +477,7 @@ QVariantMap QMakeStep::toMap() const
QVariantMap map(AbstractProcessStep::toMap()); QVariantMap map(AbstractProcessStep::toMap());
map.insert(QMAKE_ARGUMENTS_KEY, m_userArgs); map.insert(QMAKE_ARGUMENTS_KEY, m_userArgs);
map.insert(QMAKE_FORCED_KEY, m_forced); map.insert(QMAKE_FORCED_KEY, m_forced);
map.insert(QMAKE_SELECTED_ABIS_KEY, m_selectedAbis);
return map; return map;
} }
@@ -473,6 +485,7 @@ bool QMakeStep::fromMap(const QVariantMap &map)
{ {
m_userArgs = map.value(QMAKE_ARGUMENTS_KEY).toString(); m_userArgs = map.value(QMAKE_ARGUMENTS_KEY).toString();
m_forced = map.value(QMAKE_FORCED_KEY, false).toBool(); m_forced = map.value(QMAKE_FORCED_KEY, false).toBool();
m_selectedAbis = map.value(QMAKE_SELECTED_ABIS_KEY).toStringList();
// Backwards compatibility with < Creator 4.12. // Backwards compatibility with < Creator 4.12.
const QVariant separateDebugInfo const QVariant separateDebugInfo
@@ -637,29 +650,26 @@ void QMakeStepConfigWidget::separateDebugInfoChanged()
void QMakeStepConfigWidget::abisChanged() void QMakeStepConfigWidget::abisChanged()
{ {
if (m_abisParam.isEmpty())
return;
QStringList args = m_step->extraArguments();
for (auto it = args.begin(); it != args.end(); ++it) {
if (it->startsWith(m_abisParam)) {
args.erase(it);
break;
}
}
QStringList abis; QStringList abis;
for (int i = 0; i < abisListWidget->count(); ++i) { for (int i = 0; i < abisListWidget->count(); ++i) {
auto item = abisListWidget->item(i); auto item = abisListWidget->item(i);
if (item->checkState() == Qt::CheckState::Checked) if (item->checkState() == Qt::CheckState::Checked)
abis << item->text(); abis << item->text();
} }
if (abis.isEmpty()) { m_step->setSelectedAbis(abis);
abisListWidget->item(m_preferredAbiIndex)->setCheckState(Qt::CheckState::Checked);
return; if (isAndroidKit()) {
const QString prefix = "ANDROID_ABIS=";
QStringList args = m_step->extraArguments();
for (auto it = args.begin(); it != args.end(); ++it) {
if (it->startsWith(prefix)) {
args.erase(it);
break;
} }
args << QStringLiteral("%1\"%2\"").arg(m_abisParam, abis.join(' ')); }
args << prefix + '"' + abis.join(' ') + '"';
m_step->setExtraArguments(args); m_step->setExtraArguments(args);
}
updateSummaryLabel(); updateSummaryLabel();
updateEffectiveQMakeCall(); updateEffectiveQMakeCall();
@@ -705,6 +715,18 @@ void QMakeStepConfigWidget::askForRebuild(const QString &title)
question->show(); question->show();
} }
bool QMakeStepConfigWidget::isAndroidKit() const
{
BaseQtVersion *qtVersion = QtKitAspect::qtVersion(m_step->target()->kit());
if (!qtVersion)
return false;
const Abis abis = qtVersion->qtAbis();
return Utils::anyOf(abis, [](const Abi &abi) {
return abi.osFlavor() == Abi::OSFlavor::AndroidLinuxFlavor;
});
}
void QMakeStepConfigWidget::updateSummaryLabel() void QMakeStepConfigWidget::updateSummaryLabel()
{ {
BaseQtVersion *qtVersion = QtKitAspect::qtVersion(m_step->target()->kit()); BaseQtVersion *qtVersion = QtKitAspect::qtVersion(m_step->target()->kit());
@@ -712,29 +734,35 @@ void QMakeStepConfigWidget::updateSummaryLabel()
setSummaryText(tr("<b>qmake:</b> No Qt version set. Cannot run qmake.")); setSummaryText(tr("<b>qmake:</b> No Qt version set. Cannot run qmake."));
return; return;
} }
bool enableAbisSelect = qtVersion->qtAbis().size() > 1; const Abis abis = qtVersion->qtAbis();
const bool enableAbisSelect = abis.size() > 1;
abisLabel->setVisible(enableAbisSelect); abisLabel->setVisible(enableAbisSelect);
abisListWidget->setVisible(enableAbisSelect); abisListWidget->setVisible(enableAbisSelect);
if (enableAbisSelect && abisListWidget->count() != qtVersion->qtAbis().size()) {
abisListWidget->clear();
bool isAndroid = true;
m_preferredAbiIndex = -1;
for (const auto &abi : qtVersion->qtAbis()) {
auto item = new QListWidgetItem{abi.param(), abisListWidget};
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
item->setCheckState(Qt::Unchecked);
isAndroid = isAndroid && abi.osFlavor() == Abi::OSFlavor::AndroidLinuxFlavor;
if (isAndroid && (item->text() == "armeabi-v7a" ||
(m_preferredAbiIndex == -1 && item->text() == "arm64-v8a"))) {
m_preferredAbiIndex = abisListWidget->count() - 1;
}
}
if (isAndroid)
m_abisParam = "ANDROID_ABIS=";
if (m_preferredAbiIndex == -1) if (enableAbisSelect && abisListWidget->count() != abis.size()) {
m_preferredAbiIndex = 0; abisListWidget->clear();
abisListWidget->item(m_preferredAbiIndex)->setCheckState(Qt::Checked); QStringList selectedAbis = m_step->selectedAbis();
if (selectedAbis.isEmpty() && isAndroidKit()) {
// Prefer ARM for Android, prefer 32bit.
for (const Abi &abi : abis) {
if (abi.param() == "armeabi-v7a")
selectedAbis.append(abi.param());
}
if (selectedAbis.isEmpty()) {
for (const Abi &abi : abis) {
if (abi.param() == "arm64-v8a")
selectedAbis.append(abi.param());
}
}
}
for (const Abi &abi : abis) {
const QString param = abi.param();
auto item = new QListWidgetItem{param, abisListWidget};
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
item->setCheckState(selectedAbis.contains(param) ? Qt::Checked : Qt::Unchecked);
}
abisChanged(); abisChanged();
} }

View File

@@ -155,6 +155,9 @@ public:
QVariantMap toMap() const override; QVariantMap toMap() const override;
QStringList selectedAbis() const;
void setSelectedAbis(const QStringList &selectedAbis);
signals: signals:
void userArgumentsChanged(); void userArgumentsChanged();
void extraArgumentsChanged(); void extraArgumentsChanged();
@@ -188,6 +191,7 @@ private:
bool m_runMakeQmake = false; bool m_runMakeQmake = false;
bool m_scriptTemplate = false; bool m_scriptTemplate = false;
QStringList m_selectedAbis;
}; };
@@ -217,11 +221,10 @@ private:
void updateSummaryLabel(); void updateSummaryLabel();
void updateEffectiveQMakeCall(); void updateEffectiveQMakeCall();
bool isAndroidKit() const;
QMakeStep *m_step = nullptr; QMakeStep *m_step = nullptr;
bool m_ignoreChange = false; bool m_ignoreChange = false;
int m_preferredAbiIndex = -1;
QString m_abisParam;
QLabel *abisLabel = nullptr; QLabel *abisLabel = nullptr;
QComboBox *buildConfigurationComboBox = nullptr; QComboBox *buildConfigurationComboBox = nullptr;