Skip to content

Change project.buildDir in standalone subprojects property#91030

Merged
fluttergithubbot merged 1 commit into
flutter:masterfrom
littleGnAl:littlegnal/fix-subprojects-builddir-not-correct-2
Oct 2, 2021
Merged

Change project.buildDir in standalone subprojects property#91030
fluttergithubbot merged 1 commit into
flutter:masterfrom
littleGnAl:littlegnal/fix-subprojects-builddir-not-correct-2

Conversation

@littleGnAl

@littleGnAl littleGnAl commented Sep 30, 2021

Copy link
Copy Markdown
Contributor

If there is a plugin project whose name is before 'app' (in lexicographical order), the project ':app' buildDir is not set correctly.

This PR revert the changes made by #77942, I'm not sure it's the right way to fix this issue, but I add a test for this case to ensure it works as expected.

List which issues are fixed by this PR. You must list at least one issue.

Fixed #91018

If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard Bot added a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) d: examples Sample code and demos f: integration_test The flutter/packages/integration_test plugin c: contributor-productivity Team-specific productivity, code health, technical debt. tool Affects the "flutter" command-line tool. See also t: labels. labels Sep 30, 2021
@google-cla google-cla Bot added the cla: yes label Sep 30, 2021
@jmagman

jmagman commented Sep 30, 2021

Copy link
Copy Markdown
Member

@blasten

@blasten

blasten commented Oct 1, 2021

Copy link
Copy Markdown

we need a test for this. would you be able to wire a plugin in the test that has the desired name?

The code below has an example about how to create a plugin in a test:

@littleGnAl

Copy link
Copy Markdown
Contributor Author

Hello @blasten, I have reused the android_plugin_example_app_build_test.dart, should I add a standalone integration.shard for this case?
https://github.com/flutter/flutter/pull/91030/files#diff-0a03b0a0c8e091b09635cd4d75bd08462084a15c4333fbc9fa95eab9bf2537e1R129-R130

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blasten I have added a new test case here, should I move it to a standalone test file?

@blasten

blasten commented Oct 1, 2021

Copy link
Copy Markdown

ah - that should work. does the test fail if you revert the changes to the template?

@littleGnAl

Copy link
Copy Markdown
Contributor Author

ah - that should work. does the test fail if you revert the changes to the template?

@blasten It seems no

@blasten blasten left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Please verify the test fail without the fix

@littleGnAl

Copy link
Copy Markdown
Contributor Author

@blasten The test fails without the fix.

➜  flutter_tools git:(littlegnal/fix-subprojects-builddir-not-correct-2) ../../bin/cache/dart-sdk/bin/pub run test /Users/fenglang/codes/source/flutter/packages/flutter_tools/test/integration.shard/android_plugin_example_app_build_test.dart
The top level `pub` command is deprecated. Use `dart pub` instead.
01:49 +1 -1: plugin example android/app/build should not exists after flutter build [E]
  Expected: false
    Actual: <true>

  package:test_api                                                          expect
  test/integration.shard/android_plugin_example_app_build_test.dart 72:5    main._createAndBuildPlugin
  test/integration.shard/android_plugin_example_app_build_test.dart 130:5   main.<fn>
  test/integration.shard/android_plugin_example_app_build_test.dart 129:82  main.<fn>
  test/src/common.dart 163:18                                               test.<fn>
  test/src/common.dart 159:5                                                test.<fn>

01:49 +1 -1: loading /Users/fenglang/codes/source/flutter/packages/flutter_tools/test/integration.shard/android_plugin_example_app_build_test.dart
Consider enabling the flag chain-stack-traces to receive more detailed exceptions.
For example, 'dart test --chain-stack-traces'.
01:49 +1 -1: Some tests failed.
diff --git a/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle b/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle
index 24047dce5d..ed45c65885 100644
--- a/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle
+++ b/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle
@@ -21,8 +21,6 @@ allprojects {
 rootProject.buildDir = '../build'
 subprojects {
     project.buildDir = "${rootProject.buildDir}/${project.name}"
-}
-subprojects {
     project.evaluationDependsOn(':app')
 }

@littleGnAl littleGnAl force-pushed the littlegnal/fix-subprojects-builddir-not-correct-2 branch from a6b5f9f to 4b5df4a Compare October 1, 2021 03:18
@littleGnAl

Copy link
Copy Markdown
Contributor Author

@blasten I finally move the test to a standalone file to fill more test cases, pls take a look again, thanks.

@littleGnAl

Copy link
Copy Markdown
Contributor Author

The tests fail without this fix.

➜  flutter_tools git:(littlegnal/fix-subprojects-builddir-not-correct-2) ✗ ../../bin/cache/dart-sdk/bin/pub run test /Users/fenglang/codes/source/flutter/packages/flutter_tools/test/integration.shard/flutter_build_android_app_project_builddir_test.dart
The top level `pub` command is deprecated. Use `dart pub` instead.
01:08 +0 -1: android/app/build should not exists after flutter build apk [E]
  Expected: not a file system entity that exists
    Actual: LocalDirectory:<LocalDirectory: '/private/var/folders/gk/3g8dn2ys3nv01yxsd0j_1cz00000gr/T/flutter_flutter_plugin_test.tUCf5b/aaa/example/android/app/build'>

  package:test_api                                                                  expect
  test/integration.shard/flutter_build_android_app_project_builddir_test.dart 55:5  main._checkBuildDir
  test/integration.shard/flutter_build_android_app_project_builddir_test.dart 68:7  main.<fn>
  test/integration.shard/flutter_build_android_app_project_builddir_test.dart 60:5  main.<fn>
  test/src/common.dart 163:18                                                       test.<fn>
  test/src/common.dart 159:5                                                        test.<fn>

01:08 +0 -1: loading /Users/fenglang/codes/source/flutter/packages/flutter_tools/test/integration.shard/flutter_build_android_app_project_builddir_test.dart
Consider enabling the flag chain-stack-traces to receive more detailed exceptions.
For example, 'dart test --chain-stack-traces'.
01:47 +0 -2: android/app/build should not exists after flutter build appbundle [E]
  Expected: not a file system entity that exists
    Actual: LocalDirectory:<LocalDirectory: '/private/var/folders/gk/3g8dn2ys3nv01yxsd0j_1cz00000gr/T/flutter_flutter_plugin_test.D0m6sd/aaa/example/android/app/build'>

  package:test_api                                                                  expect
  test/integration.shard/flutter_build_android_app_project_builddir_test.dart 55:5  main._checkBuildDir
  test/integration.shard/flutter_build_android_app_project_builddir_test.dart 82:7  main.<fn>
  test/integration.shard/flutter_build_android_app_project_builddir_test.dart 74:5  main.<fn>
  test/src/common.dart 163:18                                                       test.<fn>
  test/src/common.dart 159:5                                                        test.<fn>

01:47 +0 -2: loading /Users/fenglang/codes/source/flutter/packages/flutter_tools/test/integration.shard/flutter_build_android_app_project_builddir_test.dart
Consider enabling the flag chain-stack-traces to receive more detailed exceptions.
For example, 'dart test --chain-stack-traces'.
01:47 +0 -2: Some tests failed.
diff --git a/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle b/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle
index 24047dce5d..ed45c65885 100644
--- a/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle
+++ b/packages/flutter_tools/templates/app_shared/android-kotlin.tmpl/build.gradle
@@ -21,8 +21,6 @@ allprojects {
 rootProject.buildDir = '../build'
 subprojects {
     project.buildDir = "${rootProject.buildDir}/${project.name}"
-}
-subprojects {
     project.evaluationDependsOn(':app')
 }

@blasten blasten left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! LGTM

@fluttergithubbot fluttergithubbot merged commit 1b73a35 into flutter:master Oct 2, 2021
@gspencergoog

Copy link
Copy Markdown
Contributor

This appears to have broken the build. I'm going to try and revert and see if it fixes this.

gspencergoog added a commit to gspencergoog/flutter that referenced this pull request Oct 2, 2021
…lutter#91030)"

This reverts commit 1b73a35 because it appears to have broken the build.
@gspencergoog

Copy link
Copy Markdown
Contributor

Actually, it doesn't appear to be the case: the revert PR failed too. Probably an infra issue.

AngeloAvv pushed a commit to AngeloAvv/flutter that referenced this pull request Jun 23, 2026
## Summary

`libapp.so` could be silently dropped from release APKs
and app bundles, surfacing as either:

- a runtime crash on launch — `VM snapshot invalid and could not be
inferred from
  settings` — for APKs, or
- a `Release app bundle failed to strip debug symbols from native
libraries`
  build failure for app bundles.

## Root cause

Regression from flutter#181275, which moved `libapp.so` from a jar dependency
onto a
Flutter Gradle Plugin source-set `jniLibs` directory. That delivery was
fragile
in two ways, both of which dropped `libapp.so` from the merged native
libraries
(while `libflutter.so`/`libdartjni.so`, delivered as AAR dependencies,
were
unaffected — which is why the failure looked asymmetric):

1. The source-set `jniLibs` `srcDir` was resolved eagerly
(`.get().asFile`) at
`:app` configuration time, while the copy task wrote lazily. When `:app`
was
   evaluated before its build directory had been redirected — a combined
`subprojects { … evaluationDependsOn(":app") }` block (the pre-flutter#91030
template
shape) together with a plugin whose Gradle subproject name sorts before
`:app` — the two disagreed on the build directory and the staged
`libapp.so`
   was never merged. (flutter#186810)
2. The copy task wrote into a directory nested inside the Flutter task's
own
output directory, creating overlapping task outputs that undermined
Gradle's
incremental checks — e.g. a flavored project where a prior single-ABI
build
(a `flutter run` on one device) left the other ABIs missing `libapp.so`.
   (flutter#187388)

## Fix

Stage `libapp.so` (and any bundled native assets) through a dedicated
`CopyFlutterJniLibsTask` whose output is registered on each variant via
AGP's
variant API:
[`variant.sources.jniLibs.addGeneratedSourceDirectory(...)`](https://developer.android.com/reference/tools/gradle-api/9.1/com/android/build/api/variant/SourceDirectories#addStaticSourceDirectory(kotlin.String)).
AGP then
owns the task dependency, resolves the output path lazily (correct
regardless of
project evaluation order or build-dir redirection), keeps it in its own
output
directory (no overlapping outputs), and strips/extracts debug symbols
from it
like any other native library. This restores the robustness of the
original
jar-based inclusion while keeping `libapp.so` strippable.

## Tests

New integration test `gradle_libapp_so_packaging_test.dart` covering
both
triggers: the combined `subprojects` block + a plugin sorted before
`:app`, and
a flavored single-ABI build preceding a multi-ABI build.

Fixes flutter#186810
Fixes flutter#187388
Fixes flutter#187553
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
## Summary

`libapp.so` could be silently dropped from release APKs
and app bundles, surfacing as either:

- a runtime crash on launch — `VM snapshot invalid and could not be
inferred from
  settings` — for APKs, or
- a `Release app bundle failed to strip debug symbols from native
libraries`
  build failure for app bundles.

## Root cause

Regression from flutter#181275, which moved `libapp.so` from a jar dependency
onto a
Flutter Gradle Plugin source-set `jniLibs` directory. That delivery was
fragile
in two ways, both of which dropped `libapp.so` from the merged native
libraries
(while `libflutter.so`/`libdartjni.so`, delivered as AAR dependencies,
were
unaffected — which is why the failure looked asymmetric):

1. The source-set `jniLibs` `srcDir` was resolved eagerly
(`.get().asFile`) at
`:app` configuration time, while the copy task wrote lazily. When `:app`
was
   evaluated before its build directory had been redirected — a combined
`subprojects { … evaluationDependsOn(":app") }` block (the pre-flutter#91030
template
shape) together with a plugin whose Gradle subproject name sorts before
`:app` — the two disagreed on the build directory and the staged
`libapp.so`
   was never merged. (flutter#186810)
2. The copy task wrote into a directory nested inside the Flutter task's
own
output directory, creating overlapping task outputs that undermined
Gradle's
incremental checks — e.g. a flavored project where a prior single-ABI
build
(a `flutter run` on one device) left the other ABIs missing `libapp.so`.
   (flutter#187388)

## Fix

Stage `libapp.so` (and any bundled native assets) through a dedicated
`CopyFlutterJniLibsTask` whose output is registered on each variant via
AGP's
variant API:
[`variant.sources.jniLibs.addGeneratedSourceDirectory(...)`](https://developer.android.com/reference/tools/gradle-api/9.1/com/android/build/api/variant/SourceDirectories#addStaticSourceDirectory(kotlin.String)).
AGP then
owns the task dependency, resolves the output path lazily (correct
regardless of
project evaluation order or build-dir redirection), keeps it in its own
output
directory (no overlapping outputs), and strips/extracts debug symbols
from it
like any other native library. This restores the robustness of the
original
jar-based inclusion while keeping `libapp.so` strippable.

## Tests

New integration test `gradle_libapp_so_packaging_test.dart` covering
both
triggers: the combined `subprojects` block + a plugin sorted before
`:app`, and
a flavored single-ABI build preceding a multi-ABI build.

Fixes flutter#186810
Fixes flutter#187388
Fixes flutter#187553
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) c: contributor-productivity Team-specific productivity, code health, technical debt. d: examples Sample code and demos f: integration_test The flutter/packages/integration_test plugin tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

android/app module's project buildDir not correct after subprojects block merged

5 participants