flutter{329,332}: Pass --project-cache-dir to Gradle

Changed files
+316 -12
pkgs
development
compilers
flutter
+158 -6
pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch
···
This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.
-
Now the `.gradle` will be built in `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, but `build` doesn't.
-
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/` as well, we need to set `buildDirectory`.
-
diff --git a/packages/flutter_tools/gradle/settings.gradle b/packages/flutter_tools/gradle/settings.gradle
-
new file mode 100644
-
index 0000000000..b2485c94b4
+
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, we need to set `buildDirectory`.
+
To move `.gradle` as well, the `--project-cache-dir` argument must be passed to the Gradle wrapper.
+
Changing the `GradleUtils.getExecutable` function signature is a delibarate choice, to ensure that no new unpatched usages slip in.
--- /dev/null
+++ b/packages/flutter_tools/gradle/settings.gradle
@@ -0,0 +1,19 @@
···
+includeBuild(dir)
--- a/packages/flutter_tools/gradle/build.gradle.kts
+++ b/packages/flutter_tools/gradle/build.gradle.kts
-
@@ -4,6 +4,8 @@
+
@@ -4,6 +4,11 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
+// While flutter_tools runs Gradle with a --project-cache-dir, this startParameter
+
+// is not passed correctly to the Kotlin Gradle plugin for some reason, and so
+
+// must be set here as well.
+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
+
plugins {
`java-gradle-plugin`
groovy
+
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
+
@@ -456,9 +456,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
// from the local.properties file.
+
updateLocalProperties(project: project, buildInfo: androidBuildInfo.buildInfo);
+
+
- final List<String> options = <String>[];
+
-
+
- final String gradleExecutablePath = _gradleUtils.getExecutable(project);
+
+ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+
+ project,
+
+ );
+
+
// All automatically created files should exist.
+
if (configOnly) {
+
@@ -781,7 +781,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
'aar_init_script.gradle',
+
);
+
final List<String> command = <String>[
+
- _gradleUtils.getExecutable(project),
+
+ ..._gradleUtils.getExecutable(project),
+
'-I=$initScript',
+
'-Pflutter-root=$flutterRoot',
+
'-Poutput-dir=${outputDirectory.path}',
+
@@ -896,6 +896,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
final List<String> results = <String>[];
+
+
try {
+
+ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+
+ project,
+
+ );
+
+
+
exitCode = await _runGradleTask(
+
_kBuildVariantTaskName,
+
preRunTask: () {
+
@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
),
+
);
+
},
+
- options: const <String>['-q'],
+
+ options: <String>[...options, '-q'],
+
project: project,
+
localGradleErrors: gradleErrors,
+
- gradleExecutablePath: _gradleUtils.getExecutable(project),
+
+ gradleExecutablePath: gradleExecutablePath,
+
outputParser: (String line) {
+
if (_kBuildVariantRegex.firstMatch(line) case final RegExpMatch match) {
+
results.add(match.namedGroup(_kBuildVariantRegexGroupName)!);
+
@@ -948,6 +952,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
late Stopwatch sw;
+
int exitCode = 1;
+
try {
+
+ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+
+ project,
+
+ );
+
+
+
exitCode = await _runGradleTask(
+
taskName,
+
preRunTask: () {
+
@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
),
+
);
+
},
+
- options: <String>['-q', '-PoutputPath=$outputPath'],
+
+ options: <String>[...options, '-q', '-PoutputPath=$outputPath'],
+
project: project,
+
localGradleErrors: gradleErrors,
+
- gradleExecutablePath: _gradleUtils.getExecutable(project),
+
+ gradleExecutablePath: gradleExecutablePath,
+
);
+
} on Error catch (error) {
+
_logger.printError(error.toString());
+
--- a/packages/flutter_tools/lib/src/android/gradle_errors.dart
+
+++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart
+
@@ -240,7 +240,12 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
+
required bool usesAndroidX,
+
}) async {
+
final RunResult tasksRunResult = await globals.processUtils.run(
+
- <String>[globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'],
+
+ <String>[
+
+ ...globals.gradleUtils!.getExecutable(project),
+
+ 'app:tasks',
+
+ '--all',
+
+ '--console=auto',
+
+ ],
+
throwOnError: true,
+
workingDirectory: project.android.hostAppGradleRoot.path,
+
environment: globals.java?.environment,
+
--- a/packages/flutter_tools/lib/src/android/gradle_utils.dart
+
+++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart
+
@@ -3,6 +3,7 @@
+
// found in the LICENSE file.
+
+
import 'package:meta/meta.dart';
+
+import 'package:path/path.dart';
+
import 'package:process/process.dart';
+
import 'package:unified_analytics/unified_analytics.dart';
+
+
@@ -154,9 +155,16 @@ class GradleUtils {
+
final Logger _logger;
+
final OperatingSystemUtils _operatingSystemUtils;
+
+
+ List<String> get _requiredArguments => <String>[
+
+ '--project-cache-dir=${join(switch (globals.platform.environment['XDG_CACHE_HOME']) {
+
+ final String cacheHome => cacheHome,
+
+ _ => join(globals.fsUtils.homeDirPath ?? throwToolExit('No cache directory has been specified.'), '.cache'),
+
+ }, 'flutter', 'nix-flutter-tools-gradle', globals.flutterVersion.engineRevision.substring(0, 10), 'cache')}',
+
+ ];
+
+
+
/// Gets the Gradle executable path and prepares the Gradle project.
+
/// This is the `gradlew` or `gradlew.bat` script in the `android/` directory.
+
- String getExecutable(FlutterProject project) {
+
+ List<String> getExecutable(FlutterProject project) {
+
final Directory androidDir = project.android.hostAppGradleRoot;
+
injectGradleWrapperIfNeeded(androidDir);
+
+
@@ -167,7 +175,7 @@ class GradleUtils {
+
// If the Gradle executable doesn't have execute permission,
+
// then attempt to set it.
+
_operatingSystemUtils.makeExecutable(gradle);
+
- return gradle.absolute.path;
+
+ return <String>[gradle.absolute.path, ..._requiredArguments];
+
}
+
throwToolExit(
+
'Unable to locate gradlew script. Please check that ${gradle.path} '
+
--- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
+
+++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
+
@@ -2740,8 +2740,8 @@ Gradle Crashed
+
+
class FakeGradleUtils extends Fake implements GradleUtils {
+
@override
+
- String getExecutable(FlutterProject project) {
+
- return 'gradlew';
+
+ List<String> getExecutable(FlutterProject project) {
+
+ return const <String>['gradlew'];
+
}
+
}
+
+
--- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
+
+++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
+
@@ -1580,8 +1580,8 @@ Platform fakePlatform(String name) {
+
+
class FakeGradleUtils extends Fake implements GradleUtils {
+
@override
+
- String getExecutable(FlutterProject project) {
+
- return 'gradlew';
+
+ List<String> getExecutable(FlutterProject project) {
+
+ return const <String>['gradlew'];
+
}
+
}
+
+158 -6
pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch
···
This Gradle project will build the actual `packages/flutter_tools/gradle` project by setting
`rootProject.projectDir = new File("$settingsDir")` and `apply from: new File("$settingsDir/settings.gradle.kts")`.
-
Now the `.gradle` will be built in `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, but `build` doesn't.
-
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/` as well, we need to set `buildDirectory`.
-
diff --git a/packages/flutter_tools/gradle/settings.gradle b/packages/flutter_tools/gradle/settings.gradle
-
new file mode 100644
-
index 0000000000..b2485c94b4
+
To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle/<short engine rev>/`, we need to set `buildDirectory`.
+
To move `.gradle` as well, the `--project-cache-dir` argument must be passed to the Gradle wrapper.
+
Changing the `GradleUtils.getExecutable` function signature is a delibarate choice, to ensure that no new unpatched usages slip in.
--- /dev/null
+++ b/packages/flutter_tools/gradle/settings.gradle
@@ -0,0 +1,19 @@
···
+includeBuild(dir)
--- a/packages/flutter_tools/gradle/build.gradle.kts
+++ b/packages/flutter_tools/gradle/build.gradle.kts
-
@@ -4,6 +4,8 @@
+
@@ -4,6 +4,11 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
+// While flutter_tools runs Gradle with a --project-cache-dir, this startParameter
+
+// is not passed correctly to the Kotlin Gradle plugin for some reason, and so
+
+// must be set here as well.
+gradle.startParameter.projectCacheDir = layout.buildDirectory.dir("cache").get().asFile
+
plugins {
`java-gradle-plugin`
groovy
+
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
+
@@ -456,9 +456,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
// from the local.properties file.
+
updateLocalProperties(project: project, buildInfo: androidBuildInfo.buildInfo);
+
+
- final List<String> options = <String>[];
+
-
+
- final String gradleExecutablePath = _gradleUtils.getExecutable(project);
+
+ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+
+ project,
+
+ );
+
+
// All automatically created files should exist.
+
if (configOnly) {
+
@@ -781,7 +781,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
'aar_init_script.gradle',
+
);
+
final List<String> command = <String>[
+
- _gradleUtils.getExecutable(project),
+
+ ..._gradleUtils.getExecutable(project),
+
'-I=$initScript',
+
'-Pflutter-root=$flutterRoot',
+
'-Poutput-dir=${outputDirectory.path}',
+
@@ -896,6 +896,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
final List<String> results = <String>[];
+
+
try {
+
+ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+
+ project,
+
+ );
+
+
+
exitCode = await _runGradleTask(
+
_kBuildVariantTaskName,
+
preRunTask: () {
+
@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
),
+
);
+
},
+
- options: const <String>['-q'],
+
+ options: <String>[...options, '-q'],
+
project: project,
+
localGradleErrors: gradleErrors,
+
- gradleExecutablePath: _gradleUtils.getExecutable(project),
+
+ gradleExecutablePath: gradleExecutablePath,
+
outputParser: (String line) {
+
if (_kBuildVariantRegex.firstMatch(line) case final RegExpMatch match) {
+
results.add(match.namedGroup(_kBuildVariantRegexGroupName)!);
+
@@ -948,6 +952,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
late Stopwatch sw;
+
int exitCode = 1;
+
try {
+
+ final [String gradleExecutablePath, ...List<String> options] = _gradleUtils.getExecutable(
+
+ project,
+
+ );
+
+
+
exitCode = await _runGradleTask(
+
taskName,
+
preRunTask: () {
+
@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder {
+
),
+
);
+
},
+
- options: <String>['-q', '-PoutputPath=$outputPath'],
+
+ options: <String>[...options, '-q', '-PoutputPath=$outputPath'],
+
project: project,
+
localGradleErrors: gradleErrors,
+
- gradleExecutablePath: _gradleUtils.getExecutable(project),
+
+ gradleExecutablePath: gradleExecutablePath,
+
);
+
} on Error catch (error) {
+
_logger.printError(error.toString());
+
--- a/packages/flutter_tools/lib/src/android/gradle_errors.dart
+
+++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart
+
@@ -240,7 +240,12 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
+
required bool usesAndroidX,
+
}) async {
+
final RunResult tasksRunResult = await globals.processUtils.run(
+
- <String>[globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'],
+
+ <String>[
+
+ ...globals.gradleUtils!.getExecutable(project),
+
+ 'app:tasks',
+
+ '--all',
+
+ '--console=auto',
+
+ ],
+
throwOnError: true,
+
workingDirectory: project.android.hostAppGradleRoot.path,
+
environment: globals.java?.environment,
+
--- a/packages/flutter_tools/lib/src/android/gradle_utils.dart
+
+++ b/packages/flutter_tools/lib/src/android/gradle_utils.dart
+
@@ -3,6 +3,7 @@
+
// found in the LICENSE file.
+
+
import 'package:meta/meta.dart';
+
+import 'package:path/path.dart';
+
import 'package:process/process.dart';
+
import 'package:unified_analytics/unified_analytics.dart';
+
+
@@ -154,9 +155,16 @@ class GradleUtils {
+
final Logger _logger;
+
final OperatingSystemUtils _operatingSystemUtils;
+
+
+ List<String> get _requiredArguments => <String>[
+
+ '--project-cache-dir=${join(switch (globals.platform.environment['XDG_CACHE_HOME']) {
+
+ final String cacheHome => cacheHome,
+
+ _ => join(globals.fsUtils.homeDirPath ?? throwToolExit('No cache directory has been specified.'), '.cache'),
+
+ }, 'flutter', 'nix-flutter-tools-gradle', globals.flutterVersion.engineRevision.substring(0, 10), 'cache')}',
+
+ ];
+
+
+
/// Gets the Gradle executable path and prepares the Gradle project.
+
/// This is the `gradlew` or `gradlew.bat` script in the `android/` directory.
+
- String getExecutable(FlutterProject project) {
+
+ List<String> getExecutable(FlutterProject project) {
+
final Directory androidDir = project.android.hostAppGradleRoot;
+
injectGradleWrapperIfNeeded(androidDir);
+
+
@@ -167,7 +175,7 @@ class GradleUtils {
+
// If the Gradle executable doesn't have execute permission,
+
// then attempt to set it.
+
_operatingSystemUtils.makeExecutable(gradle);
+
- return gradle.absolute.path;
+
+ return <String>[gradle.absolute.path, ..._requiredArguments];
+
}
+
throwToolExit(
+
'Unable to locate gradlew script. Please check that ${gradle.path} '
+
--- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
+
+++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
+
@@ -2740,8 +2740,8 @@ Gradle Crashed
+
+
class FakeGradleUtils extends Fake implements GradleUtils {
+
@override
+
- String getExecutable(FlutterProject project) {
+
- return 'gradlew';
+
+ List<String> getExecutable(FlutterProject project) {
+
+ return const <String>['gradlew'];
+
}
+
}
+
+
--- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
+
+++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
+
@@ -1580,8 +1580,8 @@ Platform fakePlatform(String name) {
+
+
class FakeGradleUtils extends Fake implements GradleUtils {
+
@override
+
- String getExecutable(FlutterProject project) {
+
- return 'gradlew';
+
+ List<String> getExecutable(FlutterProject project) {
+
+ return const <String>['gradlew'];
+
}
+
}
+