Android: allow using string based versions in compileSdkVersion

Some platform sdk packages have names that contains non-integer
characters such as android-33-ext5 or android-UpsideDownCake
which fail building with androiddeployqt because build.gradle
expects an integer only. This allows using string based versions
and also fallbacks to setting an integer only value if it finds
that the build.gradle of the project is still explicitly
converting to integer (this to avoid breaking existing projects).

Fixes: QTBUG-112465
Pick-to: 6.5 6.2 5.15
Change-Id: If8cfc0fb84f0880a43644dc0a4188671736d3e21
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
This commit is contained in:
Assam Boudjelthia 2023-04-04 12:36:24 +01:00
parent 4521dfe75a
commit a43f349f9c
2 changed files with 43 additions and 9 deletions

View File

@ -35,7 +35,7 @@ android {
* Changing them manually might break the compilation! * Changing them manually might break the compilation!
*******************************************************/ *******************************************************/
compileSdkVersion androidCompileSdkVersion.toInteger() compileSdkVersion androidCompileSdkVersion
buildToolsVersion androidBuildToolsVersion buildToolsVersion androidBuildToolsVersion
ndkVersion androidNdkVersion ndkVersion androidNdkVersion

View File

@ -2693,22 +2693,36 @@ void checkAndWarnGradleLongPaths(const QString &outputDirectory)
} }
#endif #endif
bool gradleSetsLegacyPackagingProperty(const QString &path) struct GradleFlags {
bool setsLegacyPackaging = false;
bool usesIntegerCompileSdkVersion = false;
};
GradleFlags gradleBuildFlags(const QString &path)
{ {
GradleFlags flags;
QFile file(path); QFile file(path);
if (!file.open(QIODevice::ReadOnly)) if (!file.open(QIODevice::ReadOnly))
return false; return flags;
auto isComment = [](const QByteArray &line) {
const auto trimmed = line.trimmed();
return trimmed.startsWith("//") || trimmed.startsWith('*') || trimmed.startsWith("/*");
};
const auto lines = file.readAll().split('\n'); const auto lines = file.readAll().split('\n');
for (const auto &line : lines) { for (const auto &line : lines) {
if (isComment(line))
continue;
if (line.contains("useLegacyPackaging")) { if (line.contains("useLegacyPackaging")) {
const auto trimmed = line.trimmed(); flags.setsLegacyPackaging = true;
if (!trimmed.startsWith("//") && !trimmed.startsWith('*') && !trimmed.startsWith("/*")) } else if (line.contains("compileSdkVersion androidCompileSdkVersion.toInteger()")) {
return true; flags.usesIntegerCompileSdkVersion = true;
} }
} }
return false; return flags;
} }
bool buildAndroidProject(const Options &options) bool buildAndroidProject(const Options &options)
@ -2723,7 +2737,8 @@ bool buildAndroidProject(const Options &options)
GradleProperties gradleProperties = readGradleProperties(gradlePropertiesPath); GradleProperties gradleProperties = readGradleProperties(gradlePropertiesPath);
const QString gradleBuildFilePath = options.outputDirectory + "build.gradle"_L1; const QString gradleBuildFilePath = options.outputDirectory + "build.gradle"_L1;
if (!gradleSetsLegacyPackagingProperty(gradleBuildFilePath)) GradleFlags gradleFlags = gradleBuildFlags(gradleBuildFilePath);
if (!gradleFlags.setsLegacyPackaging)
gradleProperties["android.bundle.enableUncompressedNativeLibs"] = "false"; gradleProperties["android.bundle.enableUncompressedNativeLibs"] = "false";
gradleProperties["buildDir"] = "build"; gradleProperties["buildDir"] = "build";
@ -2738,7 +2753,26 @@ bool buildAndroidProject(const Options &options)
(options.qtInstallDirectory + u'/' + options.qtDataDirectory + (options.qtInstallDirectory + u'/' + options.qtDataDirectory +
"/src/android/java"_L1) "/src/android/java"_L1)
.toUtf8(); .toUtf8();
gradleProperties["androidCompileSdkVersion"] = options.androidPlatform.split(u'-').last().toLocal8Bit();
QByteArray sdkPlatformVersion;
// Provide the integer version only if build.gradle explicitly converts to Integer,
// to avoid regression to existing projects that build for sdk platform of form android-xx.
if (gradleFlags.usesIntegerCompileSdkVersion) {
const QByteArray tmp = options.androidPlatform.split(u'-').last().toLocal8Bit();
bool ok;
tmp.toInt(&ok);
if (ok) {
sdkPlatformVersion = tmp;
} else {
fprintf(stderr, "Warning: Gradle expects SDK platform version to be an integer, "
"but the set version is not convertible to an integer.");
}
}
if (sdkPlatformVersion.isEmpty())
sdkPlatformVersion = options.androidPlatform.toLocal8Bit();
gradleProperties["androidCompileSdkVersion"] = sdkPlatformVersion;
gradleProperties["qtMinSdkVersion"] = options.minSdkVersion; gradleProperties["qtMinSdkVersion"] = options.minSdkVersion;
gradleProperties["qtTargetSdkVersion"] = options.targetSdkVersion; gradleProperties["qtTargetSdkVersion"] = options.targetSdkVersion;
gradleProperties["androidNdkVersion"] = options.ndkVersion.toUtf8(); gradleProperties["androidNdkVersion"] = options.ndkVersion.toUtf8();