windows.dart 6.81 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import '../../artifacts.dart';
import '../../base/file_system.dart';
7
import '../../build_info.dart';
8
import '../build_system.dart';
9 10 11
import '../depfile.dart';
import '../exceptions.dart';
import 'assets.dart';
12
import 'common.dart';
13 14 15 16 17 18 19 20 21 22 23 24
import 'desktop.dart';
import 'icon_tree_shaker.dart';

/// The only files/subdirectories we care about.
const List<String> _kWindowsArtifacts = <String>[
  'flutter_windows.dll',
  'flutter_windows.dll.exp',
  'flutter_windows.dll.lib',
  'flutter_windows.dll.pdb',
  'flutter_export.h',
  'flutter_messenger.h',
  'flutter_plugin_registrar.h',
25
  'flutter_texture_registrar.h',
26 27 28 29
  'flutter_windows.h',
];

const String _kWindowsDepfile = 'windows_engine_sources.d';
30 31

/// Copies the Windows desktop embedding files to the copy directory.
32
class UnpackWindows extends Target {
33 34 35
  const UnpackWindows(this.targetPlatform);

  final TargetPlatform targetPlatform;
36 37 38 39 40 41 42 43 44 45

  @override
  String get name => 'unpack_windows';

  @override
  List<Source> get inputs => const <Source>[
    Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/windows.dart'),
  ];

  @override
46 47 48 49
  List<Source> get outputs => const <Source>[];

  @override
  List<String> get depfiles => const <String>[_kWindowsDepfile];
50 51 52 53 54

  @override
  List<Target> get dependencies => const <Target>[];

  @override
55
  Future<void> build(Environment environment) async {
56 57 58 59
    final String? buildModeEnvironment = environment.defines[kBuildMode];
    if (buildModeEnvironment == null) {
      throw MissingDefineException(kBuildMode, name);
    }
60
    final BuildMode buildMode = BuildMode.fromCliName(buildModeEnvironment);
61 62 63
    final String engineSourcePath = environment.artifacts
      .getArtifactPath(
        Artifact.windowsDesktopPath,
64
        platform: targetPlatform,
65 66 67 68 69
        mode: buildMode,
      );
    final String clientSourcePath = environment.artifacts
      .getArtifactPath(
        Artifact.windowsCppClientWrapper,
70
        platform: targetPlatform,
71 72
        mode: buildMode,
      );
73 74
    final Directory outputDirectory = environment.fileSystem.directory(
      environment.fileSystem.path.join(
75 76 77
        environment.projectDir.path,
        'windows',
        'flutter',
78 79 80 81 82 83
        'ephemeral',
      ),
    );
    final Depfile depfile = unpackDesktopArtifacts(
      fileSystem: environment.fileSystem,
      artifacts: _kWindowsArtifacts,
84
      engineSourcePath: engineSourcePath,
85
      outputDirectory: outputDirectory,
86
      clientSourcePaths: <String>[clientSourcePath],
87 88
      icuDataPath: environment.artifacts.getArtifactPath(
        Artifact.icuData,
89
        platform: targetPlatform,
90
      )
91
    );
92
    environment.depFileService.writeToFile(
93 94 95 96 97 98
      depfile,
      environment.buildDir.childFile(_kWindowsDepfile),
    );
  }
}

99 100
/// Creates a bundle for the Windows desktop target.
abstract class BundleWindowsAssets extends Target {
101 102 103
  const BundleWindowsAssets(this.targetPlatform);

  final TargetPlatform targetPlatform;
104 105

  @override
106 107 108
  List<Target> get dependencies => <Target>[
    const KernelSnapshot(),
    UnpackWindows(targetPlatform),
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
  ];

  @override
  List<Source> get inputs => const <Source>[
    Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/windows.dart'),
    Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
    ...IconTreeShaker.inputs,
  ];

  @override
  List<String> get depfiles => const <String>[
    'flutter_assets.d',
  ];

  @override
  Future<void> build(Environment environment) async {
125 126
    final String? buildModeEnvironment = environment.defines[kBuildMode];
    if (buildModeEnvironment == null) {
127
      throw MissingDefineException(kBuildMode, 'bundle_windows_assets');
128
    }
129
    final BuildMode buildMode = BuildMode.fromCliName(buildModeEnvironment);
130 131 132 133 134 135 136 137 138 139
    final Directory outputDirectory = environment.outputDir
      .childDirectory('flutter_assets');
    if (!outputDirectory.existsSync()) {
      outputDirectory.createSync();
    }

    // Only copy the kernel blob in debug mode.
    if (buildMode == BuildMode.debug) {
      environment.buildDir.childFile('app.dill')
        .copySync(outputDirectory.childFile('kernel_blob.bin').path);
140
    }
141 142 143
    final Depfile depfile = await copyAssets(
      environment,
      outputDirectory,
144
      targetPlatform: targetPlatform,
145
    );
146
    environment.depFileService.writeToFile(
147 148 149
      depfile,
      environment.buildDir.childFile('flutter_assets.d'),
    );
150 151
  }
}
152 153 154 155

/// A wrapper for AOT compilation that copies app.so into the output directory.
class WindowsAotBundle extends Target {
  /// Create a [WindowsAotBundle] wrapper for [aotTarget].
156
  const WindowsAotBundle(this.aotTarget);
157 158 159 160 161

  /// The [AotElfBase] subclass that produces the app.so.
  final AotElfBase aotTarget;

  @override
162
  String get name => 'windows_aot_bundle';
163 164 165 166 167 168 169

  @override
  List<Source> get inputs => const <Source>[
    Source.pattern('{BUILD_DIR}/app.so'),
  ];

  @override
170
  List<Source> get outputs =>
171 172 173 174 175 176 177 178 179 180 181 182
    const <Source>[
      Source.pattern('{OUTPUT_DIR}/windows/app.so'),
    ];

  @override
  List<Target> get dependencies => <Target>[
    aotTarget,
  ];

  @override
  Future<void> build(Environment environment) async {
    final File outputFile = environment.buildDir.childFile('app.so');
183
    final Directory outputDirectory = environment.outputDir.childDirectory('windows');
184 185 186 187 188 189 190 191
    if (!outputDirectory.existsSync()) {
      outputDirectory.createSync(recursive: true);
    }
    outputFile.copySync(outputDirectory.childFile('app.so').path);
  }
}

class ReleaseBundleWindowsAssets extends BundleWindowsAssets {
192
  const ReleaseBundleWindowsAssets(super.targetPlatform);
193 194

  @override
195
  String get name => 'release_bundle_${getNameForTargetPlatform(targetPlatform)}_assets';
196 197 198 199 200 201 202

  @override
  List<Source> get outputs => const <Source>[];

  @override
  List<Target> get dependencies => <Target>[
    ...super.dependencies,
203
    WindowsAotBundle(AotElfRelease(targetPlatform)),
204 205 206 207
  ];
}

class ProfileBundleWindowsAssets extends BundleWindowsAssets {
208
  const ProfileBundleWindowsAssets(super.targetPlatform);
209 210

  @override
211
  String get name => 'profile_bundle_${getNameForTargetPlatform(targetPlatform)}_assets';
212 213 214 215 216 217 218

  @override
  List<Source> get outputs => const <Source>[];

  @override
  List<Target> get dependencies => <Target>[
    ...super.dependencies,
219
    WindowsAotBundle(AotElfProfile(targetPlatform)),
220 221 222 223
  ];
}

class DebugBundleWindowsAssets extends BundleWindowsAssets {
224
  const DebugBundleWindowsAssets(super.targetPlatform);
225 226

  @override
227
  String get name => 'debug_bundle_${getNameForTargetPlatform(targetPlatform)}_assets';
228 229 230 231 232 233 234 235 236 237 238

  @override
  List<Source> get inputs => <Source>[
    const Source.pattern('{BUILD_DIR}/app.dill'),
  ];

  @override
  List<Source> get outputs => <Source>[
    const Source.pattern('{OUTPUT_DIR}/flutter_assets/kernel_blob.bin'),
  ];
}