From 4ccd185ba8fb3a5c1ad8c6d0c672e638d3b365c9 Mon Sep 17 00:00:00 2001 From: hacker1024 Date: Sun, 1 Jun 2025 20:32:58 +1000 Subject: [PATCH 1/2] flutter{329,332}: Pass --project-cache-dir to Gradle --- .../gradle-flutter-tools-wrapper.patch | 164 +++++++++++++++++- .../gradle-flutter-tools-wrapper.patch | 164 +++++++++++++++++- 2 files changed, 316 insertions(+), 12 deletions(-) diff --git a/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch b/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch index b579b4b42f8e..2d72b8915282 100644 --- a/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch +++ b/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch @@ -15,11 +15,9 @@ The intermediate project makes a `settings.gradle` file in `$HOME/.cache/flutter 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//`, but `build` doesn't. -To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle//` 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//`, 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 @@ @@ -44,12 +42,166 @@ index 0000000000..b2485c94b4 +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 options = []; +- +- final String gradleExecutablePath = _gradleUtils.getExecutable(project); ++ final [String gradleExecutablePath, ...List 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 command = [ +- _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 results = []; + + try { ++ final [String gradleExecutablePath, ...List options] = _gradleUtils.getExecutable( ++ project, ++ ); ++ + exitCode = await _runGradleTask( + _kBuildVariantTaskName, + preRunTask: () { +@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder { + ), + ); + }, +- options: const ['-q'], ++ options: [...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 options] = _gradleUtils.getExecutable( ++ project, ++ ); ++ + exitCode = await _runGradleTask( + taskName, + preRunTask: () { +@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder { + ), + ); + }, +- options: ['-q', '-PoutputPath=$outputPath'], ++ options: [...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( +- [globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'], ++ [ ++ ...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 get _requiredArguments => [ ++ '--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 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 [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 getExecutable(FlutterProject project) { ++ return const ['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 getExecutable(FlutterProject project) { ++ return const ['gradlew']; + } + } + diff --git a/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch b/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch index b579b4b42f8e..2d72b8915282 100644 --- a/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch +++ b/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch @@ -15,11 +15,9 @@ The intermediate project makes a `settings.gradle` file in `$HOME/.cache/flutter 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//`, but `build` doesn't. -To move `build` to `$HOME/.cache/flutter/nix-flutter-tools-gradle//` 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//`, 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 @@ @@ -44,12 +42,166 @@ index 0000000000..b2485c94b4 +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 options = []; +- +- final String gradleExecutablePath = _gradleUtils.getExecutable(project); ++ final [String gradleExecutablePath, ...List 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 command = [ +- _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 results = []; + + try { ++ final [String gradleExecutablePath, ...List options] = _gradleUtils.getExecutable( ++ project, ++ ); ++ + exitCode = await _runGradleTask( + _kBuildVariantTaskName, + preRunTask: () { +@@ -911,10 +915,10 @@ class AndroidGradleBuilder implements AndroidBuilder { + ), + ); + }, +- options: const ['-q'], ++ options: [...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 options] = _gradleUtils.getExecutable( ++ project, ++ ); ++ + exitCode = await _runGradleTask( + taskName, + preRunTask: () { +@@ -963,10 +971,10 @@ class AndroidGradleBuilder implements AndroidBuilder { + ), + ); + }, +- options: ['-q', '-PoutputPath=$outputPath'], ++ options: [...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( +- [globals.gradleUtils!.getExecutable(project), 'app:tasks', '--all', '--console=auto'], ++ [ ++ ...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 get _requiredArguments => [ ++ '--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 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 [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 getExecutable(FlutterProject project) { ++ return const ['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 getExecutable(FlutterProject project) { ++ return const ['gradlew']; + } + } + From c276ee50c4c2dac4f28d5293424b3e963dcd567c Mon Sep 17 00:00:00 2001 From: hacker1024 Date: Sun, 1 Jun 2025 21:04:25 +1000 Subject: [PATCH 2/2] flutter{329,332}: Pass -Pkotlin.project.persistent.dir as well --- .../gradle-flutter-tools-wrapper.patch | 29 ++++++++++++++----- .../gradle-flutter-tools-wrapper.patch | 29 ++++++++++++++----- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch b/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch index 2d72b8915282..34f6a1c99a64 100644 --- a/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch +++ b/pkgs/development/compilers/flutter/versions/3_29/patches/gradle-flutter-tools-wrapper.patch @@ -152,16 +152,29 @@ Changing the `GradleUtils.getExecutable` function signature is a delibarate choi import 'package:process/process.dart'; import 'package:unified_analytics/unified_analytics.dart'; -@@ -154,9 +155,16 @@ class GradleUtils { +@@ -154,9 +155,29 @@ class GradleUtils { final Logger _logger; final OperatingSystemUtils _operatingSystemUtils; -+ List get _requiredArguments => [ -+ '--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')}', -+ ]; ++ List get _requiredArguments { ++ final String cacheDir = 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), ++ ); ++ ++ return [ ++ '--project-cache-dir=${join(cacheDir, 'cache')}', ++ '-Pkotlin.project.persistent.dir=${join(cacheDir, 'kotlin')}', ++ ]; ++ } + /// Gets the Gradle executable path and prepares the Gradle project. /// This is the `gradlew` or `gradlew.bat` script in the `android/` directory. @@ -170,7 +183,7 @@ Changing the `GradleUtils.getExecutable` function signature is a delibarate choi final Directory androidDir = project.android.hostAppGradleRoot; injectGradleWrapperIfNeeded(androidDir); -@@ -167,7 +175,7 @@ class GradleUtils { +@@ -167,7 +188,7 @@ class GradleUtils { // If the Gradle executable doesn't have execute permission, // then attempt to set it. _operatingSystemUtils.makeExecutable(gradle); diff --git a/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch b/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch index 2d72b8915282..34f6a1c99a64 100644 --- a/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch +++ b/pkgs/development/compilers/flutter/versions/3_32/patches/gradle-flutter-tools-wrapper.patch @@ -152,16 +152,29 @@ Changing the `GradleUtils.getExecutable` function signature is a delibarate choi import 'package:process/process.dart'; import 'package:unified_analytics/unified_analytics.dart'; -@@ -154,9 +155,16 @@ class GradleUtils { +@@ -154,9 +155,29 @@ class GradleUtils { final Logger _logger; final OperatingSystemUtils _operatingSystemUtils; -+ List get _requiredArguments => [ -+ '--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')}', -+ ]; ++ List get _requiredArguments { ++ final String cacheDir = 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), ++ ); ++ ++ return [ ++ '--project-cache-dir=${join(cacheDir, 'cache')}', ++ '-Pkotlin.project.persistent.dir=${join(cacheDir, 'kotlin')}', ++ ]; ++ } + /// Gets the Gradle executable path and prepares the Gradle project. /// This is the `gradlew` or `gradlew.bat` script in the `android/` directory. @@ -170,7 +183,7 @@ Changing the `GradleUtils.getExecutable` function signature is a delibarate choi final Directory androidDir = project.android.hostAppGradleRoot; injectGradleWrapperIfNeeded(androidDir); -@@ -167,7 +175,7 @@ class GradleUtils { +@@ -167,7 +188,7 @@ class GradleUtils { // If the Gradle executable doesn't have execute permission, // then attempt to set it. _operatingSystemUtils.makeExecutable(gradle);