flx.dart 5.17 KB
Newer Older
1 2 3 4 5 6
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

7 8
import 'package:meta/meta.dart' show required;

9
import 'artifacts.dart';
10
import 'asset.dart';
11
import 'base/common.dart';
12
import 'base/file_system.dart';
13
import 'base/process.dart';
14
import 'build_info.dart';
15
import 'dart/package_map.dart';
16
import 'devfs.dart';
17
import 'globals.dart';
Devon Carew's avatar
Devon Carew committed
18
import 'zip.dart';
19 20

const String defaultMainPath = 'lib/main.dart';
21
const String defaultAssetBasePath = '.';
22
const String defaultManifestPath = 'pubspec.yaml';
23 24 25
String get defaultFlxOutputPath => fs.path.join(getBuildDirectory(), 'app.flx');
String get defaultSnapshotPath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin');
String get defaultDepfilePath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin.d');
26 27
const String defaultPrivateKeyPath = 'privatekey.der';

28
const String _kKernelKey = 'kernel_blob.bin';
29 30
const String _kSnapshotKey = 'snapshot_blob.bin';

31
Future<int> createSnapshot({
32 33
  @required String mainPath,
  @required String snapshotPath,
34
  String depfilePath,
35
  @required String packages
36 37 38 39
}) {
  assert(mainPath != null);
  assert(snapshotPath != null);
  assert(packages != null);
40
  final String snapshotterPath = artifacts.getArtifactPath(Artifact.genSnapshot, null, BuildMode.debug);
41 42
  final String vmSnapshotData = artifacts.getArtifactPath(Artifact.vmSnapshotData);
  final String isolateSnapshotData = artifacts.getArtifactPath(Artifact.isolateSnapshotData);
43 44 45 46 47 48 49 50 51 52 53

  final List<String> args = <String>[
    snapshotterPath,
    '--snapshot_kind=script',
    '--vm_snapshot_data=$vmSnapshotData',
    '--isolate_snapshot_data=$isolateSnapshotData',
    '--packages=$packages',
    '--script_snapshot=$snapshotPath'
  ];
  if (depfilePath != null) {
    args.add('--dependencies=$depfilePath');
54
    fs.file(depfilePath).parent.childFile('gen_snapshot.d').writeAsString('$depfilePath: $snapshotterPath\n');
55 56 57 58 59
  }
  args.add(mainPath);
  return runCommandAndStreamOutput(args);
}

60
Future<Null> build({
61 62
  String mainPath: defaultMainPath,
  String manifestPath: defaultManifestPath,
63 64 65
  String outputPath,
  String snapshotPath,
  String depfilePath,
66
  String privateKeyPath: defaultPrivateKeyPath,
67
  String workingDirPath,
68
  String packagesPath,
69
  String kernelPath,
70
  bool precompiledSnapshot: false,
71
  bool reportLicensedPackages: false
72
}) async {
73 74 75 76
  outputPath ??= defaultFlxOutputPath;
  snapshotPath ??= defaultSnapshotPath;
  depfilePath ??= defaultDepfilePath;
  workingDirPath ??= getAssetBuildDirectory();
77
  packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
78
  File snapshotFile;
Devon Carew's avatar
Devon Carew committed
79

80 81 82 83 84
  if (!precompiledSnapshot) {
    ensureDirectoryExists(snapshotPath);

    // In a precompiled snapshot, the instruction buffer contains script
    // content equivalents
85
    final int result = await createSnapshot(
86 87
      mainPath: mainPath,
      snapshotPath: snapshotPath,
88 89
      depfilePath: depfilePath,
      packages: packagesPath
90
    );
91 92
    if (result != 0)
      throwToolExit('Failed to run the Flutter compiler. Exit code: $result', exitCode: result);
93

94
    snapshotFile = fs.file(snapshotPath);
95
  }
96

97 98 99 100
  DevFSContent kernelContent;
  if (kernelPath != null)
    kernelContent = new DevFSFileContent(fs.file(kernelPath));

101
  return assemble(
102
    manifestPath: manifestPath,
103
    kernelContent: kernelContent,
Ian Hickson's avatar
Ian Hickson committed
104 105 106 107
    snapshotFile: snapshotFile,
    outputPath: outputPath,
    privateKeyPath: privateKeyPath,
    workingDirPath: workingDirPath,
108
    packagesPath: packagesPath,
109
    reportLicensedPackages: reportLicensedPackages
110
  ).then((_) => null);
111 112
}

113
Future<List<String>> assemble({
114
  String manifestPath,
115
  DevFSContent kernelContent,
Devon Carew's avatar
Devon Carew committed
116
  File snapshotFile,
117
  String outputPath,
118
  String privateKeyPath: defaultPrivateKeyPath,
119
  String workingDirPath,
120
  String packagesPath,
121
  bool includeDefaultFonts: true,
122
  bool reportLicensedPackages: false
123
}) async {
124 125
  outputPath ??= defaultFlxOutputPath;
  workingDirPath ??= getAssetBuildDirectory();
126
  packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
127 128
  printTrace('Building $outputPath');

129
  // Build the asset bundle.
130 131
  final AssetBundle assetBundle = new AssetBundle();
  final int result = await assetBundle.build(
132 133
    manifestPath: manifestPath,
    workingDirPath: workingDirPath,
134
    packagesPath: packagesPath,
135
    includeDefaultFonts: includeDefaultFonts,
136 137
    reportLicensedPackages: reportLicensedPackages
  );
138 139
  if (result != 0)
    throwToolExit('Error building $outputPath: $result', exitCode: result);
140

141
  final ZipBuilder zipBuilder = new ZipBuilder();
142

143 144
  // Add all entries from the asset bundle.
  zipBuilder.entries.addAll(assetBundle.entries);
145

146 147 148 149
  final List<String> fileDependencies = assetBundle.entries.values
      .expand((DevFSContent content) => content.fileDependencies)
      .toList();

150 151
  if (kernelContent != null)
    zipBuilder.entries[_kKernelKey] = kernelContent;
152
  if (snapshotFile != null)
153
    zipBuilder.entries[_kSnapshotKey] = new DevFSFileContent(snapshotFile);
Ian Hickson's avatar
Ian Hickson committed
154

155
  ensureDirectoryExists(outputPath);
156

157
  printTrace('Encoding zip file to $outputPath');
158
  await zipBuilder.createZip(fs.file(outputPath), fs.directory(workingDirPath));
159

Devon Carew's avatar
Devon Carew committed
160
  printTrace('Built $outputPath.');
161 162

  return fileDependencies;
163
}