Skip to content

Commit a07ff6e

Browse files
bartekpaciapull[bot]
authored andcommitted
Improve Android SDK and NDK mistmatch warning message (flutter#147809)
This PR resolves flutter#147806 - List plugin that want to be compiled against a higher Android SDK version - List plugins that depend on a different NDK version (we don't have a way to compare them) - Small formatting and wording improvements - Update syntax to work for both Groovy and Kotlin - If project uses `build.gradle.kts`, then it is mentioned in the warning message (previously always `build.gradle` was mentioned) <img width="1209" alt="demo" src="https://github.com/flutter/flutter/assets/40357511/be3522b5-d1b4-4983-9fed-8aaa0f0bc7f7">
1 parent e3350be commit a07ff6e

File tree

3 files changed

+70
-19
lines changed

3 files changed

+70
-19
lines changed

packages/flutter_tools/gradle/src/main/groovy/flutter.groovy

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ class FlutterPlugin implements Plugin<Project> {
693693
if (pluginProject == null) {
694694
// Plugin was not included in `settings.gradle`, but is listed in `.flutter-plugins`.
695695
project.logger.error("Plugin project :${it.name} listed, but not found. Please fix your settings.gradle/settings.gradle.kts.")
696-
} else if (doesSupportAndroidPlatform(pluginProject.projectDir.parentFile.path as String)) {
696+
} else if (pluginSupportsAndroidPlatform(pluginProject)) {
697697
// Plugin has a functioning `android` folder and is included successfully, although it's not supported.
698698
// It must be configured nonetheless, to not throw an "Unresolved reference" exception.
699699
configurePluginProject(it)
@@ -706,20 +706,31 @@ class FlutterPlugin implements Plugin<Project> {
706706

707707
// TODO(54566): Can remove this function and its call sites once resolved.
708708
/**
709-
* Returns `true` if the given path contains an `android` directory
709+
* Returns `true` if the given project is a plugin project having an `android` directory
710710
* containing a `build.gradle` or `build.gradle.kts` file.
711711
*/
712-
private Boolean doesSupportAndroidPlatform(String path) {
713-
File buildGradle = new File(path, 'android' + File.separator + 'build.gradle')
714-
File buildGradleKts = new File(path, 'android' + File.separator + 'build.gradle.kts')
712+
private Boolean pluginSupportsAndroidPlatform(Project project) {
713+
File buildGradle = new File(project.projectDir.parentFile, "android" + File.separator + "build.gradle")
714+
File buildGradleKts = new File(project.projectDir.parentFile, "android" + File.separator + "build.gradle.kts")
715+
return buildGradle.exists() || buildGradleKts.exists()
716+
}
717+
718+
/**
719+
* Returns the Gradle build script for the build. When both Groovy and
720+
* Kotlin variants exist, then Groovy (build.gradle) is preferred over
721+
* Kotlin (build.gradle.kts). This is the same behavior as Gradle 8.5.
722+
*/
723+
private File buildGradleFile(Project project) {
724+
File buildGradle = new File(project.projectDir.parentFile, "app" + File.separator + "build.gradle")
725+
File buildGradleKts = new File(project.projectDir.parentFile, "app" + File.separator + "build.gradle.kts")
715726
if (buildGradle.exists() && buildGradleKts.exists()) {
716727
project.logger.error(
717728
"Both build.gradle and build.gradle.kts exist, so " +
718729
"build.gradle.kts is ignored. This is likely a mistake."
719730
)
720731
}
721732

722-
return buildGradle.exists() || buildGradleKts.exists()
733+
return buildGradle.exists() ? buildGradle : buildGradleKts
723734
}
724735

725736
/**
@@ -837,6 +848,8 @@ class FlutterPlugin implements Plugin<Project> {
837848
String projectNdkVersion = project.android.ndkVersion ?: ndkVersionIfUnspecified
838849
String maxPluginNdkVersion = projectNdkVersion
839850
int numProcessedPlugins = getPluginList(project).size()
851+
List<Tuple2<String, String>> pluginsWithHigherSdkVersion = []
852+
List<Tuple2<String, String>> pluginsWithDifferentNdkVersion = []
840853

841854
getPluginList(project).each { pluginObject ->
842855
assert(pluginObject.name instanceof String)
@@ -851,17 +864,49 @@ class FlutterPlugin implements Plugin<Project> {
851864
if (getCompileSdkFromProject(pluginProject).isInteger()) {
852865
pluginCompileSdkVersion = getCompileSdkFromProject(pluginProject) as int
853866
}
867+
854868
maxPluginCompileSdkVersion = Math.max(pluginCompileSdkVersion, maxPluginCompileSdkVersion)
869+
if (pluginCompileSdkVersion > projectCompileSdkVersion) {
870+
pluginsWithHigherSdkVersion.add(new Tuple(pluginProject.name, pluginCompileSdkVersion))
871+
}
872+
855873
String pluginNdkVersion = pluginProject.android.ndkVersion ?: ndkVersionIfUnspecified
856874
maxPluginNdkVersion = mostRecentSemanticVersion(pluginNdkVersion, maxPluginNdkVersion)
875+
if (pluginNdkVersion != projectNdkVersion) {
876+
pluginsWithDifferentNdkVersion.add(new Tuple(pluginProject.name, pluginNdkVersion))
877+
}
857878

858879
numProcessedPlugins--
859880
if (numProcessedPlugins == 0) {
860881
if (maxPluginCompileSdkVersion > projectCompileSdkVersion) {
861-
project.logger.error("One or more plugins require a higher Android SDK version.\nFix this issue by adding the following to ${project.projectDir}${File.separator}build.gradle:\nandroid {\n compileSdkVersion ${maxPluginCompileSdkVersion}\n ...\n}\n")
882+
project.logger.error("Your project is configured to compile against Android SDK $projectCompileSdkVersion, but the following plugin(s) require to be compiled against a higher Android SDK version:")
883+
for (Tuple2<String, String> pluginToCompileSdkVersion : pluginsWithHigherSdkVersion) {
884+
project.logger.error("- ${pluginToCompileSdkVersion.first} compiles against Android SDK ${pluginToCompileSdkVersion.second}")
885+
}
886+
project.logger.error("""\
887+
Fix this issue by compiling against the highest Android SDK version (they are backward compatible).
888+
Add the following to ${buildGradleFile(project).path}:
889+
890+
android {
891+
compileSdk = ${maxPluginCompileSdkVersion}
892+
...
893+
}
894+
""".stripIndent())
862895
}
863896
if (maxPluginNdkVersion != projectNdkVersion) {
864-
project.logger.error("One or more plugins require a higher Android NDK version.\nFix this issue by adding the following to ${project.projectDir}${File.separator}build.gradle:\nandroid {\n ndkVersion \"${maxPluginNdkVersion}\"\n ...\n}\n")
897+
project.logger.error("Your project is configured with Android NDK $projectNdkVersion, but the following plugin(s) depend on a different Android NDK version:")
898+
for (Tuple2<String, String> pluginToNdkVersion : pluginsWithDifferentNdkVersion) {
899+
project.logger.error("- ${pluginToNdkVersion.first} requires Android NDK ${pluginToNdkVersion.second}")
900+
}
901+
project.logger.error("""\
902+
Fix this issue by using the highest Android NDK version (they are backward compatible).
903+
Add the following to ${buildGradleFile(project).path}:
904+
905+
android {
906+
ndkVersion = \"${maxPluginNdkVersion}\"
907+
...
908+
}
909+
""".stripIndent())
865910
}
866911
}
867912
}

packages/flutter_tools/test/integration.shard/android_plugin_compilesdkversion_mismatch_test.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,20 @@ void main() {
7575

7676
// Check error message is thrown
7777
expect(
78-
result.stdout,
78+
result.stderr,
7979
contains(
80-
'Warning: The plugin test_plugin requires Android SDK version 31 or higher.'));
80+
'Your project is configured to compile against Android SDK 30, but '
81+
'the following plugin(s) require to be compiled against a higher Android SDK version:'));
8182
expect(
8283
result.stderr,
83-
contains('One or more plugins require a higher Android SDK version.'),
84+
contains('- test_plugin compiles against Android SDK 31'),
8485
);
8586
expect(
8687
result.stderr,
8788
contains(
88-
'Fix this issue by adding the following to ${projectGradleFile.path}'));
89+
'Fix this issue by compiling against the highest Android SDK version (they are backward compatible).'));
90+
expect(
91+
result.stderr,
92+
contains('Add the following to ${projectGradleFile.path}:'));
8993
});
9094
}

packages/flutter_tools/test/integration.shard/android_plugin_ndkversion_mismatch_test.dart

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ void main() {
7474

7575
// Check that an error message is thrown.
7676
expect(result.stderr, contains('''
77-
One or more plugins require a higher Android NDK version.
78-
Fix this issue by adding the following to ${projectGradleFile.path}:
79-
android {
80-
ndkVersion "21.4.7075529"
81-
...
82-
}
83-
77+
Your project is configured with Android NDK 21.1.6352462, but the following plugin(s) depend on a different Android NDK version:
78+
- test_plugin requires Android NDK 21.4.7075529
79+
Fix this issue by using the highest Android NDK version (they are backward compatible).
80+
Add the following to ${projectGradleFile.path}:
81+
82+
android {
83+
ndkVersion = "21.4.7075529"
84+
...
85+
}
8486
'''));
8587
});
8688
}

0 commit comments

Comments
 (0)