mirror of
https://github.com/flutter/flutter
synced 2024-08-27 03:50:33 +00:00
[flutter_tools] support --split-debug-info option in android builds (#49650)
This commit is contained in:
parent
de7908f9e9
commit
da4b5d68c4
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -102,6 +102,9 @@ unlinked_spec.ds
|
|||
# Coverage
|
||||
coverage/
|
||||
|
||||
# Symbols
|
||||
app.*.symbols
|
||||
|
||||
# Exceptions to above rules.
|
||||
!**/ios/**/default.mode1v3
|
||||
!**/ios/**/default.mode2v3
|
||||
|
|
|
@ -37,6 +37,12 @@ if [[ -n "$FLUTTER_ENGINE" ]]; then
|
|||
flutter_engine_flag="--local-engine-src-path=${FLUTTER_ENGINE}"
|
||||
fi
|
||||
|
||||
# Provide location to split debug info
|
||||
split_debug_info_option=""
|
||||
if [[ -n "$SPLIT_DEBUG_INFO" ]]; then
|
||||
split_debug_info_option="-dSplitDebugInfo=${SPLIT_DEBUG_INFO}"
|
||||
fi
|
||||
|
||||
# Set the build mode
|
||||
build_mode="$(echo "${FLUTTER_BUILD_MODE:-${CONFIGURATION}}" | tr "[:upper:]" "[:lower:]")"
|
||||
|
||||
|
@ -75,7 +81,8 @@ RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics \
|
|||
-dTargetPlatform=darwin-x64 \
|
||||
-dTargetFile="${target_path}" \
|
||||
-dBuildMode="${build_mode}" \
|
||||
-dFontSubset="${icon_tree_shaker_flag}" \
|
||||
"${split_debug_info_option}" \
|
||||
-dFontSubset="${icon_tree_shaker_flag}" \
|
||||
--build-inputs="${build_inputs_path}" \
|
||||
--build-outputs="${build_outputs_path}" \
|
||||
--output="${ephemeral_dir}" \
|
||||
|
|
|
@ -603,6 +603,10 @@ class FlutterPlugin implements Plugin<Project> {
|
|||
if (project.hasProperty('extra-gen-snapshot-options')) {
|
||||
extraGenSnapshotOptionsValue = project.property('extra-gen-snapshot-options')
|
||||
}
|
||||
String splitDebugInfoValue = null
|
||||
if (project.hasProperty('split-debug-info')) {
|
||||
splitDebugInfoValue = project.property('split-debug-info')
|
||||
}
|
||||
Boolean treeShakeIconsOptionsValue = false
|
||||
if (project.hasProperty('tree-shake-icons')) {
|
||||
treeShakeIconsOptionsValue = project.property('tree-shake-icons').toBoolean()
|
||||
|
@ -641,6 +645,7 @@ class FlutterPlugin implements Plugin<Project> {
|
|||
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/")
|
||||
extraFrontEndOptions extraFrontEndOptionsValue
|
||||
extraGenSnapshotOptions extraGenSnapshotOptionsValue
|
||||
splitDebugInfo splitDebugInfoValue
|
||||
treeShakeIcons treeShakeIconsOptionsValue
|
||||
}
|
||||
File libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar")
|
||||
|
@ -775,6 +780,8 @@ abstract class BaseFlutterTask extends DefaultTask {
|
|||
@Optional @Input
|
||||
String extraGenSnapshotOptions
|
||||
@Optional @Input
|
||||
String splitDebugInfo
|
||||
@Optional @Input
|
||||
Boolean treeShakeIcons
|
||||
|
||||
@OutputFiles
|
||||
|
@ -832,6 +839,9 @@ abstract class BaseFlutterTask extends DefaultTask {
|
|||
if (extraFrontEndOptions != null) {
|
||||
args "-dExtraFrontEndOptions=${extraFrontEndOptions}"
|
||||
}
|
||||
if (splitDebugInfo != null) {
|
||||
args "-dSplitDebugInfo=${splitDebugInfo}"
|
||||
}
|
||||
if (treeShakeIcons == true) {
|
||||
args "-dTreeShakeIcons=true"
|
||||
}
|
||||
|
|
|
@ -338,6 +338,9 @@ Future<void> buildGradleApp({
|
|||
if (androidBuildInfo.fastStart) {
|
||||
command.add('-Pfast-start=true');
|
||||
}
|
||||
if (androidBuildInfo.buildInfo.splitDebugInfoPath != null) {
|
||||
command.add('-Psplit-debug-info=${androidBuildInfo.buildInfo.splitDebugInfoPath}');
|
||||
}
|
||||
if (androidBuildInfo.buildInfo.treeShakeIcons) {
|
||||
command.add('-Ptree-shake-icons=true');
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ class AotBuilder {
|
|||
extraGenSnapshotOptions: extraGenSnapshotOptions,
|
||||
bitcode: bitcode,
|
||||
quiet: quiet,
|
||||
splitDebugInfo: null,
|
||||
).then<int>((int buildExitCode) {
|
||||
return buildExitCode;
|
||||
});
|
||||
|
@ -128,6 +129,7 @@ class AotBuilder {
|
|||
outputPath: outputPath,
|
||||
extraGenSnapshotOptions: extraGenSnapshotOptions,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
if (snapshotExitCode != 0) {
|
||||
status?.cancel();
|
||||
|
|
|
@ -94,6 +94,7 @@ class AOTSnapshotter {
|
|||
DarwinArch darwinArch,
|
||||
List<String> extraGenSnapshotOptions = const <String>[],
|
||||
@required bool bitcode,
|
||||
@required String splitDebugInfo,
|
||||
bool quiet = false,
|
||||
}) async {
|
||||
if (bitcode && platform != TargetPlatform.ios) {
|
||||
|
@ -157,11 +158,25 @@ class AOTSnapshotter {
|
|||
genSnapshotArgs.add('--no-use-integer-division');
|
||||
}
|
||||
|
||||
// The name of the debug file must contain additonal information about
|
||||
// the architecture, since a single build command may produce
|
||||
// multiple debug files.
|
||||
final String archName = getNameForTargetPlatform(platform, darwinArch: darwinArch);
|
||||
final String debugFilename = 'app.$archName.symbols';
|
||||
if (splitDebugInfo != null) {
|
||||
globals.fs.directory(splitDebugInfo)
|
||||
.createSync(recursive: true);
|
||||
}
|
||||
|
||||
// Optimization arguments.
|
||||
genSnapshotArgs.addAll(<String>[
|
||||
// Faster async/await
|
||||
'--no-causal-async-stacks',
|
||||
'--lazy-async-stacks',
|
||||
if (splitDebugInfo != null) ...<String>[
|
||||
'--dwarf-stack-traces',
|
||||
'--save-debugging-info=${globals.fs.path.join(splitDebugInfo, debugFilename)}'
|
||||
]
|
||||
]);
|
||||
|
||||
genSnapshotArgs.add(mainPath);
|
||||
|
|
|
@ -21,6 +21,7 @@ class BuildInfo {
|
|||
this.fileSystemScheme,
|
||||
this.buildNumber,
|
||||
this.buildName,
|
||||
this.splitDebugInfoPath,
|
||||
@required this.treeShakeIcons,
|
||||
});
|
||||
|
||||
|
@ -62,6 +63,11 @@ class BuildInfo {
|
|||
/// On Xcode builds it is used as CFBundleShortVersionString,
|
||||
final String buildName;
|
||||
|
||||
/// An optional directory path to save debugging information from dwarf stack
|
||||
/// traces. If null, stack trace information is not stripped from the
|
||||
/// executable.
|
||||
final String splitDebugInfoPath;
|
||||
|
||||
static const BuildInfo debug = BuildInfo(BuildMode.debug, null, treeShakeIcons: false);
|
||||
static const BuildInfo profile = BuildInfo(BuildMode.profile, null, treeShakeIcons: kIconTreeShakerEnabledDefault);
|
||||
static const BuildInfo jitRelease = BuildInfo(BuildMode.jitRelease, null, treeShakeIcons: kIconTreeShakerEnabledDefault);
|
||||
|
@ -392,7 +398,7 @@ DarwinArch getIOSArchForName(String arch) {
|
|||
return null;
|
||||
}
|
||||
|
||||
String getNameForTargetPlatform(TargetPlatform platform) {
|
||||
String getNameForTargetPlatform(TargetPlatform platform, {DarwinArch darwinArch}) {
|
||||
switch (platform) {
|
||||
case TargetPlatform.android_arm:
|
||||
return 'android-arm';
|
||||
|
@ -403,6 +409,9 @@ String getNameForTargetPlatform(TargetPlatform platform) {
|
|||
case TargetPlatform.android_x86:
|
||||
return 'android-x86';
|
||||
case TargetPlatform.ios:
|
||||
if (darwinArch != null) {
|
||||
return 'ios-${getNameForDarwinArch(darwinArch)}';
|
||||
}
|
||||
return 'ios';
|
||||
case TargetPlatform.darwin_x64:
|
||||
return 'darwin-x64';
|
||||
|
|
|
@ -204,6 +204,7 @@ class AndroidAot extends AotElfBase {
|
|||
Future<void> build(Environment environment) async {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: false);
|
||||
final Directory output = environment.buildDir.childDirectory(_androidAbiName);
|
||||
final String splitDebugInfo = environment.defines[kSplitDebugInfo];
|
||||
if (environment.defines[kBuildMode] == null) {
|
||||
throw MissingDefineException(kBuildMode, 'aot_elf');
|
||||
}
|
||||
|
@ -221,6 +222,7 @@ class AndroidAot extends AotElfBase {
|
|||
outputPath: output.path,
|
||||
bitcode: false,
|
||||
extraGenSnapshotOptions: extraGenSnapshotOptions,
|
||||
splitDebugInfo: splitDebugInfo,
|
||||
);
|
||||
if (snapshotExitCode != 0) {
|
||||
throw Exception('AOT snapshotter exited with code $snapshotExitCode');
|
||||
|
|
|
@ -41,6 +41,9 @@ const String kExtraFrontEndOptions = 'ExtraFrontEndOptions';
|
|||
/// This is expected to be a comma separated list of strings.
|
||||
const String kExtraGenSnapshotOptions = 'ExtraGenSnapshotOptions';
|
||||
|
||||
/// Whether to strip source code information out of release builds and where to save it.
|
||||
const String kSplitDebugInfo = 'SplitDebugInfo';
|
||||
|
||||
/// Alternative scheme for file URIs.
|
||||
///
|
||||
/// May be used along with [kFileSystemRoots] to support a multi-root
|
||||
|
@ -259,6 +262,7 @@ abstract class AotElfBase extends Target {
|
|||
?? const <String>[];
|
||||
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
|
||||
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
|
||||
final String saveDebuggingInformation = environment.defines[kSplitDebugInfo];
|
||||
final int snapshotExitCode = await snapshotter.build(
|
||||
platform: targetPlatform,
|
||||
buildMode: buildMode,
|
||||
|
@ -267,6 +271,7 @@ abstract class AotElfBase extends Target {
|
|||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
extraGenSnapshotOptions: extraGenSnapshotOptions,
|
||||
splitDebugInfo: saveDebuggingInformation
|
||||
);
|
||||
if (snapshotExitCode != 0) {
|
||||
throw Exception('AOT snapshotter exited with code $snapshotExitCode');
|
||||
|
|
|
@ -38,6 +38,7 @@ abstract class AotAssemblyBase extends Target {
|
|||
final bool bitcode = environment.defines[kBitcodeFlag] == 'true';
|
||||
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
|
||||
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
|
||||
final String splitDebugInfo = environment.defines[kSplitDebugInfo];
|
||||
final List<DarwinArch> iosArchs = environment.defines[kIosArchs]
|
||||
?.split(' ')
|
||||
?.map(getIOSArchForName)
|
||||
|
@ -60,6 +61,7 @@ abstract class AotAssemblyBase extends Target {
|
|||
darwinArch: iosArch,
|
||||
bitcode: bitcode,
|
||||
quiet: true,
|
||||
splitDebugInfo: splitDebugInfo,
|
||||
));
|
||||
}
|
||||
final List<int> results = await Future.wait(pending);
|
||||
|
|
|
@ -200,6 +200,7 @@ class CompileMacOSFramework extends Target {
|
|||
if (buildMode == BuildMode.debug) {
|
||||
throw Exception('precompiled macOS framework only supported in release/profile builds.');
|
||||
}
|
||||
final String splitDebugInfo = environment.defines[kSplitDebugInfo];
|
||||
final int result = await AOTSnapshotter(reportTimings: false).build(
|
||||
bitcode: false,
|
||||
buildMode: buildMode,
|
||||
|
@ -208,6 +209,7 @@ class CompileMacOSFramework extends Target {
|
|||
platform: TargetPlatform.darwin_x64,
|
||||
darwinArch: DarwinArch.x86_64,
|
||||
packagesPath: environment.projectDir.childFile('.packages').path,
|
||||
splitDebugInfo: splitDebugInfo,
|
||||
);
|
||||
if (result != 0) {
|
||||
throw Exception('gen shapshot failed.');
|
||||
|
|
|
@ -26,6 +26,7 @@ class BuildApkCommand extends BuildSubCommand {
|
|||
usesBuildNumberOption();
|
||||
usesBuildNameOption();
|
||||
addShrinkingFlag();
|
||||
addSplitDebugInfoOption();
|
||||
argParser
|
||||
..addFlag('split-per-abi',
|
||||
negatable: false,
|
||||
|
|
|
@ -167,6 +167,11 @@ List<String> _xcodeBuildSettingsLines({
|
|||
xcodeBuildSettings.add('FLUTTER_TARGET=$targetOverride');
|
||||
}
|
||||
|
||||
// This is an optional path to split debug info
|
||||
if (buildInfo.splitDebugInfoPath != null) {
|
||||
xcodeBuildSettings.add('SPLIT_DEBUG_INFO=${buildInfo.splitDebugInfoPath}');
|
||||
}
|
||||
|
||||
// The build outputs directory, relative to FLUTTER_APPLICATION_PATH.
|
||||
xcodeBuildSettings.add('FLUTTER_BUILD_DIR=${buildDirOverride ?? getBuildDirectory()}');
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ class FlutterOptions {
|
|||
static const String kEnableExperiment = 'enable-experiment';
|
||||
static const String kFileSystemRoot = 'filesystem-root';
|
||||
static const String kFileSystemScheme = 'filesystem-scheme';
|
||||
static const String kSplitDebugInfoOption = 'split-debug-info';
|
||||
}
|
||||
|
||||
abstract class FlutterCommand extends Command<void> {
|
||||
|
@ -366,6 +367,20 @@ abstract class FlutterCommand extends Command<void> {
|
|||
help: 'Build a JIT release version of your app${defaultToRelease ? ' (default mode)' : ''}.');
|
||||
}
|
||||
|
||||
void addSplitDebugInfoOption() {
|
||||
argParser.addOption(FlutterOptions.kSplitDebugInfoOption,
|
||||
help: 'In a release build, this flag reduces application size by storing '
|
||||
'Dart program symbols in a separate file on the host rather than in the '
|
||||
'application. The value of the flag should be a directory where program '
|
||||
'symbol files can be stored for later use. These symbol files contain '
|
||||
'the information needed to symbolize Dart stack traces. For an app built '
|
||||
'with this flag, the \'flutter symbolize\' command with the right program '
|
||||
'symbol file is required to obtain a human readable stack trace. This '
|
||||
'command is tracked by https://github.com/flutter/flutter/issues/50206',
|
||||
valueHelp: '/project-name/v1.2.3/',
|
||||
);
|
||||
}
|
||||
|
||||
void addTreeShakeIconsFlag() {
|
||||
argParser.addFlag('tree-shake-icons',
|
||||
negatable: true,
|
||||
|
@ -499,6 +514,9 @@ abstract class FlutterCommand extends Command<void> {
|
|||
buildName: argParser.options.containsKey('build-name')
|
||||
? stringArg('build-name')
|
||||
: null,
|
||||
splitDebugInfoPath: argParser.options.containsKey(FlutterOptions.kSplitDebugInfoOption)
|
||||
? stringArg(FlutterOptions.kSplitDebugInfoOption)
|
||||
: null,
|
||||
treeShakeIcons: argParser.options.containsKey('tree-shake-icons')
|
||||
? boolArg('tree-shake-icons')
|
||||
: kIconTreeShakerEnabledDefault,
|
||||
|
|
|
@ -33,5 +33,8 @@
|
|||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Exceptions to above rules.
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
|
|
|
@ -40,3 +40,6 @@ build/
|
|||
.ios/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
|
|
@ -266,6 +266,7 @@ void main() {
|
|||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
), isNot(equals(0)));
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
|
@ -278,6 +279,7 @@ void main() {
|
|||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
), isNot(0));
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
|
@ -290,6 +292,7 @@ void main() {
|
|||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
), isNot(0));
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
|
@ -316,6 +319,7 @@ void main() {
|
|||
outputPath: outputPath,
|
||||
darwinArch: DarwinArch.armv7,
|
||||
bitcode: true,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -376,6 +380,7 @@ void main() {
|
|||
outputPath: outputPath,
|
||||
darwinArch: DarwinArch.armv7,
|
||||
bitcode: true,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -435,6 +440,7 @@ void main() {
|
|||
outputPath: outputPath,
|
||||
darwinArch: DarwinArch.armv7,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -463,6 +469,61 @@ void main() {
|
|||
expect(assemblyFile.readAsStringSync().contains('.section __DWARF'), true);
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
testUsingContext('builds iOS armv7 profile AOT snapshot with dwarf stack traces', () async {
|
||||
globals.fs.file('main.dill').writeAsStringSync('binary magic');
|
||||
|
||||
final String outputPath = globals.fs.path.join('build', 'foo');
|
||||
globals.fs.directory(outputPath).createSync(recursive: true);
|
||||
|
||||
final String assembly = globals.fs.path.join(outputPath, 'snapshot_assembly.S');
|
||||
genSnapshot.outputs = <String, String>{
|
||||
assembly: 'blah blah\n.section __DWARF\nblah blah\n',
|
||||
};
|
||||
final String debugPath = globals.fs.path.join('foo', 'app.ios-armv7.symbols');
|
||||
|
||||
final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
|
||||
when(mockXcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
|
||||
when(mockXcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
|
||||
|
||||
final int genSnapshotExitCode = await snapshotter.build(
|
||||
platform: TargetPlatform.ios,
|
||||
buildMode: BuildMode.profile,
|
||||
mainPath: 'main.dill',
|
||||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
darwinArch: DarwinArch.armv7,
|
||||
bitcode: false,
|
||||
splitDebugInfo: 'foo',
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
expect(genSnapshot.callCount, 1);
|
||||
expect(genSnapshot.snapshotType.platform, TargetPlatform.ios);
|
||||
expect(genSnapshot.snapshotType.mode, BuildMode.profile);
|
||||
expect(genSnapshot.additionalArgs, <String>[
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-assembly',
|
||||
'--assembly=$assembly',
|
||||
'--strip',
|
||||
'--no-sim-use-hardfp',
|
||||
'--no-use-integer-division',
|
||||
'--no-causal-async-stacks',
|
||||
'--lazy-async-stacks',
|
||||
'--dwarf-stack-traces',
|
||||
'--save-debugging-info=$debugPath',
|
||||
'main.dill',
|
||||
]);
|
||||
verifyNever(mockXcode.cc(argThat(contains('-fembed-bitcode'))));
|
||||
verifyNever(mockXcode.clang(argThat(contains('-fembed-bitcode'))));
|
||||
|
||||
verify(mockXcode.cc(argThat(contains('-isysroot')))).called(1);
|
||||
verify(mockXcode.clang(argThat(contains('-isysroot')))).called(1);
|
||||
|
||||
final File assemblyFile = globals.fs.file(assembly);
|
||||
expect(assemblyFile.existsSync(), true);
|
||||
expect(assemblyFile.readAsStringSync().contains('.section __DWARF'), true);
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
testUsingContext('builds iOS arm64 profile AOT snapshot', () async {
|
||||
globals.fs.file('main.dill').writeAsStringSync('binary magic');
|
||||
|
||||
|
@ -485,6 +546,7 @@ void main() {
|
|||
outputPath: outputPath,
|
||||
darwinArch: DarwinArch.arm64,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -524,6 +586,7 @@ void main() {
|
|||
outputPath: outputPath,
|
||||
darwinArch: DarwinArch.armv7,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -565,6 +628,7 @@ void main() {
|
|||
outputPath: outputPath,
|
||||
darwinArch: DarwinArch.arm64,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -595,6 +659,7 @@ void main() {
|
|||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -614,6 +679,42 @@ void main() {
|
|||
]);
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
testUsingContext('builds shared library for android-arm with dwarf stack traces', () async {
|
||||
globals.fs.file('main.dill').writeAsStringSync('binary magic');
|
||||
|
||||
final String outputPath = globals.fs.path.join('build', 'foo');
|
||||
final String debugPath = globals.fs.path.join('foo', 'app.android-arm.symbols');
|
||||
globals.fs.directory(outputPath).createSync(recursive: true);
|
||||
|
||||
final int genSnapshotExitCode = await snapshotter.build(
|
||||
platform: TargetPlatform.android_arm,
|
||||
buildMode: BuildMode.release,
|
||||
mainPath: 'main.dill',
|
||||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
splitDebugInfo: 'foo',
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
expect(genSnapshot.callCount, 1);
|
||||
expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm);
|
||||
expect(genSnapshot.snapshotType.mode, BuildMode.release);
|
||||
expect(genSnapshot.additionalArgs, <String>[
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=build/foo/app.so',
|
||||
'--strip',
|
||||
'--no-sim-use-hardfp',
|
||||
'--no-use-integer-division',
|
||||
'--no-causal-async-stacks',
|
||||
'--lazy-async-stacks',
|
||||
'--dwarf-stack-traces',
|
||||
'--save-debugging-info=$debugPath',
|
||||
'main.dill',
|
||||
]);
|
||||
}, overrides: contextOverrides);
|
||||
|
||||
testUsingContext('builds shared library for android-arm64', () async {
|
||||
globals.fs.file('main.dill').writeAsStringSync('binary magic');
|
||||
|
||||
|
@ -627,6 +728,7 @@ void main() {
|
|||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
@ -665,6 +767,7 @@ void main() {
|
|||
packagesPath: '.packages',
|
||||
outputPath: outputPath,
|
||||
bitcode: false,
|
||||
splitDebugInfo: null,
|
||||
);
|
||||
|
||||
expect(genSnapshotExitCode, 0);
|
||||
|
|
|
@ -78,4 +78,11 @@ void main() {
|
|||
expect(() => BuildMode.fromName('foo'), throwsArgumentError);
|
||||
});
|
||||
});
|
||||
|
||||
test('getNameForTargetPlatform on Darwin arches', () {
|
||||
expect(getNameForTargetPlatform(TargetPlatform.ios, darwinArch: DarwinArch.arm64), 'ios-arm64');
|
||||
expect(getNameForTargetPlatform(TargetPlatform.ios, darwinArch: DarwinArch.armv7), 'ios-armv7');
|
||||
expect(getNameForTargetPlatform(TargetPlatform.ios, darwinArch: DarwinArch.x86_64), 'ios-x86_64');
|
||||
expect(getNameForTargetPlatform(TargetPlatform.android), isNot(contains('ios')));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -230,6 +230,35 @@ void main() {
|
|||
ProcessManager: () => mockProcessManager,
|
||||
});
|
||||
|
||||
testUsingContext('--split-debug-info is enabled when an output directory is provided', () async {
|
||||
final String projectPath = await createProject(tempDir,
|
||||
arguments: <String>['--no-pub', '--template=app']);
|
||||
|
||||
await expectLater(() async {
|
||||
await runBuildApkCommand(projectPath, arguments: <String>['--split-debug-info=${tempDir.path}']);
|
||||
}, throwsToolExit(message: 'Gradle task assembleRelease failed with exit code 1'));
|
||||
|
||||
verify(mockProcessManager.start(
|
||||
<String>[
|
||||
gradlew,
|
||||
'-q',
|
||||
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
|
||||
'-Ptrack-widget-creation=true',
|
||||
'-Pshrink=true',
|
||||
'-Ptarget-platform=android-arm,android-arm64,android-x64',
|
||||
'-Psplit-debug-info=${tempDir.path}',
|
||||
'assembleRelease',
|
||||
],
|
||||
workingDirectory: anyNamed('workingDirectory'),
|
||||
environment: anyNamed('environment'),
|
||||
)).called(1);
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
AndroidSdk: () => mockAndroidSdk,
|
||||
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
|
||||
ProcessManager: () => mockProcessManager,
|
||||
});
|
||||
|
||||
testUsingContext('shrinking is disabled when --no-shrink is passed', () async {
|
||||
final String projectPath = await createProject(tempDir,
|
||||
arguments: <String>['--no-pub', '--template=app']);
|
||||
|
|
Loading…
Reference in a new issue