build_info.dart 9.66 KB
Newer Older
1 2 3 4
// 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.

5
import 'base/context.dart';
6
import 'base/file_system.dart';
7
import 'base/platform.dart';
8
import 'base/utils.dart';
9
import 'globals.dart';
10

11 12
/// Information about a build to be performed or used.
class BuildInfo {
13
  const BuildInfo(this.mode, this.flavor, {
14
    this.trackWidgetCreation = false,
15
    this.compilationTraceFilePath,
16 17
    this.createBaseline = false,
    this.createPatch = false,
18 19 20
    this.patchNumber,
    this.patchDir,
    this.baselineDir,
21 22
    this.extraFrontEndOptions,
    this.extraGenSnapshotOptions,
23
    this.buildSharedLibrary,
24
    this.targetPlatform,
25 26
    this.fileSystemRoots,
    this.fileSystemScheme,
27 28
    this.buildNumber,
    this.buildName,
29
  });
30 31

  final BuildMode mode;
32

33 34 35 36 37 38 39 40
  /// Represents a custom Android product flavor or an Xcode scheme, null for
  /// using the default.
  ///
  /// If not null, the Gradle build task will be `assembleFlavorMode` (e.g.
  /// `assemblePaidRelease`), and the Xcode build configuration will be
  /// Mode-Flavor (e.g. Release-Paid).
  final String flavor;

41 42 43
  final List<String> fileSystemRoots;
  final String fileSystemScheme;

44 45 46
  /// Whether the build should track widget creation locations.
  final bool trackWidgetCreation;

47 48
  /// Dart compilation trace file to use for JIT VM snapshot.
  final String compilationTraceFilePath;
49

50 51 52
  /// Save baseline package.
  final bool createBaseline;

53
  /// Build differential snapshot.
54 55 56
  final bool createPatch;

  /// Internal version number of dynamic patch (not displayed to users).
57
  /// Each patch may have a unique number to differentiate from previous
58 59 60 61 62 63 64 65 66 67
  /// patches for the same versionCode on Android or CFBundleVersion on iOS.
  final int patchNumber;

  /// The directory where to store generated dynamic patches.
  final String patchDir;

  /// The directory where to store generated baseline packages.
  /// Built packages, such as APK files on Android, are saved and can be used
  /// to generate dynamic patches in later builds.
  final String baselineDir;
68

69 70 71 72 73 74
  /// Extra command-line options for front-end.
  final String extraFrontEndOptions;

  /// Extra command-line options for gen_snapshot.
  final String extraGenSnapshotOptions;

75
  /// Whether to prefer AOT compiling to a *so file.
76
  final bool buildSharedLibrary;
77

78 79 80
  /// Target platform for the build (e.g. android_arm versus android_arm64).
  final TargetPlatform targetPlatform;

81 82 83 84 85 86 87 88 89 90 91 92 93
  /// Internal version number (not displayed to users).
  /// Each build must have a unique number to differentiate it from previous builds.
  /// It is used to determine whether one build is more recent than another, with higher numbers indicating more recent build.
  /// On Android it is used as versionCode.
  /// On Xcode builds it is used as CFBundleVersion.
  final int buildNumber;

  /// A "x.y.z" string used as the version number shown to users.
  /// For each new version of your app, you will provide a version number to differentiate it from previous versions.
  /// On Android it is used as versionName.
  /// On Xcode builds it is used as CFBundleShortVersionString,
  final String buildName;

94 95 96
  static const BuildInfo debug = BuildInfo(BuildMode.debug, null);
  static const BuildInfo profile = BuildInfo(BuildMode.profile, null);
  static const BuildInfo release = BuildInfo(BuildMode.release, null);
97 98
  static const BuildInfo dynamicProfile = BuildInfo(BuildMode.dynamicProfile, null);
  static const BuildInfo dynamicRelease = BuildInfo(BuildMode.dynamicRelease, null);
99 100 101 102 103 104 105 106 107

  /// Returns whether a debug build is requested.
  ///
  /// Exactly one of [isDebug], [isProfile], or [isRelease] is true.
  bool get isDebug => mode == BuildMode.debug;

  /// Returns whether a profile build is requested.
  ///
  /// Exactly one of [isDebug], [isProfile], or [isRelease] is true.
108
  bool get isProfile => mode == BuildMode.profile || mode == BuildMode.dynamicProfile;
109 110 111 112

  /// Returns whether a release build is requested.
  ///
  /// Exactly one of [isDebug], [isProfile], or [isRelease] is true.
113
  bool get isRelease => mode == BuildMode.release || mode == BuildMode.dynamicRelease;
114

115 116 117
  /// Returns whether a dynamic build is requested.
  bool get isDynamic => mode == BuildMode.dynamicProfile || mode == BuildMode.dynamicRelease;

118 119 120 121
  bool get usesAot => isAotBuildMode(mode);
  bool get supportsEmulator => isEmulatorBuildMode(mode);
  bool get supportsSimulator => isEmulatorBuildMode(mode);
  String get modeName => getModeName(mode);
122
  String get friendlyModeName => getFriendlyModeName(mode);
123 124

  BuildInfo withTargetPlatform(TargetPlatform targetPlatform) =>
125
      BuildInfo(mode, flavor,
126
          trackWidgetCreation: trackWidgetCreation,
127
          compilationTraceFilePath: compilationTraceFilePath,
128
          createPatch: createPatch,
129 130
          extraFrontEndOptions: extraFrontEndOptions,
          extraGenSnapshotOptions: extraGenSnapshotOptions,
131
          buildSharedLibrary: buildSharedLibrary,
132
          targetPlatform: targetPlatform);
133 134
}

135
/// The type of build.
136 137
enum BuildMode {
  debug,
138
  profile,
139 140 141
  release,
  dynamicProfile,
  dynamicRelease
142 143
}

144
String getModeName(BuildMode mode) => getEnumName(mode);
145

146 147 148 149
String getFriendlyModeName(BuildMode mode) {
  return snakeCase(getModeName(mode)).replaceAll('_', ' ');
}

150 151 152 153 154
// Returns true if the selected build mode uses ahead-of-time compilation.
bool isAotBuildMode(BuildMode mode) {
  return mode == BuildMode.profile || mode == BuildMode.release;
}

155
// Returns true if the given build mode can be used on emulators / simulators.
156 157 158 159 160
bool isEmulatorBuildMode(BuildMode mode) {
  return mode == BuildMode.debug ||
    mode == BuildMode.dynamicRelease ||
    mode == BuildMode.dynamicProfile;
}
161

162
enum HostPlatform {
163 164
  darwin_x64,
  linux_x64,
165
  windows_x64,
166 167 168
}

String getNameForHostPlatform(HostPlatform platform) {
169 170
  switch (platform) {
    case HostPlatform.darwin_x64:
171
      return 'darwin-x64';
172
    case HostPlatform.linux_x64:
173
      return 'linux-x64';
174 175
    case HostPlatform.windows_x64:
      return 'windows-x64';
176 177
  }
  assert(false);
pq's avatar
pq committed
178
  return null;
179 180 181
}

enum TargetPlatform {
182
  android_arm,
183
  android_arm64,
184
  android_x64,
185
  android_x86,
186
  ios,
187
  darwin_x64,
188
  linux_x64,
189 190
  windows_x64,
  fuchsia,
191
  tester,
192 193
}

194 195 196 197 198 199 200 201 202
/// iOS target device architecture.
//
// TODO(cbracken): split TargetPlatform.ios into ios_armv7, ios_arm64.
enum IOSArch {
  armv7,
  arm64,
}

/// The default set of iOS device architectures to build for.
203
const List<IOSArch> defaultIOSArchs = <IOSArch>[
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
  IOSArch.arm64,
];

String getNameForIOSArch(IOSArch arch) {
  switch (arch) {
    case IOSArch.armv7:
      return 'armv7';
    case IOSArch.arm64:
      return 'arm64';
  }
  assert(false);
  return null;
}

IOSArch getIOSArchForName(String arch) {
  switch (arch) {
    case 'armv7':
      return IOSArch.armv7;
    case 'arm64':
      return IOSArch.arm64;
  }
  assert(false);
  return null;
}

229
String getNameForTargetPlatform(TargetPlatform platform) {
230 231
  switch (platform) {
    case TargetPlatform.android_arm:
232
      return 'android-arm';
233 234
    case TargetPlatform.android_arm64:
      return 'android-arm64';
235
    case TargetPlatform.android_x64:
236
      return 'android-x64';
237
    case TargetPlatform.android_x86:
238
      return 'android-x86';
239
    case TargetPlatform.ios:
240
      return 'ios';
241
    case TargetPlatform.darwin_x64:
242
      return 'darwin-x64';
243
    case TargetPlatform.linux_x64:
244
      return 'linux-x64';
245 246
    case TargetPlatform.windows_x64:
      return 'windows-x64';
247 248
    case TargetPlatform.fuchsia:
      return 'fuchsia';
249 250
    case TargetPlatform.tester:
      return 'flutter-tester';
251 252
  }
  assert(false);
pq's avatar
pq committed
253
  return null;
254 255
}

256 257 258 259
TargetPlatform getTargetPlatformForName(String platform) {
  switch (platform) {
    case 'android-arm':
      return TargetPlatform.android_arm;
260 261
    case 'android-arm64':
      return TargetPlatform.android_arm64;
262 263 264 265 266 267 268 269 270 271 272
    case 'android-x64':
      return TargetPlatform.android_x64;
    case 'android-x86':
      return TargetPlatform.android_x86;
    case 'ios':
      return TargetPlatform.ios;
    case 'darwin-x64':
      return TargetPlatform.darwin_x64;
    case 'linux-x64':
      return TargetPlatform.linux_x64;
  }
pq's avatar
pq committed
273
  assert(platform != null);
274 275 276
  return null;
}

277
HostPlatform getCurrentHostPlatform() {
278
  if (platform.isMacOS)
279
    return HostPlatform.darwin_x64;
280
  if (platform.isLinux)
281
    return HostPlatform.linux_x64;
282 283
  if (platform.isWindows)
    return HostPlatform.windows_x64;
284

285
  printError('Unsupported host platform, defaulting to Linux');
286 287

  return HostPlatform.linux_x64;
288
}
289 290 291

/// Returns the top-level build output directory.
String getBuildDirectory() {
292 293
  // TODO(johnmccutchan): Stop calling this function as part of setting
  // up command line argument processing.
294
  if (context == null || config == null)
295 296
    return 'build';

297
  final String buildDir = config.getValue('build-dir') ?? 'build';
298
  if (fs.path.isAbsolute(buildDir)) {
299
    throw Exception(
300 301 302 303 304 305 306
        'build-dir config setting in ${config.configPath} must be relative');
  }
  return buildDir;
}

/// Returns the Android build output directory.
String getAndroidBuildDirectory() {
307
  // TODO(cbracken): move to android subdir.
308 309 310 311 312
  return getBuildDirectory();
}

/// Returns the AOT build output directory.
String getAotBuildDirectory() {
313
  return fs.path.join(getBuildDirectory(), 'aot');
314 315 316 317
}

/// Returns the asset build output directory.
String getAssetBuildDirectory() {
318
  return fs.path.join(getBuildDirectory(), 'flutter_assets');
319 320 321 322
}

/// Returns the iOS build output directory.
String getIosBuildDirectory() {
323
  return fs.path.join(getBuildDirectory(), 'ios');
324
}
325 326 327 328 329 330

/// Returns directory used by incremental compiler (IKG - incremental kernel
/// generator) to store cached intermediate state.
String getIncrementalCompilerByteStoreDirectory() {
  return fs.path.join(getBuildDirectory(), 'ikg_byte_store');
}