Skip to content

Commit 0975e61

Browse files
authored
[tool][android] Allow --target-platform work properly with --debug mode (flutter#154476)
This PR addresses an issue where the `--target-platform` flag was not being respected when building APKs in debug mode. Previously, debug builds would always include `x86` and `x64` architectures, regardless of the specified target platform. This change ensures that the `--target-platform` flag is honored across all build modes, including debug. To achieve this, `BuildApkCommand` has been slightly changed to become responsible for list of archs that should be built in the current run,rather than just parsing arguments. Previously, this responsibility was distributed to gradle, which could be frustrating (in my opinion) Fixes flutter#153359
1 parent 6bba08c commit 0975e61

File tree

5 files changed

+189
-47
lines changed

5 files changed

+189
-47
lines changed

dev/devicelab/bin/tasks/build_aar_module_test.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ Future<void> main() async {
228228

229229
checkFileContains(<String>[
230230
'flutter_embedding_debug',
231-
'x86_debug',
232231
'x86_64_debug',
233232
'armeabi_v7a_debug',
234233
'arm64_v8a_debug',

dev/devicelab/bin/tasks/gradle_plugin_light_apk_test.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ Future<void> main() async {
3434
...debugAssets,
3535
...baseApkFiles,
3636
'lib/armeabi-v7a/libflutter.so',
37-
// Debug mode intentionally includes `x86` and `x86_64`.
38-
'lib/x86/libflutter.so',
39-
'lib/x86_64/libflutter.so',
4037
], apkFiles);
4138

4239
checkCollectionDoesNotContain<String>(<String>[
@@ -65,9 +62,7 @@ Future<void> main() async {
6562
...flutterAssets,
6663
...debugAssets,
6764
...baseApkFiles,
68-
// Debug mode intentionally includes `x86` and `x86_64`.
6965
'lib/x86/libflutter.so',
70-
'lib/x86_64/libflutter.so',
7166
], apkFiles);
7267

7368
checkCollectionDoesNotContain<String>(<String>[
@@ -96,8 +91,6 @@ Future<void> main() async {
9691
...flutterAssets,
9792
...debugAssets,
9893
...baseApkFiles,
99-
// Debug mode intentionally includes `x86` and `x86_64`.
100-
'lib/x86/libflutter.so',
10194
'lib/x86_64/libflutter.so',
10295
], apkFiles);
10396

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -637,11 +637,6 @@ class FlutterPlugin implements Plugin<Project> {
637637
"io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion")
638638
}
639639
List<String> platforms = getTargetPlatforms().collect()
640-
// Debug mode includes x86 and x64, which are commonly used in emulators.
641-
if (flutterBuildMode == "debug" && !useLocalEngine()) {
642-
platforms.add("android-x86")
643-
platforms.add("android-x64")
644-
}
645640
platforms.each { platform ->
646641
String arch = PLATFORM_ARCH_MAP[platform].replace("-", "_")
647642
// Add the `libflutter.so` dependency.

packages/flutter_tools/lib/src/commands/build_apk.dart

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,43 @@ class BuildApkCommand extends BuildSubCommand {
4848
help: 'Generate build files used by flutter but '
4949
'do not build any artifacts.')
5050
..addMultiOption('target-platform',
51-
defaultsTo: <String>['android-arm', 'android-arm64', 'android-x64'],
5251
allowed: <String>['android-arm', 'android-arm64', 'android-x86', 'android-x64'],
53-
// https://github.com/flutter/flutter/issues/153359 tracks debug build type support.
5452
help:
55-
'The target platform for which the app is compiled. Supports release but not debug build types.',
53+
'The target platform for which the app is compiled.',
5654
);
5755
usesTrackWidgetCreation(verboseHelp: verboseHelp);
5856
}
5957

58+
BuildMode get _buildMode {
59+
if (boolArg('release')) {
60+
return BuildMode.release;
61+
} else if (boolArg('profile')) {
62+
return BuildMode.profile;
63+
} else if (boolArg('debug')) {
64+
return BuildMode.debug;
65+
} else if (boolArg('jit-release')) {
66+
return BuildMode.jitRelease;
67+
}
68+
return BuildMode.release;
69+
}
70+
static const List<String> _kDefaultJitArchs = <String>[
71+
'android-arm',
72+
'android-arm64',
73+
'android-x86',
74+
'android-x64',
75+
];
76+
static const List<String> _kDefaultAotArchs = <String>[
77+
'android-arm',
78+
'android-arm64',
79+
'android-x64',
80+
];
81+
List<String> get _targetArchs => stringsArg('target-platform').isEmpty
82+
? switch (_buildMode) {
83+
BuildMode.release || BuildMode.profile => _kDefaultAotArchs,
84+
BuildMode.debug || BuildMode.jitRelease => _kDefaultJitArchs,
85+
}
86+
: stringsArg('target-platform');
87+
6088
@override
6189
final String name = 'apk';
6290

@@ -81,46 +109,20 @@ class BuildApkCommand extends BuildSubCommand {
81109

82110
@override
83111
Future<CustomDimensions> get usageValues async {
84-
String buildMode;
85-
86-
if (boolArg('release')) {
87-
buildMode = 'release';
88-
} else if (boolArg('debug')) {
89-
buildMode = 'debug';
90-
} else if (boolArg('profile')) {
91-
buildMode = 'profile';
92-
} else {
93-
// The build defaults to release.
94-
buildMode = 'release';
95-
}
96-
97112
return CustomDimensions(
98-
commandBuildApkTargetPlatform: stringsArg('target-platform').join(','),
99-
commandBuildApkBuildMode: buildMode,
113+
commandBuildApkTargetPlatform: _targetArchs.join(','),
114+
commandBuildApkBuildMode: _buildMode.cliName,
100115
commandBuildApkSplitPerAbi: boolArg('split-per-abi'),
101116
);
102117
}
103118

104119
@override
105120
Future<Event> unifiedAnalyticsUsageValues(String commandPath) async {
106-
final String buildMode;
107-
108-
if (boolArg('release')) {
109-
buildMode = 'release';
110-
} else if (boolArg('debug')) {
111-
buildMode = 'debug';
112-
} else if (boolArg('profile')) {
113-
buildMode = 'profile';
114-
} else {
115-
// The build defaults to release.
116-
buildMode = 'release';
117-
}
118-
119121
return Event.commandUsageValues(
120122
workflow: commandPath,
121123
commandHasTerminal: hasTerminal,
122-
buildApkTargetPlatform: stringsArg('target-platform').join(','),
123-
buildApkBuildMode: buildMode,
124+
buildApkTargetPlatform: _targetArchs.join(','),
125+
buildApkBuildMode: _buildMode.cliName,
124126
buildApkSplitPerAbi: boolArg('split-per-abi'),
125127
);
126128
}
@@ -131,10 +133,11 @@ class BuildApkCommand extends BuildSubCommand {
131133
exitWithNoSdkMessage();
132134
}
133135
final BuildInfo buildInfo = await getBuildInfo();
136+
134137
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(
135138
buildInfo,
136139
splitPerAbi: boolArg('split-per-abi'),
137-
targetArchs: stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName),
140+
targetArchs: _targetArchs.map<AndroidArch>(getAndroidArchForName),
138141
);
139142
validateBuild(androidBuildInfo);
140143
displayNullSafetyMode(androidBuildInfo.buildInfo);

packages/flutter_tools/test/commands.shard/permeable/build_apk_test.dart

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,172 @@ void main() {
4848
testUsingContext('indicate the default target platforms', () async {
4949
final String projectPath = await createProject(tempDir,
5050
arguments: <String>['--no-pub', '--template=app']);
51+
52+
// Without buildMode flag.
5153
await runBuildApkCommand(projectPath);
54+
expect(
55+
fakeAnalytics.sentEvents,
56+
contains(
57+
Event.commandUsageValues(
58+
workflow: 'apk',
59+
commandHasTerminal: false,
60+
buildApkTargetPlatform: 'android-arm,android-arm64,android-x64',
61+
buildApkBuildMode: 'release',
62+
buildApkSplitPerAbi: false,
63+
),
64+
),
65+
);
66+
67+
await runBuildApkCommand(projectPath, arguments: <String>['--debug']);
68+
expect(
69+
fakeAnalytics.sentEvents,
70+
contains(
71+
Event.commandUsageValues(
72+
workflow: 'apk',
73+
commandHasTerminal: false,
74+
buildApkTargetPlatform: 'android-arm,android-arm64,android-x86,android-x64',
75+
buildApkBuildMode: 'debug',
76+
buildApkSplitPerAbi: false,
77+
),
78+
),
79+
);
5280

81+
await runBuildApkCommand(projectPath, arguments: <String>['--jit-release']);
82+
expect(
83+
fakeAnalytics.sentEvents,
84+
contains(
85+
Event.commandUsageValues(
86+
workflow: 'apk',
87+
commandHasTerminal: false,
88+
buildApkTargetPlatform: 'android-arm,android-arm64,android-x86,android-x64',
89+
buildApkBuildMode: 'jit_release',
90+
buildApkSplitPerAbi: false,
91+
),
92+
),
93+
);
94+
95+
await runBuildApkCommand(projectPath, arguments: <String>['--profile']);
5396
expect(
5497
fakeAnalytics.sentEvents,
5598
contains(
5699
Event.commandUsageValues(
57100
workflow: 'apk',
58101
commandHasTerminal: false,
59102
buildApkTargetPlatform: 'android-arm,android-arm64,android-x64',
103+
buildApkBuildMode: 'profile',
104+
buildApkSplitPerAbi: false,
105+
),
106+
),
107+
);
108+
109+
await runBuildApkCommand(projectPath, arguments: <String>['--release']);
110+
expect(
111+
fakeAnalytics.sentEvents,
112+
contains(
113+
Event.commandUsageValues(
114+
workflow: 'apk',
115+
commandHasTerminal: false,
116+
buildApkTargetPlatform: 'android-arm,android-arm64,android-x64',
117+
buildApkBuildMode: 'release',
118+
buildApkSplitPerAbi: false,
119+
),
120+
),
121+
);
122+
123+
}, overrides: <Type, Generator>{
124+
AndroidBuilder: () => FakeAndroidBuilder(),
125+
Analytics: () => fakeAnalytics,
126+
});
127+
128+
testUsingContext('Each build mode respects --target-platform', () async {
129+
final String projectPath = await createProject(tempDir,
130+
arguments: <String>['--no-pub', '--template=app']);
131+
132+
// Without buildMode flag.
133+
await runBuildApkCommand(
134+
projectPath,
135+
arguments: <String>['--target-platform=android-arm'],
136+
);
137+
expect(
138+
fakeAnalytics.sentEvents,
139+
contains(
140+
Event.commandUsageValues(
141+
workflow: 'apk',
142+
commandHasTerminal: false,
143+
buildApkTargetPlatform: 'android-arm',
60144
buildApkBuildMode: 'release',
61145
buildApkSplitPerAbi: false,
62146
),
63147
),
64148
);
149+
150+
await runBuildApkCommand(
151+
projectPath,
152+
arguments: <String>['--debug', '--target-platform=android-arm'],
153+
);
154+
expect(
155+
fakeAnalytics.sentEvents,
156+
contains(
157+
Event.commandUsageValues(
158+
workflow: 'apk',
159+
commandHasTerminal: false,
160+
buildApkTargetPlatform: 'android-arm',
161+
buildApkBuildMode: 'debug',
162+
buildApkSplitPerAbi: false,
163+
),
164+
),
165+
);
166+
167+
await runBuildApkCommand(
168+
projectPath,
169+
arguments: <String>['--release', '--target-platform=android-arm'],
170+
);
171+
expect(
172+
fakeAnalytics.sentEvents,
173+
contains(
174+
Event.commandUsageValues(
175+
workflow: 'apk',
176+
commandHasTerminal: false,
177+
buildApkTargetPlatform: 'android-arm',
178+
buildApkBuildMode: 'release',
179+
buildApkSplitPerAbi: false,
180+
),
181+
),
182+
);
183+
184+
await runBuildApkCommand(
185+
projectPath,
186+
arguments: <String>['--profile', '--target-platform=android-arm'],
187+
);
188+
expect(
189+
fakeAnalytics.sentEvents,
190+
contains(
191+
Event.commandUsageValues(
192+
workflow: 'apk',
193+
commandHasTerminal: false,
194+
buildApkTargetPlatform: 'android-arm',
195+
buildApkBuildMode: 'profile',
196+
buildApkSplitPerAbi: false,
197+
),
198+
),
199+
);
200+
201+
await runBuildApkCommand(
202+
projectPath,
203+
arguments: <String>['--jit-release', '--target-platform=android-arm'],
204+
);
205+
expect(
206+
fakeAnalytics.sentEvents,
207+
contains(
208+
Event.commandUsageValues(
209+
workflow: 'apk',
210+
commandHasTerminal: false,
211+
buildApkTargetPlatform: 'android-arm',
212+
buildApkBuildMode: 'jit_release',
213+
buildApkSplitPerAbi: false,
214+
),
215+
),
216+
);
65217
}, overrides: <Type, Generator>{
66218
AndroidBuilder: () => FakeAndroidBuilder(),
67219
Analytics: () => fakeAnalytics,

0 commit comments

Comments
 (0)