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 {
const char QMAKE_ARGUMENTS_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeArguments";
const char QMAKE_FORCED_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeForced";
const char QMAKE_SELECTED_ABIS_KEY[] = "QtProjectManager.QMakeBuildStep.SelectedAbis";
}
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)
{
if (m_userArgs == arguments)
@@ -466,6 +477,7 @@ QVariantMap QMakeStep::toMap() const
QVariantMap map(AbstractProcessStep::toMap());
map.insert(QMAKE_ARGUMENTS_KEY, m_userArgs);
map.insert(QMAKE_FORCED_KEY, m_forced);
map.insert(QMAKE_SELECTED_ABIS_KEY, m_selectedAbis);
return map;
}
@@ -473,6 +485,7 @@ bool QMakeStep::fromMap(const QVariantMap &map)
{
m_userArgs = map.value(QMAKE_ARGUMENTS_KEY).toString();
m_forced = map.value(QMAKE_FORCED_KEY, false).toBool();
m_selectedAbis = map.value(QMAKE_SELECTED_ABIS_KEY).toStringList();
// Backwards compatibility with < Creator 4.12.
const QVariant separateDebugInfo
@@ -637,29 +650,26 @@ void QMakeStepConfigWidget::separateDebugInfoChanged()
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;
for (int i = 0; i < abisListWidget->count(); ++i) {
auto item = abisListWidget->item(i);
if (item->checkState() == Qt::CheckState::Checked)
abis << item->text();
}
if (abis.isEmpty()) {
abisListWidget->item(m_preferredAbiIndex)->setCheckState(Qt::CheckState::Checked);
return;
m_step->setSelectedAbis(abis);
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);
}
updateSummaryLabel();
updateEffectiveQMakeCall();
@@ -705,6 +715,18 @@ void QMakeStepConfigWidget::askForRebuild(const QString &title)
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()
{
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."));
return;
}
bool enableAbisSelect = qtVersion->qtAbis().size() > 1;
const Abis abis = qtVersion->qtAbis();
const bool enableAbisSelect = abis.size() > 1;
abisLabel->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)
m_preferredAbiIndex = 0;
abisListWidget->item(m_preferredAbiIndex)->setCheckState(Qt::Checked);
if (enableAbisSelect && abisListWidget->count() != abis.size()) {
abisListWidget->clear();
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();
}

View File

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