mirror of
https://github.com/flutter/flutter
synced 2024-10-14 04:02:56 +00:00
[flutter_tool] Fuchsia AOT builds (#45187)
This commit is contained in:
parent
43a8a1902e
commit
a57dddd217
|
@ -61,7 +61,7 @@ enum Artifact {
|
|||
|
||||
// Fuchsia artifacts from the engine prebuilts.
|
||||
fuchsiaKernelCompiler,
|
||||
fuchsiaFlutterJitRunner,
|
||||
fuchsiaFlutterRunner,
|
||||
}
|
||||
|
||||
String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMode mode ]) {
|
||||
|
@ -136,11 +136,10 @@ String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMo
|
|||
return 'flutter_ddc_sdk.dill';
|
||||
case Artifact.fuchsiaKernelCompiler:
|
||||
return 'kernel_compiler.snapshot';
|
||||
case Artifact.fuchsiaFlutterJitRunner:
|
||||
if (mode == BuildMode.debug || mode == BuildMode.profile) {
|
||||
return 'flutter_jit_runner-0.far';
|
||||
}
|
||||
return 'flutter_jit_product_runner-0.far';
|
||||
case Artifact.fuchsiaFlutterRunner:
|
||||
final String jitOrAot = mode.isJit ? '_jit' : '_aot';
|
||||
final String productOrNo = mode.isRelease ? '_product' : '';
|
||||
return 'flutter$jitOrAot${productOrNo}_runner-0.far';
|
||||
}
|
||||
assert(false, 'Invalid artifact $artifact.');
|
||||
return null;
|
||||
|
@ -278,21 +277,25 @@ class CachedArtifacts extends Artifacts {
|
|||
cache.getArtifactDirectory('flutter_runner').path,
|
||||
'flutter',
|
||||
fuchsiaArchForTargetPlatform(platform),
|
||||
getNameForBuildMode(mode),
|
||||
mode.isRelease ? 'release' : mode.toString(),
|
||||
);
|
||||
final String runtime = mode.isJit ? 'jit' : 'aot';
|
||||
switch (artifact) {
|
||||
case Artifact.genSnapshot:
|
||||
final String genSnapshot = mode.isRelease ? 'gen_snapshot_product' : 'gen_snapshot';
|
||||
return fs.path.join(root, runtime, 'dart_binaries', genSnapshot);
|
||||
case Artifact.flutterPatchedSdkPath:
|
||||
const String artifactFileName = 'flutter_runner_patched_sdk';
|
||||
return fs.path.join(root, 'jit', artifactFileName);
|
||||
return fs.path.join(root, runtime, artifactFileName);
|
||||
case Artifact.platformKernelDill:
|
||||
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
|
||||
return fs.path.join(root, 'jit', 'flutter_runner_patched_sdk', artifactFileName);
|
||||
return fs.path.join(root, runtime, 'flutter_runner_patched_sdk', artifactFileName);
|
||||
case Artifact.fuchsiaKernelCompiler:
|
||||
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
|
||||
return fs.path.join(root, 'jit', 'dart_binaries', artifactFileName);
|
||||
case Artifact.fuchsiaFlutterJitRunner:
|
||||
return fs.path.join(root, runtime, 'dart_binaries', artifactFileName);
|
||||
case Artifact.fuchsiaFlutterRunner:
|
||||
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
|
||||
return fs.path.join(root, 'jit', artifactFileName);
|
||||
return fs.path.join(root, runtime, artifactFileName);
|
||||
default:
|
||||
return _getHostArtifactPath(artifact, platform, mode);
|
||||
}
|
||||
|
@ -413,7 +416,7 @@ class LocalEngineArtifacts extends Artifacts {
|
|||
@override
|
||||
String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode }) {
|
||||
platform ??= _currentHostPlatform;
|
||||
final String artifactFileName = _artifactToFileName(artifact, platform);
|
||||
final String artifactFileName = _artifactToFileName(artifact, platform, mode);
|
||||
switch (artifact) {
|
||||
case Artifact.snapshotDart:
|
||||
return fs.path.join(_engineSrcPath, 'flutter', 'lib', 'snapshot', artifactFileName);
|
||||
|
@ -482,13 +485,13 @@ class LocalEngineArtifacts extends Artifacts {
|
|||
return fs.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
|
||||
case Artifact.fuchsiaKernelCompiler:
|
||||
final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
|
||||
final String dartBinaries = 'dart_binaries-$mode-$hostPlatform';
|
||||
final String modeName = mode.isRelease ? 'release' : mode.toString();
|
||||
final String dartBinaries = 'dart_binaries-$modeName-$hostPlatform';
|
||||
return fs.path.join(engineOutPath, 'host_bundle', dartBinaries, 'kernel_compiler.dart.snapshot');
|
||||
case Artifact.fuchsiaFlutterJitRunner:
|
||||
if (mode == BuildMode.debug || mode == BuildMode.profile) {
|
||||
return fs.path.join(engineOutPath, 'flutter_jit_runner-0.far');
|
||||
}
|
||||
return fs.path.join(engineOutPath, 'flutter_jit_product_runner-0.far');
|
||||
case Artifact.fuchsiaFlutterRunner:
|
||||
final String jitOrAot = mode.isJit ? '_jit' : '_aot';
|
||||
final String productOrNo = mode.isRelease ? '_product' : '';
|
||||
return fs.path.join(engineOutPath, 'flutter$jitOrAot${productOrNo}_runner-0.far');
|
||||
}
|
||||
assert(false, 'Invalid artifact $artifact.');
|
||||
return null;
|
||||
|
|
|
@ -59,6 +59,7 @@ class BuildInfo {
|
|||
|
||||
static const BuildInfo debug = BuildInfo(BuildMode.debug, null);
|
||||
static const BuildInfo profile = BuildInfo(BuildMode.profile, null);
|
||||
static const BuildInfo jitRelease = BuildInfo(BuildMode.jitRelease, null);
|
||||
static const BuildInfo release = BuildInfo(BuildMode.release, null);
|
||||
|
||||
/// Returns whether a debug build is requested.
|
||||
|
@ -68,14 +69,22 @@ class BuildInfo {
|
|||
|
||||
/// Returns whether a profile build is requested.
|
||||
///
|
||||
/// Exactly one of [isDebug], [isProfile], or [isRelease] is true.
|
||||
/// Exactly one of [isDebug], [isProfile], [isJitRelease],
|
||||
/// or [isRelease] is true.
|
||||
bool get isProfile => mode == BuildMode.profile;
|
||||
|
||||
/// Returns whether a release build is requested.
|
||||
///
|
||||
/// Exactly one of [isDebug], [isProfile], or [isRelease] is true.
|
||||
/// Exactly one of [isDebug], [isProfile], [isJitRelease],
|
||||
/// or [isRelease] is true.
|
||||
bool get isRelease => mode == BuildMode.release;
|
||||
|
||||
/// Returns whether a JIT release build is requested.
|
||||
///
|
||||
/// Exactly one of [isDebug], [isProfile], [isJitRelease],
|
||||
/// or [isRelease] is true.
|
||||
bool get isJitRelease => mode == BuildMode.jitRelease;
|
||||
|
||||
bool get usesAot => isAotBuildMode(mode);
|
||||
bool get supportsEmulator => isEmulatorBuildMode(mode);
|
||||
bool get supportsSimulator => isEmulatorBuildMode(mode);
|
||||
|
|
|
@ -214,7 +214,7 @@ class AttachCommand extends FlutterCommand {
|
|||
if (module == null) {
|
||||
throwToolExit('\'--module\' is required for attaching to a Fuchsia device');
|
||||
}
|
||||
usesIpv6 = device.ipv6;
|
||||
usesIpv6 = await device.ipv6;
|
||||
FuchsiaIsolateDiscoveryProtocol isolateDiscoveryProtocol;
|
||||
try {
|
||||
isolateDiscoveryProtocol = device.getIsolateDiscoveryProtocol(module);
|
||||
|
|
|
@ -31,6 +31,11 @@ class BuildFuchsiaCommand extends BuildSubCommand {
|
|||
],
|
||||
defaultsTo: FuchsiaPackageServer.toolHost,
|
||||
);
|
||||
argParser.addOption('target-platform',
|
||||
defaultsTo: 'fuchsia-x64',
|
||||
allowed: <String>['fuchsia-arm64', 'fuchsia-x64'],
|
||||
help: 'The target platform for which the app is compiled.',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -69,6 +74,7 @@ class BuildFuchsiaCommand extends BuildSubCommand {
|
|||
await buildFuchsia(
|
||||
fuchsiaProject: flutterProject.fuchsia,
|
||||
target: targetFile,
|
||||
targetPlatform: getTargetPlatformForName(argResults['target-platform']),
|
||||
buildInfo: buildInfo,
|
||||
runnerPackageSource: stringArg('runner-source'),
|
||||
);
|
||||
|
|
|
@ -19,24 +19,13 @@ import 'build.dart';
|
|||
/// .ipas, see https://flutter.dev/docs/deployment/ios.
|
||||
class BuildIOSCommand extends BuildSubCommand {
|
||||
BuildIOSCommand() {
|
||||
addBuildModeFlags(defaultToRelease: false);
|
||||
usesTargetOption();
|
||||
usesFlavorOption();
|
||||
usesPubOption();
|
||||
usesBuildNumberOption();
|
||||
usesBuildNameOption();
|
||||
argParser
|
||||
..addFlag('debug',
|
||||
negatable: false,
|
||||
help: 'Build a debug version of your app (default mode for iOS simulator builds).',
|
||||
)
|
||||
..addFlag('profile',
|
||||
negatable: false,
|
||||
help: 'Build a version of your app specialized for performance profiling.',
|
||||
)
|
||||
..addFlag('release',
|
||||
negatable: false,
|
||||
help: 'Build a release version of your app (default mode for device builds).',
|
||||
)
|
||||
..addFlag('simulator',
|
||||
help: 'Build for the iOS simulator instead of the device.',
|
||||
)
|
||||
|
|
|
@ -17,19 +17,8 @@ import 'build.dart';
|
|||
/// A command to build a linux desktop target through a build shell script.
|
||||
class BuildLinuxCommand extends BuildSubCommand {
|
||||
BuildLinuxCommand() {
|
||||
addBuildModeFlags(defaultToRelease: false);
|
||||
usesTargetOption();
|
||||
argParser.addFlag('debug',
|
||||
negatable: false,
|
||||
help: 'Build a debug version of your app.',
|
||||
);
|
||||
argParser.addFlag('profile',
|
||||
negatable: false,
|
||||
help: 'Build a version of your app specialized for performance profiling.',
|
||||
);
|
||||
argParser.addFlag('release',
|
||||
negatable: false,
|
||||
help: 'Build a version of your app specialized for performance profiling.',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -17,19 +17,8 @@ import 'build.dart';
|
|||
/// A command to build a windows desktop target through a build shell script.
|
||||
class BuildWindowsCommand extends BuildSubCommand {
|
||||
BuildWindowsCommand() {
|
||||
addBuildModeFlags(defaultToRelease: false);
|
||||
usesTargetOption();
|
||||
argParser.addFlag('debug',
|
||||
negatable: false,
|
||||
help: 'Build a debug version of your app.',
|
||||
);
|
||||
argParser.addFlag('profile',
|
||||
negatable: false,
|
||||
help: 'Build a version of your app specialized for performance profiling.',
|
||||
);
|
||||
argParser.addFlag('release',
|
||||
negatable: false,
|
||||
help: 'Build a version of your app specialized for performance profiling.',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -295,7 +295,7 @@ class RunCommand extends RunCommandBase {
|
|||
|
||||
DebuggingOptions _createDebuggingOptions() {
|
||||
final BuildInfo buildInfo = getBuildInfo();
|
||||
if (buildInfo.isRelease) {
|
||||
if (buildInfo.mode.isRelease) {
|
||||
return DebuggingOptions.disabled(
|
||||
buildInfo,
|
||||
initializePlatform: boolArg('web-initialize-platform'),
|
||||
|
|
|
@ -6,10 +6,13 @@ import 'dart:async';
|
|||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../asset.dart';
|
||||
import '../base/common.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/io.dart';
|
||||
import '../base/logger.dart';
|
||||
import '../base/process.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../build_info.dart';
|
||||
import '../bundle.dart';
|
||||
|
@ -37,6 +40,7 @@ Future<void> _timedBuildStep(String name, Future<void> Function() action) async
|
|||
// Fuchsia package.
|
||||
Future<void> buildFuchsia({
|
||||
@required FuchsiaProject fuchsiaProject,
|
||||
@required TargetPlatform targetPlatform,
|
||||
@required String target, // E.g., lib/main.dart
|
||||
BuildInfo buildInfo = BuildInfo.debug,
|
||||
String runnerPackageSource = FuchsiaPackageServer.toolHost,
|
||||
|
@ -49,12 +53,66 @@ Future<void> buildFuchsia({
|
|||
await _timedBuildStep('fuchsia-kernel-compile',
|
||||
() => fuchsiaSdk.fuchsiaKernelCompiler.build(
|
||||
fuchsiaProject: fuchsiaProject, target: target, buildInfo: buildInfo));
|
||||
|
||||
if (buildInfo.usesAot) {
|
||||
await _timedBuildStep('fuchsia-gen-snapshot',
|
||||
() => _genSnapshot(fuchsiaProject, target, buildInfo, targetPlatform));
|
||||
}
|
||||
|
||||
await _timedBuildStep('fuchsia-build-assets',
|
||||
() => _buildAssets(fuchsiaProject, target, buildInfo));
|
||||
await _timedBuildStep('fuchsia-build-package',
|
||||
() => _buildPackage(fuchsiaProject, target, buildInfo, runnerPackageSource));
|
||||
}
|
||||
|
||||
Future<void> _genSnapshot(
|
||||
FuchsiaProject fuchsiaProject,
|
||||
String target, // lib/main.dart
|
||||
BuildInfo buildInfo,
|
||||
TargetPlatform targetPlatform,
|
||||
) async {
|
||||
final String outDir = getFuchsiaBuildDirectory();
|
||||
final String appName = fuchsiaProject.project.manifest.appName;
|
||||
final String dilPath = fs.path.join(outDir, '$appName.dil');
|
||||
|
||||
final String vmSnapshotData = fs.path.join(outDir, 'vm_data.aotsnapshot');
|
||||
final String vmSnapshotInstructions = fs.path.join(outDir, 'vm_instructions.aotsnapshot');
|
||||
final String snapshotData = fs.path.join(outDir, 'data.aotsnapshot');
|
||||
final String snapshotInstructions = fs.path.join(outDir, 'instructions.aotsnapshot');
|
||||
|
||||
final String genSnapshot = artifacts.getArtifactPath(
|
||||
Artifact.genSnapshot,
|
||||
platform: targetPlatform,
|
||||
mode: buildInfo.mode,
|
||||
);
|
||||
|
||||
final List<String> command = <String>[
|
||||
genSnapshot,
|
||||
'--no_causal_async_stacks',
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-blobs',
|
||||
'--vm_snapshot_data=$vmSnapshotData',
|
||||
'--vm_snapshot_instructions=$vmSnapshotInstructions',
|
||||
'--isolate_snapshot_data=$snapshotData',
|
||||
'--isolate_snapshot_instructions=$snapshotInstructions',
|
||||
if (buildInfo.isDebug) '--enable-asserts',
|
||||
dilPath,
|
||||
];
|
||||
int result;
|
||||
final Status status = logger.startProgress(
|
||||
'Compiling Fuchsia application to native code...',
|
||||
timeout: null,
|
||||
);
|
||||
try {
|
||||
result = await processUtils.stream(command, trace: true);
|
||||
} finally {
|
||||
status.cancel();
|
||||
}
|
||||
if (result != 0) {
|
||||
throwToolExit('Build process failed');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _buildAssets(
|
||||
FuchsiaProject fuchsiaProject,
|
||||
String target, // lib/main.dart
|
||||
|
@ -98,12 +156,17 @@ void _rewriteCmx(BuildMode mode, String runnerPackageSource, File src, File dst)
|
|||
String runner;
|
||||
switch (mode) {
|
||||
case BuildMode.debug:
|
||||
case BuildMode.profile:
|
||||
runner = 'flutter_jit_runner';
|
||||
break;
|
||||
case BuildMode.release:
|
||||
case BuildMode.profile:
|
||||
runner = 'flutter_aot_runner';
|
||||
break;
|
||||
case BuildMode.jitRelease:
|
||||
runner = 'flutter_jit_product_runner';
|
||||
break;
|
||||
case BuildMode.release:
|
||||
runner = 'flutter_aot_product_runner';
|
||||
break;
|
||||
default:
|
||||
throwToolExit('Fuchsia does not support build mode "$mode"');
|
||||
break;
|
||||
|
@ -122,7 +185,6 @@ Future<void> _buildPackage(
|
|||
final String outDir = getFuchsiaBuildDirectory();
|
||||
final String pkgDir = fs.path.join(outDir, 'pkg');
|
||||
final String appName = fuchsiaProject.project.manifest.appName;
|
||||
final String dilpmanifest = fs.path.join(outDir, '$appName.dilpmanifest');
|
||||
final String pkgassets = fs.path.join(outDir, '${appName}_pkgassets');
|
||||
final String packageManifest = fs.path.join(pkgDir, 'package_manifest');
|
||||
final String devKeyPath = fs.path.join(pkgDir, 'development.key');
|
||||
|
@ -137,9 +199,29 @@ Future<void> _buildPackage(
|
|||
final File dstCmx = fs.file(fs.path.join(outDir, '$appName.cmx'));
|
||||
_rewriteCmx(buildInfo.mode, runnerPackageSource, srcCmx, dstCmx);
|
||||
|
||||
// Concatenate dilpmanifest and pkgassets into package_manifest.
|
||||
final File manifestFile = fs.file(packageManifest);
|
||||
|
||||
if (buildInfo.usesAot) {
|
||||
final String vmSnapshotData = fs.path.join(outDir, 'vm_data.aotsnapshot');
|
||||
final String vmSnapshotInstructions = fs.path.join(outDir, 'vm_instructions.aotsnapshot');
|
||||
final String snapshotData = fs.path.join(outDir, 'data.aotsnapshot');
|
||||
final String snapshotInstructions = fs.path.join(outDir, 'instructions.aotsnapshot');
|
||||
manifestFile.writeAsStringSync(
|
||||
'data/$appName/vm_snapshot_data.bin=$vmSnapshotData\n');
|
||||
manifestFile.writeAsStringSync(
|
||||
'data/$appName/vm_snapshot_instructions.bin=$vmSnapshotInstructions\n',
|
||||
mode: FileMode.append);
|
||||
manifestFile.writeAsStringSync(
|
||||
'data/$appName/isolate_snapshot_data.bin=$snapshotData\n',
|
||||
mode: FileMode.append);
|
||||
manifestFile.writeAsStringSync(
|
||||
'data/$appName/isolate_snapshot_instructions.bin=$snapshotInstructions\n',
|
||||
mode: FileMode.append);
|
||||
} else {
|
||||
final String dilpmanifest = fs.path.join(outDir, '$appName.dilpmanifest');
|
||||
manifestFile.writeAsStringSync(fs.file(dilpmanifest).readAsStringSync());
|
||||
}
|
||||
|
||||
manifestFile.writeAsStringSync(fs.file(pkgassets).readAsStringSync(),
|
||||
mode: FileMode.append);
|
||||
manifestFile.writeAsStringSync('meta/$appName.cmx=${dstCmx.path}\n',
|
||||
|
|
|
@ -40,12 +40,14 @@ class FuchsiaDevFinder {
|
|||
return result.stdout.split('\n');
|
||||
}
|
||||
|
||||
/// Returns the host address by which the device [deviceName] should use for
|
||||
/// the host.
|
||||
/// Returns the address of the named device.
|
||||
///
|
||||
/// If local is true, then gives the address by which the device reaches the
|
||||
/// host.
|
||||
///
|
||||
/// The string [deviceName] should be the name of the device from the
|
||||
/// 'list' command, e.g. 'scare-cable-skip-joy'.
|
||||
Future<String> resolve(String deviceName) async {
|
||||
Future<String> resolve(String deviceName, {bool local = false}) async {
|
||||
if (fuchsiaArtifacts.devFinder == null ||
|
||||
!fuchsiaArtifacts.devFinder.existsSync()) {
|
||||
throwToolExit('Fuchsia dev_finder tool not found.');
|
||||
|
@ -53,7 +55,7 @@ class FuchsiaDevFinder {
|
|||
final List<String> command = <String>[
|
||||
fuchsiaArtifacts.devFinder.path,
|
||||
'resolve',
|
||||
'-local',
|
||||
if (local) '-local',
|
||||
'-device-limit', '1',
|
||||
deviceName,
|
||||
];
|
||||
|
|
|
@ -230,13 +230,17 @@ class FuchsiaDevice extends Device {
|
|||
}) async {
|
||||
if (!prebuiltApplication) {
|
||||
await buildFuchsia(fuchsiaProject: FlutterProject.current().fuchsia,
|
||||
targetPlatform: await targetPlatform,
|
||||
target: mainPath,
|
||||
buildInfo: debuggingOptions.buildInfo);
|
||||
}
|
||||
// Stop the app if it's currently running.
|
||||
await stopApp(package);
|
||||
// Find out who the device thinks we are.
|
||||
final String host = await fuchsiaSdk.fuchsiaDevFinder.resolve(name);
|
||||
final String host = await fuchsiaSdk.fuchsiaDevFinder.resolve(
|
||||
name,
|
||||
local: true,
|
||||
);
|
||||
if (host == null) {
|
||||
printError('Failed to resolve host for Fuchsia device');
|
||||
return LaunchResult.failed();
|
||||
|
@ -301,7 +305,7 @@ class FuchsiaDevice extends Device {
|
|||
|
||||
// Serve the flutter_runner.
|
||||
final File flutterRunnerArchive = fs.file(artifacts.getArtifactPath(
|
||||
Artifact.fuchsiaFlutterJitRunner,
|
||||
Artifact.fuchsiaFlutterRunner,
|
||||
platform: await targetPlatform,
|
||||
mode: debuggingOptions.buildInfo.mode,
|
||||
));
|
||||
|
@ -318,10 +322,19 @@ class FuchsiaDevice extends Device {
|
|||
serverRegistered = true;
|
||||
|
||||
// Tell the package controller to prefetch the flutter_runner.
|
||||
String flutterRunnerName = 'flutter_jit_runner';
|
||||
if (!debuggingOptions.buildInfo.isDebug &&
|
||||
!debuggingOptions.buildInfo.isProfile) {
|
||||
String flutterRunnerName;
|
||||
if (debuggingOptions.buildInfo.usesAot) {
|
||||
if (debuggingOptions.buildInfo.mode.isRelease) {
|
||||
flutterRunnerName = 'flutter_aot_product_runner';
|
||||
} else {
|
||||
flutterRunnerName = 'flutter_aot_runner';
|
||||
}
|
||||
} else {
|
||||
if (debuggingOptions.buildInfo.mode.isRelease) {
|
||||
flutterRunnerName = 'flutter_jit_product_runner';
|
||||
} else {
|
||||
flutterRunnerName = 'flutter_jit_runner';
|
||||
}
|
||||
}
|
||||
if (!await fuchsiaDeviceTools.amberCtl.pkgCtlResolve(
|
||||
this, fuchsiaPackageServer, flutterRunnerName)) {
|
||||
|
@ -367,10 +380,11 @@ class FuchsiaDevice extends Device {
|
|||
status.cancel();
|
||||
}
|
||||
|
||||
if (!debuggingOptions.buildInfo.isDebug &&
|
||||
!debuggingOptions.buildInfo.isProfile) {
|
||||
if (debuggingOptions.buildInfo.mode.isRelease) {
|
||||
printTrace('App succesfully started in a release mode.');
|
||||
return LaunchResult.succeeded();
|
||||
}
|
||||
printTrace('App started in a non-release mode. Setting up vmservice connection.');
|
||||
|
||||
// In a debug or profile build, try to find the observatory uri.
|
||||
final FuchsiaIsolateDiscoveryProtocol discovery =
|
||||
|
@ -452,9 +466,9 @@ class FuchsiaDevice extends Device {
|
|||
@override
|
||||
bool get supportsScreenshot => false;
|
||||
|
||||
bool get ipv6 {
|
||||
Future<bool> get ipv6 async {
|
||||
// Workaround for https://github.com/dart-lang/sdk/issues/29456
|
||||
final String fragment = id.split('%').first;
|
||||
final String fragment = (await _resolvedIp).split('%').first;
|
||||
try {
|
||||
Uri.parseIPv6Address(fragment);
|
||||
return true;
|
||||
|
@ -468,7 +482,7 @@ class FuchsiaDevice extends Device {
|
|||
const String findCommand = 'find /hub -name vmservice-port';
|
||||
final RunResult findResult = await shell(findCommand);
|
||||
if (findResult.exitCode != 0) {
|
||||
throwToolExit("'$findCommand' on device $id failed. stderr: '${findResult.stderr}'");
|
||||
throwToolExit("'$findCommand' on device $name failed. stderr: '${findResult.stderr}'");
|
||||
return null;
|
||||
}
|
||||
final String findOutput = findResult.stdout;
|
||||
|
@ -485,7 +499,7 @@ class FuchsiaDevice extends Device {
|
|||
final String lsCommand = 'ls $path';
|
||||
final RunResult lsResult = await shell(lsCommand);
|
||||
if (lsResult.exitCode != 0) {
|
||||
throwToolExit("'$lsCommand' on device $id failed");
|
||||
throwToolExit("'$lsCommand' on device $name failed");
|
||||
return null;
|
||||
}
|
||||
final String lsOutput = lsResult.stdout;
|
||||
|
@ -502,6 +516,15 @@ class FuchsiaDevice extends Device {
|
|||
return ports;
|
||||
}
|
||||
|
||||
String _cachedResolvedIp;
|
||||
|
||||
Future<String> get _resolvedIp async {
|
||||
return _cachedResolvedIp ??= await fuchsiaSdk.fuchsiaDevFinder.resolve(
|
||||
name,
|
||||
local: false,
|
||||
);
|
||||
}
|
||||
|
||||
/// Run `command` on the Fuchsia device shell.
|
||||
Future<RunResult> shell(String command) async {
|
||||
if (fuchsiaArtifacts.sshConfig == null) {
|
||||
|
@ -512,7 +535,7 @@ class FuchsiaDevice extends Device {
|
|||
'ssh',
|
||||
'-F',
|
||||
fuchsiaArtifacts.sshConfig.absolute.path,
|
||||
id,
|
||||
await _resolvedIp,
|
||||
command,
|
||||
]);
|
||||
}
|
||||
|
@ -633,7 +656,7 @@ class FuchsiaIsolateDiscoveryProtocol {
|
|||
}
|
||||
final Uri address = flutterView.owner.vmService.httpAddress;
|
||||
if (flutterView.uiIsolate.name.contains(_isolateName)) {
|
||||
_foundUri.complete(_device.ipv6
|
||||
_foundUri.complete(await _device.ipv6
|
||||
? Uri.parse('http://[$_ipv6Loopback]:${address.port}/')
|
||||
: Uri.parse('http://$_ipv4Loopback:${address.port}/'));
|
||||
_status.stop();
|
||||
|
@ -674,7 +697,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
|
|||
'-f',
|
||||
'-L',
|
||||
'$hostPort:$_ipv4Loopback:$devicePort',
|
||||
device.id,
|
||||
await device._resolvedIp,
|
||||
'true',
|
||||
];
|
||||
final Process process = await processManager.start(command);
|
||||
|
@ -706,7 +729,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
|
|||
'-vvv',
|
||||
'-L',
|
||||
'${forwardedPort.hostPort}:$_ipv4Loopback:${forwardedPort.devicePort}',
|
||||
device.id,
|
||||
await device._resolvedIp,
|
||||
];
|
||||
final ProcessResult result = await processManager.run(command);
|
||||
if (result.exitCode != 0) {
|
||||
|
|
|
@ -7,11 +7,9 @@ import 'package:meta/meta.dart';
|
|||
import '../artifacts.dart';
|
||||
import '../base/common.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/io.dart';
|
||||
import '../base/logger.dart';
|
||||
import '../base/process.dart';
|
||||
import '../build_info.dart';
|
||||
import '../convert.dart';
|
||||
import '../globals.dart';
|
||||
import '../project.dart';
|
||||
|
||||
|
@ -58,35 +56,31 @@ class FuchsiaKernelCompiler {
|
|||
'--filesystem-root', fsRoot,
|
||||
'--packages', '$multiRootScheme:///$relativePackagesFile',
|
||||
'--output', fs.path.join(outDir, '$appName.dil'),
|
||||
'--component-name', appName,
|
||||
|
||||
// AOT/JIT:
|
||||
if (buildInfo.usesAot) ...<String>['--aot', '--tfa']
|
||||
else ...<String>[
|
||||
// TODO(zra): Add back when this is supported again.
|
||||
// See: https://github.com/flutter/flutter/issues/44925
|
||||
// '--no-link-platform',
|
||||
'--split-output-by-packages',
|
||||
'--manifest', manifestPath,
|
||||
'--component-name', appName,
|
||||
];
|
||||
'--manifest', manifestPath
|
||||
],
|
||||
|
||||
if (buildInfo.isDebug) {
|
||||
flags += <String>[
|
||||
'--embed-sources',
|
||||
];
|
||||
} else if (buildInfo.isProfile) {
|
||||
flags += <String>[
|
||||
'--no-embed-sources',
|
||||
'-Ddart.vm.profile=true',
|
||||
// debug, profile, jit release, release:
|
||||
if (buildInfo.isDebug) '--embed-sources'
|
||||
else '--no-embed-sources',
|
||||
|
||||
if (buildInfo.isProfile) '-Ddart.vm.profile=true',
|
||||
if (buildInfo.mode.isRelease) '-Ddart.vm.release=true',
|
||||
|
||||
// Use bytecode and drop the ast in JIT release mode.
|
||||
if (buildInfo.isJitRelease) ...<String>[
|
||||
'--gen-bytecode',
|
||||
'--drop-ast',
|
||||
],
|
||||
];
|
||||
} else if (buildInfo.isRelease) {
|
||||
flags += <String>[
|
||||
'--no-embed-sources',
|
||||
'-Ddart.vm.release=true',
|
||||
'--gen-bytecode',
|
||||
'--drop-ast',
|
||||
];
|
||||
} else {
|
||||
throwToolExit('Expected build type to be debug, profile, or release');
|
||||
}
|
||||
|
||||
flags += <String>[
|
||||
'$multiRootScheme:///$target',
|
||||
|
@ -97,22 +91,13 @@ class FuchsiaKernelCompiler {
|
|||
kernelCompiler,
|
||||
...flags,
|
||||
];
|
||||
final Process process = await processUtils.start(command);
|
||||
final Status status = logger.startProgress(
|
||||
'Building Fuchsia application...',
|
||||
timeout: null,
|
||||
);
|
||||
int result;
|
||||
try {
|
||||
process.stderr
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.listen(printError);
|
||||
process.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.listen(printTrace);
|
||||
result = await process.exitCode;
|
||||
result = await processUtils.stream(command, trace: true);
|
||||
} finally {
|
||||
status.cancel();
|
||||
}
|
||||
|
|
|
@ -337,6 +337,10 @@ abstract class FlutterCommand extends Command<void> {
|
|||
argParser.addFlag('release',
|
||||
negatable: false,
|
||||
help: 'Build a release version of your app${defaultToRelease ? ' (default mode)' : ''}.');
|
||||
argParser.addFlag('jit-release',
|
||||
negatable: false,
|
||||
hide: !verboseHelp,
|
||||
help: 'Build a JIT release version of your app${defaultToRelease ? ' (default mode)' : ''}.');
|
||||
}
|
||||
|
||||
void addShrinkingFlag() {
|
||||
|
@ -374,10 +378,18 @@ abstract class FlutterCommand extends Command<void> {
|
|||
}
|
||||
|
||||
BuildMode getBuildMode() {
|
||||
// No debug when _excludeDebug is true.
|
||||
// If debug is not excluded, then take the command line flag.
|
||||
final bool debugResult = !_excludeDebug && boolArg('debug');
|
||||
final List<bool> modeFlags = <bool>[debugResult, boolArg('profile'), boolArg('release')];
|
||||
final List<bool> modeFlags = <bool>[
|
||||
debugResult,
|
||||
boolArg('jit-release'),
|
||||
boolArg('profile'),
|
||||
boolArg('release'),
|
||||
];
|
||||
if (modeFlags.where((bool flag) => flag).length > 1) {
|
||||
throw UsageException('Only one of --debug, --profile, or --release can be specified.', null);
|
||||
throw UsageException('Only one of --debug, --profile, --jit-release, '
|
||||
'or --release can be specified.', null);
|
||||
}
|
||||
if (debugResult) {
|
||||
return BuildMode.debug;
|
||||
|
@ -388,6 +400,9 @@ abstract class FlutterCommand extends Command<void> {
|
|||
if (boolArg('release')) {
|
||||
return BuildMode.release;
|
||||
}
|
||||
if (boolArg('jit-release')) {
|
||||
return BuildMode.jitRelease;
|
||||
}
|
||||
return _defaultBuildMode;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import 'package:flutter_tools/src/fuchsia/fuchsia_kernel_compiler.dart';
|
|||
import 'package:flutter_tools/src/fuchsia/fuchsia_pm.dart';
|
||||
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
|
||||
import 'package:flutter_tools/src/fuchsia/tiles_ctl.dart';
|
||||
import 'package:flutter_tools/src/globals.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/vmservice.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
@ -111,6 +112,7 @@ void main() {
|
|||
expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64);
|
||||
}, overrides: <Type, Generator>{
|
||||
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(),
|
||||
ProcessUtils: () => mockProcessUtils,
|
||||
});
|
||||
|
||||
|
@ -122,6 +124,7 @@ void main() {
|
|||
expect(await device.targetPlatform, TargetPlatform.fuchsia_x64);
|
||||
}, overrides: <Type, Generator>{
|
||||
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(),
|
||||
ProcessUtils: () => mockProcessUtils,
|
||||
});
|
||||
});
|
||||
|
@ -180,6 +183,7 @@ void main() {
|
|||
sshConfig: mockFile,
|
||||
devFinder: mockFile,
|
||||
),
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(),
|
||||
});
|
||||
|
||||
group('device logs', () {
|
||||
|
@ -378,7 +382,38 @@ void main() {
|
|||
});
|
||||
});
|
||||
|
||||
group('fuchsia app start and stop: ', () {
|
||||
testUsingContext('Correct flutter runner', () async {
|
||||
expect(artifacts.getArtifactPath(
|
||||
Artifact.fuchsiaFlutterRunner,
|
||||
platform: TargetPlatform.fuchsia_x64,
|
||||
mode: BuildMode.debug,
|
||||
),
|
||||
contains('flutter_jit_runner'),
|
||||
);
|
||||
expect(artifacts.getArtifactPath(
|
||||
Artifact.fuchsiaFlutterRunner,
|
||||
platform: TargetPlatform.fuchsia_x64,
|
||||
mode: BuildMode.profile,
|
||||
),
|
||||
contains('flutter_aot_runner'),
|
||||
);
|
||||
expect(artifacts.getArtifactPath(
|
||||
Artifact.fuchsiaFlutterRunner,
|
||||
platform: TargetPlatform.fuchsia_x64,
|
||||
mode: BuildMode.release,
|
||||
),
|
||||
contains('flutter_aot_product_runner'),
|
||||
);
|
||||
expect(artifacts.getArtifactPath(
|
||||
Artifact.fuchsiaFlutterRunner,
|
||||
platform: TargetPlatform.fuchsia_x64,
|
||||
mode: BuildMode.jitRelease,
|
||||
),
|
||||
contains('flutter_jit_product_runner'),
|
||||
);
|
||||
});
|
||||
|
||||
group('Fuchsia app start and stop: ', () {
|
||||
MemoryFileSystem memoryFileSystem;
|
||||
FakeOperatingSystemUtils osUtils;
|
||||
FakeFuchsiaDeviceTools fuchsiaDeviceTools;
|
||||
|
@ -420,7 +455,7 @@ void main() {
|
|||
mode: anyNamed('mode'),
|
||||
)).thenReturn(patchedSdk.path);
|
||||
when(mockArtifacts.getArtifactPath(
|
||||
Artifact.fuchsiaFlutterJitRunner,
|
||||
Artifact.fuchsiaFlutterRunner,
|
||||
platform: anyNamed('platform'),
|
||||
mode: anyNamed('mode'),
|
||||
)).thenReturn(runner.path);
|
||||
|
@ -650,6 +685,7 @@ void main() {
|
|||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockSuccessProcessManager,
|
||||
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(),
|
||||
});
|
||||
|
||||
testUsingContext('returns "Fuchsia" when device command fails', () async {
|
||||
|
@ -658,6 +694,7 @@ void main() {
|
|||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockFailureProcessManager,
|
||||
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(),
|
||||
});
|
||||
|
||||
testUsingContext('returns "Fuchsia" when device gives an empty result', () async {
|
||||
|
@ -666,6 +703,7 @@ void main() {
|
|||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => emptyStdoutProcessManager,
|
||||
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -722,12 +760,16 @@ Process _createMockProcess({
|
|||
}
|
||||
|
||||
class MockFuchsiaDevice extends Mock implements FuchsiaDevice {
|
||||
MockFuchsiaDevice(this.id, this.portForwarder, this.ipv6);
|
||||
MockFuchsiaDevice(this.id, this.portForwarder, this._ipv6);
|
||||
|
||||
final bool _ipv6;
|
||||
|
||||
@override
|
||||
final bool ipv6;
|
||||
Future<bool> get ipv6 async => _ipv6;
|
||||
|
||||
@override
|
||||
final String id;
|
||||
|
||||
@override
|
||||
final DevicePortForwarder portForwarder;
|
||||
|
||||
|
@ -1073,7 +1115,7 @@ class FakeFuchsiaDevFinder implements FuchsiaDevFinder {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<String> resolve(String deviceName) async {
|
||||
Future<String> resolve(String deviceName, {bool local = false}) async {
|
||||
return '192.168.42.10';
|
||||
}
|
||||
}
|
||||
|
@ -1085,7 +1127,7 @@ class FailingDevFinder implements FuchsiaDevFinder {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<String> resolve(String deviceName) async {
|
||||
Future<String> resolve(String deviceName, {bool local = false}) async {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue