1// Copyright 2019 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import 'package:meta/meta.dart'; 6 7import '../artifacts.dart'; 8import '../base/common.dart'; 9import '../base/file_system.dart'; 10import '../base/io.dart'; 11import '../base/logger.dart'; 12import '../base/process.dart'; 13import '../build_info.dart'; 14import '../convert.dart'; 15import '../globals.dart'; 16import '../project.dart'; 17 18import 'fuchsia_sdk.dart'; 19 20/// This is a simple wrapper around the custom kernel compiler from the Fuchsia 21/// SDK. 22class FuchsiaKernelCompiler { 23 /// Compiles the [fuchsiaProject] with entrypoint [target] to a collection of 24 /// .dilp files (consisting of the app split along package: boundaries, but 25 /// the Flutter tool should make no use of that fact), and a manifest that 26 /// refers to them. 27 Future<void> build({ 28 @required FuchsiaProject fuchsiaProject, 29 @required String target, // E.g., lib/main.dart 30 BuildInfo buildInfo = BuildInfo.debug, 31 }) async { 32 // TODO(zra): Use filesystem root and scheme information from buildInfo. 33 if (fuchsiaArtifacts.kernelCompiler == null) { 34 throwToolExit('Fuchisa kernel compiler not found'); 35 } 36 const String multiRootScheme = 'main-root'; 37 final String packagesFile = fuchsiaProject.project.packagesFile.path; 38 final String outDir = getFuchsiaBuildDirectory(); 39 final String appName = fuchsiaProject.project.manifest.appName; 40 final String fsRoot = fuchsiaProject.project.directory.path; 41 final String relativePackagesFile = 42 fs.path.relative(packagesFile, from: fsRoot); 43 final String manifestPath = fs.path.join(outDir, '$appName.dilpmanifest'); 44 List<String> flags = <String>[ 45 '--target', 'flutter_runner', 46 '--platform', fuchsiaArtifacts.platformKernelDill.path, 47 '--filesystem-scheme', 'main-root', 48 '--filesystem-root', fsRoot, 49 '--packages', '$multiRootScheme:///$relativePackagesFile', 50 '--output', fs.path.join(outDir, '$appName.dil'), 51 '--no-link-platform', 52 '--split-output-by-packages', 53 '--manifest', manifestPath, 54 '--component-name', appName, 55 ]; 56 57 if (buildInfo.isDebug) { 58 flags += <String>[ 59 '--embed-sources', 60 ]; 61 } else if (buildInfo.isProfile) { 62 flags += <String>[ 63 '--no-embed-sources', 64 '-Ddart.vm.profile=true', 65 '--gen-bytecode', 66 '--drop-ast', 67 ]; 68 } else if (buildInfo.isRelease) { 69 flags += <String>[ 70 '--no-embed-sources', 71 '-Ddart.vm.release=true', 72 '--gen-bytecode', 73 '--drop-ast', 74 ]; 75 } else { 76 throwToolExit('Expected build type to be debug, profile, or release'); 77 } 78 79 flags += <String>[ 80 '$multiRootScheme:///$target', 81 ]; 82 83 final List<String> command = <String>[ 84 artifacts.getArtifactPath(Artifact.engineDartBinary), 85 fuchsiaArtifacts.kernelCompiler.path, 86 ...flags, 87 ]; 88 final Process process = await runCommand(command); 89 final Status status = logger.startProgress( 90 'Building Fuchsia application...', 91 timeout: null, 92 ); 93 int result; 94 try { 95 process.stderr 96 .transform(utf8.decoder) 97 .transform(const LineSplitter()) 98 .listen(printError); 99 process.stdout 100 .transform(utf8.decoder) 101 .transform(const LineSplitter()) 102 .listen(printTrace); 103 result = await process.exitCode; 104 } finally { 105 status.cancel(); 106 } 107 if (result != 0) { 108 throwToolExit('Build process failed'); 109 } 110 } 111} 112