• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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