forked from qt-creator/qt-creator
Android: Read NDK and api versions from modules/Core.json
Qt 6.5+ writes the NDK version that was used for building Qt into modules/Core.json. With this change, Qt Creator, now reads this version and (if present) prefers it over the respective NDK version defined by Qt Creator's own sdk_definition.json. The order of preference for an NDK version being required and used for a Qt version is now: 1) NDK that was manually set as "Default" 2) NDK defined by Qt's modules/Core.json 3) NDK version defined for a Qt version by sdk_definition.json 4) Default/fallback NDK version defined by sdk_definition.json Task-number: QTCREATORBUG-28629 Change-Id: I2a0a9b3a1719139dc937d468e1dd3643289510a1 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
@@ -953,6 +953,16 @@ bool AndroidConfig::sdkToolsOk() const
|
|||||||
|
|
||||||
QStringList AndroidConfig::essentialsFromQtVersion(const QtVersion &version) const
|
QStringList AndroidConfig::essentialsFromQtVersion(const QtVersion &version) const
|
||||||
{
|
{
|
||||||
|
if (auto androidQtVersion = dynamic_cast<const AndroidQtVersion *>(&version)) {
|
||||||
|
bool ok;
|
||||||
|
const AndroidQtVersion::BuiltWith bw = androidQtVersion->builtWith(&ok);
|
||||||
|
if (ok) {
|
||||||
|
const QString ndkPackage = ndkPackageMarker() + bw.ndkVersion.toString();
|
||||||
|
return QStringList(ndkPackage)
|
||||||
|
+ packagesWithoutNdks(m_defaultSdkDepends.essentialPackages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVersionNumber qtVersion = version.qtVersion();
|
QVersionNumber qtVersion = version.qtVersion();
|
||||||
for (const SdkForQtVersions &item : m_specificQtVersions)
|
for (const SdkForQtVersions &item : m_specificQtVersions)
|
||||||
if (item.containsVersion(qtVersion))
|
if (item.containsVersion(qtVersion))
|
||||||
@@ -973,6 +983,13 @@ static FilePath ndkSubPath(const SdkForQtVersions &packages)
|
|||||||
|
|
||||||
FilePath AndroidConfig::ndkSubPathFromQtVersion(const QtVersion &version) const
|
FilePath AndroidConfig::ndkSubPathFromQtVersion(const QtVersion &version) const
|
||||||
{
|
{
|
||||||
|
if (auto androidQtVersion = dynamic_cast<const AndroidQtVersion *>(&version)) {
|
||||||
|
bool ok;
|
||||||
|
const AndroidQtVersion::BuiltWith bw = androidQtVersion->builtWith(&ok);
|
||||||
|
if (ok)
|
||||||
|
return FilePath::fromString(NdksSubDir) / bw.ndkVersion.toString();
|
||||||
|
}
|
||||||
|
|
||||||
for (const SdkForQtVersions &item : m_specificQtVersions)
|
for (const SdkForQtVersions &item : m_specificQtVersions)
|
||||||
if (item.containsVersion(version.qtVersion()))
|
if (item.containsVersion(version.qtVersion()))
|
||||||
return ndkSubPath(item);
|
return ndkSubPath(item);
|
||||||
|
@@ -27,6 +27,8 @@ private slots:
|
|||||||
void testAndroidSdkManagerProgressParser();
|
void testAndroidSdkManagerProgressParser();
|
||||||
void testAndroidConfigAvailableNdkPlatforms_data();
|
void testAndroidConfigAvailableNdkPlatforms_data();
|
||||||
void testAndroidConfigAvailableNdkPlatforms();
|
void testAndroidConfigAvailableNdkPlatforms();
|
||||||
|
void testAndroidQtVersionParseBuiltWith_data();
|
||||||
|
void testAndroidQtVersionParseBuiltWith();
|
||||||
#endif // WITH_TESTS
|
#endif // WITH_TESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
|
#include <utils/fileutils.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
@@ -26,8 +27,15 @@
|
|||||||
|
|
||||||
#include <proparser/profileevaluator.h>
|
#include <proparser/profileevaluator.h>
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
# include <QTest>
|
||||||
|
# include "androidplugin.h"
|
||||||
|
#endif // WITH_TESTS
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace Android {
|
namespace Android {
|
||||||
@@ -137,6 +145,22 @@ Utils::FilePath AndroidQtVersion::androidDeploymentSettings(const Target *target
|
|||||||
.arg(displayName));
|
.arg(displayName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidQtVersion::BuiltWith AndroidQtVersion::builtWith(bool *ok) const
|
||||||
|
{
|
||||||
|
const Utils::FilePath coreModuleJson = qmakeFilePath().parentDir().parentDir()
|
||||||
|
// version.prefix() not yet set when this is called
|
||||||
|
/ "modules/Core.json";
|
||||||
|
if (coreModuleJson.exists()) {
|
||||||
|
Utils::FileReader reader;
|
||||||
|
if (reader.fetch(coreModuleJson))
|
||||||
|
return parseBuiltWith(reader.data(), ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
*ok = false;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
static int versionFromPlatformString(const QString &string, bool *ok = nullptr)
|
static int versionFromPlatformString(const QString &string, bool *ok = nullptr)
|
||||||
{
|
{
|
||||||
static const QRegularExpression regex("android-(\\d+)");
|
static const QRegularExpression regex("android-(\\d+)");
|
||||||
@@ -146,6 +170,32 @@ static int versionFromPlatformString(const QString &string, bool *ok = nullptr)
|
|||||||
return match.hasMatch() ? match.captured(1).toInt(ok) : -1;
|
return match.hasMatch() ? match.captured(1).toInt(ok) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidQtVersion::BuiltWith AndroidQtVersion::parseBuiltWith(const QByteArray &modulesCoreJsonData,
|
||||||
|
bool *ok)
|
||||||
|
{
|
||||||
|
bool validPlatformString = false;
|
||||||
|
AndroidQtVersion::BuiltWith result;
|
||||||
|
const QJsonObject jsonObject = QJsonDocument::fromJson(modulesCoreJsonData).object();
|
||||||
|
if (const QJsonValue builtWith = jsonObject.value("built_with"); !builtWith.isUndefined()) {
|
||||||
|
if (const QJsonValue android = builtWith["android"]; !android.isUndefined()) {
|
||||||
|
if (const QJsonValue apiVersion = android["api_version"]; !apiVersion.isUndefined()) {
|
||||||
|
const QString apiVersionString = apiVersion.toString();
|
||||||
|
const int v = versionFromPlatformString(apiVersionString, &validPlatformString);
|
||||||
|
if (validPlatformString)
|
||||||
|
result.apiVersion = v;
|
||||||
|
}
|
||||||
|
if (const QJsonValue ndk = android["ndk"]; !ndk.isUndefined()) {
|
||||||
|
if (const QJsonValue version = ndk["version"]; !version.isUndefined())
|
||||||
|
result.ndkVersion = QVersionNumber::fromString(version.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
*ok = validPlatformString && !result.ndkVersion.isNull();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void AndroidQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const
|
void AndroidQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const
|
||||||
{
|
{
|
||||||
m_androidAbis = evaluator->values("ALL_ANDROID_ABIS");
|
m_androidAbis = evaluator->values("ALL_ANDROID_ABIS");
|
||||||
@@ -187,5 +237,68 @@ AndroidQtVersionFactory::AndroidQtVersionFactory()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
void AndroidPlugin::testAndroidQtVersionParseBuiltWith_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("modulesCoreJson");
|
||||||
|
QTest::addColumn<bool>("hasInfo");
|
||||||
|
QTest::addColumn<QVersionNumber>("ndkVersion");
|
||||||
|
QTest::addColumn<int>("apiVersion");
|
||||||
|
|
||||||
|
QTest::newRow("Android Qt 6.4")
|
||||||
|
<< R"({
|
||||||
|
"module_name": "Core",
|
||||||
|
"version": "6.4.1",
|
||||||
|
"built_with": {
|
||||||
|
"compiler_id": "Clang",
|
||||||
|
"compiler_target": "x86_64-none-linux-android23",
|
||||||
|
"compiler_version": "12.0.8",
|
||||||
|
"cross_compiled": true,
|
||||||
|
"target_system": "Android"
|
||||||
|
}
|
||||||
|
})"
|
||||||
|
<< false
|
||||||
|
<< QVersionNumber()
|
||||||
|
<< -1;
|
||||||
|
|
||||||
|
QTest::newRow("Android Qt 6.5")
|
||||||
|
<< R"({
|
||||||
|
"module_name": "Core",
|
||||||
|
"version": "6.5.0",
|
||||||
|
"built_with": {
|
||||||
|
"android": {
|
||||||
|
"api_version": "android-31",
|
||||||
|
"ndk": {
|
||||||
|
"version": "25.1.8937393"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compiler_id": "Clang",
|
||||||
|
"compiler_target": "i686-none-linux-android23",
|
||||||
|
"compiler_version": "14.0.6",
|
||||||
|
"cross_compiled": true,
|
||||||
|
"target_system": "Android"
|
||||||
|
}
|
||||||
|
})"
|
||||||
|
<< true
|
||||||
|
<< QVersionNumber(25, 1, 8937393)
|
||||||
|
<< 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidPlugin::testAndroidQtVersionParseBuiltWith()
|
||||||
|
{
|
||||||
|
QFETCH(QString, modulesCoreJson);
|
||||||
|
QFETCH(bool, hasInfo);
|
||||||
|
QFETCH(int, apiVersion);
|
||||||
|
QFETCH(QVersionNumber, ndkVersion);
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
const AndroidQtVersion::BuiltWith bw =
|
||||||
|
AndroidQtVersion::parseBuiltWith(modulesCoreJson.toUtf8(), &ok);
|
||||||
|
QCOMPARE(ok, hasInfo);
|
||||||
|
QCOMPARE(bw.apiVersion, apiVersion);
|
||||||
|
QCOMPARE(bw.ndkVersion, ndkVersion);
|
||||||
|
}
|
||||||
|
#endif // WITH_TESTS
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
} // Android
|
} // Android
|
||||||
|
@@ -34,6 +34,13 @@ public:
|
|||||||
|
|
||||||
static Utils::FilePath androidDeploymentSettings(const ProjectExplorer::Target *target);
|
static Utils::FilePath androidDeploymentSettings(const ProjectExplorer::Target *target);
|
||||||
|
|
||||||
|
struct BuiltWith {
|
||||||
|
int apiVersion = -1;
|
||||||
|
QVersionNumber ndkVersion;
|
||||||
|
};
|
||||||
|
static BuiltWith parseBuiltWith(const QByteArray &modulesCoreJsonData, bool *ok = nullptr);
|
||||||
|
BuiltWith builtWith(bool *ok = nullptr) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void parseMkSpec(ProFileEvaluator *) const override;
|
void parseMkSpec(ProFileEvaluator *) const override;
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user