···15This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
16`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.
1718-Now the `.gradle` will be built in `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, but `build` doesn't.
19-To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/` as well, we need to set `buildDirectory`.
20-diff --git a/packages/flutter_tools/gradle/settings.gradle b/packages/flutter_tools/gradle/settings.gradle
21-new file mode 100644
22-index 0000000000..b2485c94b4
23--- /dev/null
24+++ b/packages/flutter_tools/gradle/settings.gradle
25@@ -0,0 +1,19 @@
···44+includeBuild(dir)
45--- a/packages/flutter_tools/gradle/build.gradle.kts
46+++ b/packages/flutter_tools/gradle/build.gradle.kts
47-@@ -4,6 +4,8 @@
4849 import org.jetbrains.kotlin.gradle.dsl.JvmTarget
5000051+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
52+
53 plugins {
54 `java-gradle-plugin`
55 groovy
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
···15This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
16`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.
1718+To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, we need to set `buildDirectory`.
19+To move `.gradle` as well, the `--project-cache-dir` argument must be passed to the Gradle wrapper.
20+Changing the `GradleUtils.getExecutable` function signature is a delibarate choice, to ensure that no new unpatched usages slip in.
0021--- /dev/null
22+++ b/packages/flutter_tools/gradle/settings.gradle
23@@ -0,0 +1,19 @@
···42+includeBuild(dir)
43--- a/packages/flutter_tools/gradle/build.gradle.kts
44+++ b/packages/flutter_tools/gradle/build.gradle.kts
45+@@ -4,6 +4,11 @@
4647 import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4849++// While flutter_tools runs Gradle with a --project-cache-dir, this startParameter
50++// is not passed correctly to the Kotlin Gradle plugin for some reason, and so
51++// must be set here as well.
52+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
53+
54 plugins {
55 `java-gradle-plugin`
56 groovy
57+--- a/packages/flutter_tools/lib/src/android/gradle.dart
58++++ b/packages/flutter_tools/lib/src/android/gradle.dart
59+@@ -456,9 +456,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
60+ // from the local.properties file.
61+ updateLocalProperties(project: project, buildInfo: androidBuildInfo.buildInfo);
62+63+- final List<String> options = <String>[];
64+-
65+- final String gradleExecutablePath = _gradleUtils.getExecutable(project);
66++ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
67++ project,
68++ );
69+70+ // All automatically created files should exist.
71+ if (configOnly) {
72+@@ -781,7 +781,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
73+ 'aar_init_script.gradle',
74+ );
75+ final List<String> command = <String>[
76+- _gradleUtils.getExecutable(project),
77++ ..._gradleUtils.getExecutable(project),
78+ '-I=$initScript',
79+ '-Pflutter-root=$flutterRoot',
80+ '-Poutput-dir=${outputDirectory.path}',
81+@@ -896,6 +896,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
82+ final List<String> results = <String>[];
83+84+ try {
85++ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
86++ project,
87++ );
88++
89+ exitCode = await _runGradleTask(
90+ _kBuildVariantTaskName,
91+ preRunTask: () {
92+@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
93+ ),
94+ );
95+ },
96+- options: const <String>['-q'],
97++ options: <String>[...options, '-q'],
98+ project: project,
99+ localGradleErrors: gradleErrors,
100+- gradleExecutablePath: _gradleUtils.getExecutable(project),
101++ gradleExecutablePath: gradleExecutablePath,
102+ outputParser: (String line) {
103+ if (_kBuildVariantRegex.firstMatch(line) case final RegExpMatch match) {
104+ results.add(match.namedGroup(_kBuildVariantRegexGroupName)!);
105+@@ -948,6 +952,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
106+ late Stopwatch sw;
107+ int exitCode = 1;
108+ try {
109++ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
110++ project,
111++ );
112++
113+ exitCode = await _runGradleTask(
114+ taskName,
115+ preRunTask: () {
116+@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
117+ ),
118+ );
119+ },
120+- options: <String>['-q', '-PoutputPath=$outputPath'],
121++ options: <String>[...options, '-q', '-PoutputPath=$outputPath'],
122+ project: project,
123+ localGradleErrors: gradleErrors,
124+- gradleExecutablePath: _gradleUtils.getExecutable(project),
125++ gradleExecutablePath: gradleExecutablePath,
126+ );
127+ } on Error catch (error) {
128+ _logger.printError(error.toString());
129+--- a/packages/flutter_tools/lib/src/android/gradle_errors.dart
130++++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart
131+@@ -240,7 +240,12 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
132+ required bool usesAndroidX,
133+ }) async {
134+ final RunResult tasksRunResult = await globals.processUtils.run(
135+- <String>[globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'],
136++ <String>[
137++ ...globals.gradleUtils!.getExecutable(project),
138++ 'app:tasks',
139++ '--all',
140++ '--console=auto',
141++ ],
142+ throwOnError: true,
143+ workingDirectory: project.android.hostAppGradleRoot.path,
144+ environment: globals.java?.environment,
145+--- a/packages/flutter_tools/lib/src/android/gradle_utils.dart
146++++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart
147+@@ -3,6 +3,7 @@
148+ // found in the LICENSE file.
149+150+ import 'package:meta/meta.dart';
151++import 'package:path/path.dart';
152+ import 'package:process/process.dart';
153+ import 'package:unified_analytics/unified_analytics.dart';
154+155+@@ -154,9 +155,29 @@ class GradleUtils {
156+ final Logger _logger;
157+ final OperatingSystemUtils _operatingSystemUtils;
158+159++ List<String> get _requiredArguments {
160++ final String cacheDir = join(
161++ switch (globals.platform.environment['XDG_CACHE_HOME']) {
162++ final String cacheHome => cacheHome,
163++ _ => join(
164++ globals.fsUtils.homeDirPath ?? throwToolExit('No cache directory has been specified.'),
165++ '.cache',
166++ ),
167++ },
168++ 'flutter',
169++ 'nix-flutter-tools-gradle',
170++ globals.flutterVersion.engineRevision.substring(0, 10),
171++ );
172++
173++ return <String>[
174++ '--project-cache-dir=${join(cacheDir, 'cache')}',
175++ '-Pkotlin.project.persistent.dir=${join(cacheDir, 'kotlin')}',
176++ ];
177++ }
178++
179+ /// Gets the Gradle executable path and prepares the Gradle project.
180+ /// This is the `gradlew` or `gradlew.bat` script in the `android/` directory.
181+- String getExecutable(FlutterProject project) {
182++ List<String> getExecutable(FlutterProject project) {
183+ final Directory androidDir = project.android.hostAppGradleRoot;
184+ injectGradleWrapperIfNeeded(androidDir);
185+186+@@ -167,7 +188,7 @@ class GradleUtils {
187+ // If the Gradle executable doesn't have execute permission,
188+ // then attempt to set it.
189+ _operatingSystemUtils.makeExecutable(gradle);
190+- return gradle.absolute.path;
191++ return <String>[gradle.absolute.path, ..._requiredArguments];
192+ }
193+ throwToolExit(
194+ 'Unable to locate gradlew script. Please check that ${gradle.path} '
195+--- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
196++++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
197+@@ -2740,8 +2740,8 @@ Gradle Crashed
198+199+ class FakeGradleUtils extends Fake implements GradleUtils {
200+ @override
201+- String getExecutable(FlutterProject project) {
202+- return 'gradlew';
203++ List<String> getExecutable(FlutterProject project) {
204++ return const <String>['gradlew'];
205+ }
206+ }
207+208+--- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
209++++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
210+@@ -1580,8 +1580,8 @@ Platform fakePlatform(String name) {
211+212+ class FakeGradleUtils extends Fake implements GradleUtils {
213+ @override
214+- String getExecutable(FlutterProject project) {
215+- return 'gradlew';
216++ List<String> getExecutable(FlutterProject project) {
217++ return const <String>['gradlew'];
218+ }
219+ }
220+
···15This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
16`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.
1718-Now the `.gradle` will be built in `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, but `build` doesn't.
19-To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/` as well, we need to set `buildDirectory`.
20-diff --git a/packages/flutter_tools/gradle/settings.gradle b/packages/flutter_tools/gradle/settings.gradle
21-new file mode 100644
22-index 0000000000..b2485c94b4
23--- /dev/null
24+++ b/packages/flutter_tools/gradle/settings.gradle
25@@ -0,0 +1,19 @@
···44+includeBuild(dir)
45--- a/packages/flutter_tools/gradle/build.gradle.kts
46+++ b/packages/flutter_tools/gradle/build.gradle.kts
47-@@ -4,6 +4,8 @@
4849 import org.jetbrains.kotlin.gradle.dsl.JvmTarget
5000051+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
52+
53 plugins {
54 `java-gradle-plugin`
55 groovy
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
···15This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
16`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.
1718+To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, we need to set `buildDirectory`.
19+To move `.gradle` as well, the `--project-cache-dir` argument must be passed to the Gradle wrapper.
20+Changing the `GradleUtils.getExecutable` function signature is a delibarate choice, to ensure that no new unpatched usages slip in.
0021--- /dev/null
22+++ b/packages/flutter_tools/gradle/settings.gradle
23@@ -0,0 +1,19 @@
···42+includeBuild(dir)
43--- a/packages/flutter_tools/gradle/build.gradle.kts
44+++ b/packages/flutter_tools/gradle/build.gradle.kts
45+@@ -4,6 +4,11 @@
4647 import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4849++// While flutter_tools runs Gradle with a --project-cache-dir, this startParameter
50++// is not passed correctly to the Kotlin Gradle plugin for some reason, and so
51++// must be set here as well.
52+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
53+
54 plugins {
55 `java-gradle-plugin`
56 groovy
57+--- a/packages/flutter_tools/lib/src/android/gradle.dart
58++++ b/packages/flutter_tools/lib/src/android/gradle.dart
59+@@ -456,9 +456,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
60+ // from the local.properties file.
61+ updateLocalProperties(project: project, buildInfo: androidBuildInfo.buildInfo);
62+63+- final List<String> options = <String>[];
64+-
65+- final String gradleExecutablePath = _gradleUtils.getExecutable(project);
66++ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
67++ project,
68++ );
69+70+ // All automatically created files should exist.
71+ if (configOnly) {
72+@@ -781,7 +781,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
73+ 'aar_init_script.gradle',
74+ );
75+ final List<String> command = <String>[
76+- _gradleUtils.getExecutable(project),
77++ ..._gradleUtils.getExecutable(project),
78+ '-I=$initScript',
79+ '-Pflutter-root=$flutterRoot',
80+ '-Poutput-dir=${outputDirectory.path}',
81+@@ -896,6 +896,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
82+ final List<String> results = <String>[];
83+84+ try {
85++ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
86++ project,
87++ );
88++
89+ exitCode = await _runGradleTask(
90+ _kBuildVariantTaskName,
91+ preRunTask: () {
92+@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
93+ ),
94+ );
95+ },
96+- options: const <String>['-q'],
97++ options: <String>[...options, '-q'],
98+ project: project,
99+ localGradleErrors: gradleErrors,
100+- gradleExecutablePath: _gradleUtils.getExecutable(project),
101++ gradleExecutablePath: gradleExecutablePath,
102+ outputParser: (String line) {
103+ if (_kBuildVariantRegex.firstMatch(line) case final RegExpMatch match) {
104+ results.add(match.namedGroup(_kBuildVariantRegexGroupName)!);
105+@@ -948,6 +952,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
106+ late Stopwatch sw;
107+ int exitCode = 1;
108+ try {
109++ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
110++ project,
111++ );
112++
113+ exitCode = await _runGradleTask(
114+ taskName,
115+ preRunTask: () {
116+@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
117+ ),
118+ );
119+ },
120+- options: <String>['-q', '-PoutputPath=$outputPath'],
121++ options: <String>[...options, '-q', '-PoutputPath=$outputPath'],
122+ project: project,
123+ localGradleErrors: gradleErrors,
124+- gradleExecutablePath: _gradleUtils.getExecutable(project),
125++ gradleExecutablePath: gradleExecutablePath,
126+ );
127+ } on Error catch (error) {
128+ _logger.printError(error.toString());
129+--- a/packages/flutter_tools/lib/src/android/gradle_errors.dart
130++++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart
131+@@ -240,7 +240,12 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
132+ required bool usesAndroidX,
133+ }) async {
134+ final RunResult tasksRunResult = await globals.processUtils.run(
135+- <String>[globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'],
136++ <String>[
137++ ...globals.gradleUtils!.getExecutable(project),
138++ 'app:tasks',
139++ '--all',
140++ '--console=auto',
141++ ],
142+ throwOnError: true,
143+ workingDirectory: project.android.hostAppGradleRoot.path,
144+ environment: globals.java?.environment,
145+--- a/packages/flutter_tools/lib/src/android/gradle_utils.dart
146++++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart
147+@@ -3,6 +3,7 @@
148+ // found in the LICENSE file.
149+150+ import 'package:meta/meta.dart';
151++import 'package:path/path.dart';
152+ import 'package:process/process.dart';
153+ import 'package:unified_analytics/unified_analytics.dart';
154+155+@@ -154,9 +155,29 @@ class GradleUtils {
156+ final Logger _logger;
157+ final OperatingSystemUtils _operatingSystemUtils;
158+159++ List<String> get _requiredArguments {
160++ final String cacheDir = join(
161++ switch (globals.platform.environment['XDG_CACHE_HOME']) {
162++ final String cacheHome => cacheHome,
163++ _ => join(
164++ globals.fsUtils.homeDirPath ?? throwToolExit('No cache directory has been specified.'),
165++ '.cache',
166++ ),
167++ },
168++ 'flutter',
169++ 'nix-flutter-tools-gradle',
170++ globals.flutterVersion.engineRevision.substring(0, 10),
171++ );
172++
173++ return <String>[
174++ '--project-cache-dir=${join(cacheDir, 'cache')}',
175++ '-Pkotlin.project.persistent.dir=${join(cacheDir, 'kotlin')}',
176++ ];
177++ }
178++
179+ /// Gets the Gradle executable path and prepares the Gradle project.
180+ /// This is the `gradlew` or `gradlew.bat` script in the `android/` directory.
181+- String getExecutable(FlutterProject project) {
182++ List<String> getExecutable(FlutterProject project) {
183+ final Directory androidDir = project.android.hostAppGradleRoot;
184+ injectGradleWrapperIfNeeded(androidDir);
185+186+@@ -167,7 +188,7 @@ class GradleUtils {
187+ // If the Gradle executable doesn't have execute permission,
188+ // then attempt to set it.
189+ _operatingSystemUtils.makeExecutable(gradle);
190+- return gradle.absolute.path;
191++ return <String>[gradle.absolute.path, ..._requiredArguments];
192+ }
193+ throwToolExit(
194+ 'Unable to locate gradlew script. Please check that ${gradle.path} '
195+--- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
196++++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
197+@@ -2740,8 +2740,8 @@ Gradle Crashed
198+199+ class FakeGradleUtils extends Fake implements GradleUtils {
200+ @override
201+- String getExecutable(FlutterProject project) {
202+- return 'gradlew';
203++ List<String> getExecutable(FlutterProject project) {
204++ return const <String>['gradlew'];
205+ }
206+ }
207+208+--- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
209++++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
210+@@ -1580,8 +1580,8 @@ Platform fakePlatform(String name) {
211+212+ class FakeGradleUtils extends Fake implements GradleUtils {
213+ @override
214+- String getExecutable(FlutterProject project) {
215+- return 'gradlew';
216++ List<String> getExecutable(FlutterProject project) {
217++ return const <String>['gradlew'];
218+ }
219+ }
220+