| // Copyright 2014 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Do not add package imports to this file. | |
| import 'dart:convert'; // flutter_ignore: dart_convert_import. | |
| import 'dart:io'; // flutter_ignore: dart_io_import. | |
| /// Executes the required Flutter tasks for a desktop build. | |
| Future<void> main(List<String> arguments) async { | |
| final String targetPlatform = arguments[0]; | |
| final String buildMode = arguments[1].toLowerCase(); | |
| final String? dartDefines = Platform.environment['DART_DEFINES']; | |
| final dartObfuscation = Platform.environment['DART_OBFUSCATION'] == 'true'; | |
| final String? frontendServerStarterPath = Platform.environment['FRONTEND_SERVER_STARTER_PATH']; | |
| final String? extraFrontEndOptions = Platform.environment['EXTRA_FRONT_END_OPTIONS']; | |
| final String? extraGenSnapshotOptions = Platform.environment['EXTRA_GEN_SNAPSHOT_OPTIONS']; | |
| final String? flutterEngine = Platform.environment['FLUTTER_ENGINE']; | |
| final String? flutterRoot = Platform.environment['FLUTTER_ROOT']; | |
| final String flutterTarget = | |
| Platform.environment['FLUTTER_TARGET'] ?? pathJoin(<String>['lib', 'main.dart']); | |
| final String? codeSizeDirectory = Platform.environment['CODE_SIZE_DIRECTORY']; | |
| final String? flavor = Platform.environment['FLAVOR']; | |
| final String? localEngine = Platform.environment['LOCAL_ENGINE']; | |
| final String? localEngineHost = Platform.environment['LOCAL_ENGINE_HOST']; | |
| final String? projectDirectory = Platform.environment['PROJECT_DIR']; | |
| final String? splitDebugInfo = Platform.environment['SPLIT_DEBUG_INFO']; | |
| final String? buildName = Platform.environment['BUILD_NAME']; | |
| final String? buildNumber = Platform.environment['BUILD_NUMBER']; | |
| final trackWidgetCreation = Platform.environment['TRACK_WIDGET_CREATION'] == 'true'; | |
| final treeShakeIcons = Platform.environment['TREE_SHAKE_ICONS'] == 'true'; | |
| final verbose = Platform.environment['VERBOSE_SCRIPT_LOGGING'] == 'true'; | |
| final prefixedErrors = Platform.environment['PREFIXED_ERROR_LOGGING'] == 'true'; | |
| if (projectDirectory == null) { | |
| stderr.write( | |
| 'PROJECT_DIR environment variable must be set to the location of Flutter project to be built.', | |
| ); | |
| exit(1); | |
| } | |
| if (flutterRoot == null || flutterRoot.isEmpty) { | |
| stderr.write( | |
| 'FLUTTER_ROOT environment variable must be set to the location of the Flutter SDK.', | |
| ); | |
| exit(1); | |
| } | |
| Directory.current = projectDirectory; | |
| if (localEngine != null && !localEngine.contains(buildMode)) { | |
| stderr.write(''' | |
| ERROR: Requested build with Flutter local engine at '$localEngine' | |
| This engine is not compatible with FLUTTER_BUILD_MODE: '$buildMode'. | |
| You can fix this by updating the LOCAL_ENGINE environment variable, or | |
| by running: | |
| flutter build <platform> --local-engine=<platform>_$buildMode --local-engine-host=host_$buildMode | |
| or | |
| flutter build <platform> --local-engine=<platform>_${buildMode}_unopt --local-engine-host=host_${buildMode}_unopt | |
| ======================================================================== | |
| '''); | |
| exit(1); | |
| } | |
| if (localEngineHost != null && !localEngineHost.contains(buildMode)) { | |
| stderr.write(''' | |
| ERROR: Requested build with Flutter local engine host at '$localEngineHost' | |
| This engine is not compatible with FLUTTER_BUILD_MODE: '$buildMode'. | |
| You can fix this by updating the LOCAL_ENGINE_HOST environment variable, or | |
| by running: | |
| flutter build <platform> --local-engine=<platform>_$buildMode --local-engine-host=host_$buildMode | |
| or | |
| flutter build <platform> --local-engine=<platform>_$buildMode --local-engine-host=host_${buildMode}_unopt | |
| ======================================================================== | |
| '''); | |
| exit(1); | |
| } | |
| final String flutterExecutable = pathJoin(<String>[ | |
| flutterRoot, | |
| 'bin', | |
| if (Platform.isWindows) 'flutter.bat' else 'flutter', | |
| ]); | |
| final target = targetPlatform.startsWith('darwin') | |
| ? '${buildMode}_macos_bundle_flutter_assets' | |
| : '${buildMode}_bundle_${targetPlatform}_assets'; | |
| final Process assembleProcess = await Process.start(flutterExecutable, <String>[ | |
| if (verbose) '--verbose', | |
| if (prefixedErrors) '--prefixed-errors', | |
| if (flutterEngine != null) '--local-engine-src-path=$flutterEngine', | |
| if (localEngine != null) '--local-engine=$localEngine', | |
| if (localEngineHost != null) '--local-engine-host=$localEngineHost', | |
| 'assemble', | |
| '--no-version-check', | |
| '--output=build', | |
| '-dTargetPlatform=$targetPlatform', | |
| '-dTrackWidgetCreation=$trackWidgetCreation', | |
| '-dBuildMode=$buildMode', | |
| '-dTargetFile=$flutterTarget', | |
| '-dTreeShakeIcons=$treeShakeIcons', | |
| '-dDartObfuscation=$dartObfuscation', | |
| if (codeSizeDirectory != null) '-dCodeSizeDirectory=$codeSizeDirectory', | |
| if (flavor != null && flavor.isNotEmpty) '-dFlavor=$flavor', | |
| if (splitDebugInfo != null) '-dSplitDebugInfo=$splitDebugInfo', | |
| if (buildName != null) '-dBuildName=$buildName', | |
| if (buildNumber != null) '-dBuildNumber=$buildNumber', | |
| if (dartDefines != null) '--DartDefines=$dartDefines', | |
| if (extraGenSnapshotOptions != null) '--ExtraGenSnapshotOptions=$extraGenSnapshotOptions', | |
| if (frontendServerStarterPath != null) '-dFrontendServerStarterPath=$frontendServerStarterPath', | |
| if (extraFrontEndOptions != null) '--ExtraFrontEndOptions=$extraFrontEndOptions', | |
| target, | |
| ]); | |
| assembleProcess.stdout | |
| .transform(utf8.decoder) | |
| .transform(const LineSplitter()) | |
| .listen(stdout.writeln); | |
| assembleProcess.stderr | |
| .transform(utf8.decoder) | |
| .transform(const LineSplitter()) | |
| .listen(stderr.writeln); | |
| if (await assembleProcess.exitCode != 0) { | |
| exit(1); | |
| } | |
| } | |
| /// Perform a simple path join on the segments based on the current platform. | |
| /// | |
| /// Does not normalize paths that have repeated separators. | |
| String pathJoin(List<String> segments) { | |
| final separator = Platform.isWindows ? r'\' : '/'; | |
| return segments.join(separator); | |
| } |