Switch Windows to CMake (#60629)
* First pass at CMake files; untested
* First pass of adding CMake generation logic on Windows
* Misc fixes
* Get bundling working, start incoprorating CMake build into tool
* Fix debug, exe name.
* Add resources
* Move cmake.dart
* Rip out all the vcxproj/solution plumbing
* Fix plugin cmake generation
* Build with cmake rather than calling VS directly
* Adjust Windows plugin template to match standard header directory structure
* Pass config selection when building
* Partially fix multi-config handling
* Rev template version
* Share the CMake generation instead of splitting it out
* VS build/run cycle works, with slightly awkward requirement to always build all
* Update manifest
* Plugin template fixes
* Minor adjustments
* Build install as part of build command, instead of separately
* Test cleanup
* Update Linux test for adjusted generated CMake approach
* Plugin test typo fix
* Add missing stub file for project test
* Add a constant for VS generator
diff --git a/packages/flutter_tools/bin/vs_build.bat b/packages/flutter_tools/bin/vs_build.bat
deleted file mode 100644
index ef7129d..0000000
--- a/packages/flutter_tools/bin/vs_build.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-@ECHO off
-REM Copyright 2014 The Flutter Authors. All rights reserved.
-REM Use of this source code is governed by a BSD-style license that can be
-REM found in the LICENSE file.
-
-REM Calls vcvars64.bat to configure a command-line build environment, then builds
-REM a project with msbuild.
-@echo off
-
-set VCVARS=%~1
-set PROJECT=%~2
-set CONFIG=%~3
-
-call "%VCVARS%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-msbuild "%PROJECT%" /p:Configuration=%CONFIG%
diff --git a/packages/flutter_tools/lib/src/linux/cmake.dart b/packages/flutter_tools/lib/src/cmake.dart
similarity index 63%
rename from packages/flutter_tools/lib/src/linux/cmake.dart
rename to packages/flutter_tools/lib/src/cmake.dart
index 8a50066..e57b974 100644
--- a/packages/flutter_tools/lib/src/linux/cmake.dart
+++ b/packages/flutter_tools/lib/src/cmake.dart
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import '../project.dart';
+import 'project.dart';
-/// Extracts the `BINARY_NAME` from a Linux project CMake file.
+/// Extracts the `BINARY_NAME` from a project's CMake file.
///
/// Returns `null` if it cannot be found.
-String getCmakeExecutableName(LinuxProject project) {
+String getCmakeExecutableName(CmakeBasedProject project) {
if (!project.cmakeFile.existsSync()) {
return null;
}
@@ -21,24 +21,30 @@
return null;
}
+String _escapeBackslashes(String s) {
+ return s.replaceAll(r'\', r'\\');
+}
+
/// Writes a generated CMake configuration file for [project], including
/// variables expected by the build template and an environment variable list
/// for calling back into Flutter.
-void writeGeneratedCmakeConfig(String flutterRoot, LinuxProject project, Map<String, String> environment) {
+void writeGeneratedCmakeConfig(String flutterRoot, CmakeBasedProject project, Map<String, String> environment) {
// Only a limited set of variables are needed by the CMake files themselves,
// the rest are put into a list to pass to the re-entrant build step.
+ final String escapedFlutterRoot = _escapeBackslashes(flutterRoot);
+ final String escapedProjectDir = _escapeBackslashes(project.parent.directory.path);
final StringBuffer buffer = StringBuffer('''
# Generated code do not commit.
-set(FLUTTER_ROOT "$flutterRoot")
-set(PROJECT_DIR "${project.project.directory.path}")
+file(TO_CMAKE_PATH "$escapedFlutterRoot" FLUTTER_ROOT)
+file(TO_CMAKE_PATH "$escapedProjectDir" PROJECT_DIR)
# Environment variables to pass to tool_backend.sh
list(APPEND FLUTTER_TOOL_ENVIRONMENT
- "FLUTTER_ROOT=\\"\${FLUTTER_ROOT}\\""
- "PROJECT_DIR=\\"\${PROJECT_DIR}\\""
+ "FLUTTER_ROOT=\\"$escapedFlutterRoot\\""
+ "PROJECT_DIR=\\"$escapedProjectDir\\""
''');
for (final String key in environment.keys) {
- final String value = environment[key];
+ final String value = _escapeBackslashes(environment[key]);
buffer.writeln(' "$key=\\"$value\\""');
}
buffer.writeln(')');
diff --git a/packages/flutter_tools/lib/src/linux/application_package.dart b/packages/flutter_tools/lib/src/linux/application_package.dart
index d1a579f..acc80f2 100644
--- a/packages/flutter_tools/lib/src/linux/application_package.dart
+++ b/packages/flutter_tools/lib/src/linux/application_package.dart
@@ -7,9 +7,9 @@
import '../application_package.dart';
import '../base/file_system.dart';
import '../build_info.dart';
+import '../cmake.dart';
import '../globals.dart' as globals;
import '../project.dart';
-import 'cmake.dart';
abstract class LinuxApp extends ApplicationPackage {
LinuxApp({@required String projectBundleId}) : super(id: projectBundleId);
@@ -52,7 +52,7 @@
}
class BuildableLinuxApp extends LinuxApp {
- BuildableLinuxApp({this.project}) : super(projectBundleId: project.project.manifest.appName);
+ BuildableLinuxApp({this.project}) : super(projectBundleId: project.parent.manifest.appName);
final LinuxProject project;
@@ -68,5 +68,5 @@
}
@override
- String get name => project.project.manifest.appName;
+ String get name => project.parent.manifest.appName;
}
diff --git a/packages/flutter_tools/lib/src/linux/build_linux.dart b/packages/flutter_tools/lib/src/linux/build_linux.dart
index 2ff8690..fbbbf9e 100644
--- a/packages/flutter_tools/lib/src/linux/build_linux.dart
+++ b/packages/flutter_tools/lib/src/linux/build_linux.dart
@@ -10,10 +10,10 @@
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
+import '../cmake.dart';
import '../globals.dart' as globals;
import '../plugins.dart';
import '../project.dart';
-import 'cmake.dart';
/// Builds the Linux project through the Makefile.
Future<void> buildLinux(
@@ -39,7 +39,7 @@
}
writeGeneratedCmakeConfig(Cache.flutterRoot, linuxProject, environmentConfig);
- createPluginSymlinks(linuxProject.project);
+ createPluginSymlinks(linuxProject.parent);
final Status status = globals.logger.startProgress(
'Building Linux application...',
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index 97e3406..d8b32d9 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -6,6 +6,7 @@
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
+import 'package:path/path.dart' as path; // ignore: package_path_import
import 'package:yaml/yaml.dart';
import 'android/gradle.dart';
@@ -17,8 +18,6 @@
import 'globals.dart' as globals;
import 'platform_plugins.dart';
import 'project.dart';
-import 'windows/property_sheet.dart';
-import 'windows/visual_studio_solution_utils.dart';
void _renderTemplateToFile(String template, dynamic context, String filePath) {
final String renderedTemplate = globals.templateRenderer
@@ -801,7 +800,7 @@
#include "generated_plugin_registrant.h"
{{#plugins}}
-#include <{{filename}}.h>
+#include <{{name}}/{{filename}}.h>
{{/plugins}}
void RegisterPlugins(flutter::PluginRegistry* registry) {
@@ -848,7 +847,7 @@
}
''';
-const String _linuxPluginCmakefileTemplate = r'''
+const String _pluginCmakefileTemplate = r'''
#
# Generated file, do not edit.
#
@@ -862,7 +861,7 @@
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory({{pluginsDir}}/${plugin}/linux plugins/${plugin})
+ add_subdirectory({{pluginsDir}}/${plugin}/{{os}} plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
@@ -917,6 +916,7 @@
// that file's directory.
final String makefileDirPath = project.linux.cmakeFile.parent.absolute.path;
final Map<String, dynamic> context = <String, dynamic>{
+ 'os': 'linux',
'plugins': linuxPlugins,
'pluginsDir': globals.fs.path.relative(
project.linux.pluginSymlinkDirectory.absolute.path,
@@ -924,7 +924,7 @@
),
};
await _writeLinuxPluginRegistrant(project.linux.managedDirectory, context);
- await _writeLinuxPluginCmakefile(project.linux.generatedPluginCmakeFile, context);
+ await _writePluginCmakefile(project.linux.generatedPluginCmakeFile, context);
}
Future<void> _writeLinuxPluginRegistrant(Directory destination, Map<String, dynamic> templateContext) async {
@@ -941,9 +941,9 @@
);
}
-Future<void> _writeLinuxPluginCmakefile(File destinationFile, Map<String, dynamic> templateContext) async {
+Future<void> _writePluginCmakefile(File destinationFile, Map<String, dynamic> templateContext) async {
_renderTemplateToFile(
- _linuxPluginCmakefileTemplate,
+ _pluginCmakefileTemplate,
templateContext,
destinationFile.path,
);
@@ -984,11 +984,22 @@
Future<void> _writeWindowsPluginFiles(FlutterProject project, List<Plugin> plugins) async {
final List<Plugin>nativePlugins = _filterNativePlugins(plugins, WindowsPlugin.kConfigKey);
final List<Map<String, dynamic>> windowsPlugins = _extractPlatformMaps(nativePlugins, WindowsPlugin.kConfigKey);
+ // The generated file is checked in, so can't use absolute paths. It is
+ // included by the main CMakeLists.txt, so relative paths must be relative to
+ // that file's directory.
+ final String makefileDirPath = project.windows.cmakeFile.parent.absolute.path;
+ final path.Context cmakePathContext = path.Context(style: path.Style.posix);
+ final List<String> relativePathComponents = globals.fs.path.split(globals.fs.path.relative(
+ project.windows.pluginSymlinkDirectory.absolute.path,
+ from: makefileDirPath,
+ ));
final Map<String, dynamic> context = <String, dynamic>{
+ 'os': 'windows',
'plugins': windowsPlugins,
+ 'pluginsDir': cmakePathContext.joinAll(relativePathComponents),
};
await _writeCppPluginRegistrant(project.windows.managedDirectory, context);
- await _writeWindowsPluginProperties(project.windows, windowsPlugins);
+ await _writePluginCmakefile(project.windows.generatedPluginCmakeFile, context);
}
Future<void> _writeCppPluginRegistrant(Directory destination, Map<String, dynamic> templateContext) async {
@@ -1005,20 +1016,6 @@
);
}
-Future<void> _writeWindowsPluginProperties(WindowsProject project, List<Map<String, dynamic>> windowsPlugins) async {
- final List<String> pluginLibraryFilenames = windowsPlugins.map(
- (Map<String, dynamic> plugin) => '${plugin['name']}_plugin.lib').toList();
- // Use paths relative to the VS project directory.
- final String projectDir = project.vcprojFile.parent.path;
- final String symlinkDirPath = project.pluginSymlinkDirectory.path.substring(projectDir.length + 1);
- final List<String> pluginIncludePaths = windowsPlugins.map((Map<String, dynamic> plugin) =>
- globals.fs.path.join(symlinkDirPath, plugin['name'] as String, 'windows')).toList();
- project.generatedPluginPropertySheetFile.writeAsStringSync(PropertySheet(
- includePaths: pluginIncludePaths,
- libraryDependencies: pluginLibraryFilenames,
- ).toString());
-}
-
Future<void> _writeWebPluginRegistrant(FlutterProject project, List<Plugin> plugins) async {
final List<Map<String, dynamic>> webPlugins = _extractPlatformMaps(plugins, WebPlugin.kConfigKey);
final Map<String, dynamic> context = <String, dynamic>{
@@ -1159,9 +1156,6 @@
}
if (featureFlags.isWindowsEnabled && project.windows.existsSync()) {
await _writeWindowsPluginFiles(project, plugins);
-
- final List<Plugin> nativePlugins = _filterNativePlugins(plugins, WindowsPlugin.kConfigKey);
- await VisualStudioSolutionUtils(project: project.windows, fileSystem: globals.fs).updatePlugins(nativePlugins);
}
for (final XcodeBasedProject subproject in <XcodeBasedProject>[project.ios, project.macos]) {
if (!project.isModule && (!checkProjects || subproject.existsSync())) {
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 2fe310c..c3b566e 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -329,6 +329,27 @@
File get podManifestLock;
}
+/// Represents a CMake-based sub-project.
+///
+/// This defines interfaces common to Windows and Linux projects.
+abstract class CmakeBasedProject {
+ /// The parent of this project.
+ FlutterProject get parent;
+
+ /// Whether the subproject (either Windows or Linux) exists in the Flutter project.
+ bool existsSync();
+
+ /// The native project CMake specification.
+ File get cmakeFile;
+
+ /// Contains definitions for FLUTTER_ROOT, LOCAL_ENGINE, and more flags for
+ /// the build.
+ File get generatedCmakeConfigFile;
+
+ /// Includable CMake with rules and variables for plugin builds.
+ File get generatedPluginCmakeFile;
+}
+
/// Represents the iOS sub-project of a Flutter project.
///
/// Instances will reflect the contents of the `ios/` sub-folder of
@@ -995,18 +1016,28 @@
}
/// The Windows sub project
-class WindowsProject extends FlutterProjectPlatform {
- WindowsProject._(this.project);
+class WindowsProject extends FlutterProjectPlatform implements CmakeBasedProject {
+ WindowsProject._(this.parent);
- final FlutterProject project;
+ @override
+ final FlutterProject parent;
@override
String get pluginConfigKey => WindowsPlugin.kConfigKey;
@override
- bool existsSync() => _editableDirectory.existsSync() && solutionFile.existsSync();
+ bool existsSync() => _editableDirectory.existsSync() && cmakeFile.existsSync();
- Directory get _editableDirectory => project.directory.childDirectory('windows');
+ @override
+ File get cmakeFile => _editableDirectory.childFile('CMakeLists.txt');
+
+ @override
+ File get generatedCmakeConfigFile => ephemeralDirectory.childFile('generated_config.cmake');
+
+ @override
+ File get generatedPluginCmakeFile => managedDirectory.childFile('generated_plugins.cmake');
+
+ Directory get _editableDirectory => parent.directory.childDirectory('windows');
/// The directory in the project that is managed by Flutter. As much as
/// possible, files that are edited by Flutter tooling after initial project
@@ -1018,24 +1049,6 @@
/// checked in should live here.
Directory get ephemeralDirectory => managedDirectory.childDirectory('ephemeral');
- /// Contains definitions for FLUTTER_ROOT, LOCAL_ENGINE, and more flags for
- /// the build.
- File get generatedPropertySheetFile => ephemeralDirectory.childFile('Generated.props');
-
- /// Contains configuration to add plugins to the build.
- File get generatedPluginPropertySheetFile => managedDirectory.childFile('GeneratedPlugins.props');
-
- // The MSBuild project file.
- File get vcprojFile => _editableDirectory.childFile('Runner.vcxproj');
-
- // The MSBuild solution file.
- File get solutionFile => _editableDirectory.childFile('Runner.sln');
-
- /// The file where the VS build will write the name of the built app.
- ///
- /// Ideally this will be replaced in the future with inspection of the project.
- File get nameFile => ephemeralDirectory.childFile('exe_filename');
-
/// The directory to write plugin symlinks.
Directory get pluginSymlinkDirectory => ephemeralDirectory.childDirectory('.plugin_symlinks');
@@ -1043,15 +1056,16 @@
}
/// The Linux sub project.
-class LinuxProject extends FlutterProjectPlatform {
- LinuxProject._(this.project);
+class LinuxProject extends FlutterProjectPlatform implements CmakeBasedProject {
+ LinuxProject._(this.parent);
- final FlutterProject project;
+ @override
+ final FlutterProject parent;
@override
String get pluginConfigKey => LinuxPlugin.kConfigKey;
- Directory get _editableDirectory => project.directory.childDirectory('linux');
+ Directory get _editableDirectory => parent.directory.childDirectory('linux');
/// The directory in the project that is managed by Flutter. As much as
/// possible, files that are edited by Flutter tooling after initial project
@@ -1066,14 +1080,13 @@
@override
bool existsSync() => _editableDirectory.existsSync();
- /// The Linux project CMake specification.
+ @override
File get cmakeFile => _editableDirectory.childFile('CMakeLists.txt');
- /// Contains definitions for FLUTTER_ROOT, LOCAL_ENGINE, and more flags for
- /// the build.
+ @override
File get generatedCmakeConfigFile => ephemeralDirectory.childFile('generated_config.cmake');
- /// Includable CMake with rules and variables for plugin builds.
+ @override
File get generatedPluginCmakeFile => managedDirectory.childFile('generated_plugins.cmake');
/// The directory to write plugin symlinks.
diff --git a/packages/flutter_tools/lib/src/windows/application_package.dart b/packages/flutter_tools/lib/src/windows/application_package.dart
index bd93c80..8051b06 100644
--- a/packages/flutter_tools/lib/src/windows/application_package.dart
+++ b/packages/flutter_tools/lib/src/windows/application_package.dart
@@ -5,10 +5,10 @@
import 'package:meta/meta.dart';
import '../application_package.dart';
-import '../base/common.dart';
import '../base/file_system.dart';
import '../base/utils.dart';
import '../build_info.dart';
+import '../cmake.dart';
import '../globals.dart' as globals;
import '../project.dart';
@@ -55,24 +55,21 @@
class BuildableWindowsApp extends WindowsApp {
BuildableWindowsApp({
@required this.project,
- }) : super(projectBundleId: project.project.manifest.appName);
+ }) : super(projectBundleId: project.parent.manifest.appName);
final WindowsProject project;
@override
String executable(BuildMode buildMode) {
- final File exeNameFile = project.nameFile;
- if (!exeNameFile.existsSync()) {
- throwToolExit('Failed to find Windows executable name');
- }
+ final String binaryName = getCmakeExecutableName(project);
return globals.fs.path.join(
getWindowsBuildDirectory(),
- 'x64',
+ 'runner',
toTitleCase(getNameForBuildMode(buildMode)),
- 'Runner',
- exeNameFile.readAsStringSync().trim());
+ '$binaryName.exe',
+ );
}
@override
- String get name => project.project.manifest.appName;
+ String get name => project.parent.manifest.appName;
}
diff --git a/packages/flutter_tools/lib/src/windows/build_windows.dart b/packages/flutter_tools/lib/src/windows/build_windows.dart
index 9a3f813..31a9967 100644
--- a/packages/flutter_tools/lib/src/windows/build_windows.dart
+++ b/packages/flutter_tools/lib/src/windows/build_windows.dart
@@ -10,18 +10,23 @@
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
+import '../cmake.dart';
import '../globals.dart' as globals;
import '../plugins.dart';
import '../project.dart';
-import 'property_sheet.dart';
import 'visual_studio.dart';
+// From https://cmake.org/cmake/help/v3.15/manual/cmake-generators.7.html#visual-studio-generators
+// This may need to become a getter on VisualStudio in the future to support
+// future major versions of Visual Studio.
+const String _cmakeVisualStudioGeneratorIdentifier = 'Visual Studio 16 2019';
+
/// Builds the Windows project using msbuild.
Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, {
String target,
VisualStudio visualStudioOverride,
}) async {
- if (!windowsProject.solutionFile.existsSync()) {
+ if (!windowsProject.cmakeFile.existsSync()) {
throwToolExit(
'No Windows desktop project configured. '
'See https://github.com/flutter/flutter/wiki/Desktop-shells#create '
@@ -43,8 +48,8 @@
}
// Ensure that necessary emphemeral files are generated and up to date.
- _writeGeneratedFlutterProperties(windowsProject, buildInfo, target);
- createPluginSymlinks(windowsProject.project);
+ _writeGeneratedFlutterConfig(windowsProject, buildInfo, target);
+ createPluginSymlinks(windowsProject.parent);
final VisualStudio visualStudio = visualStudioOverride ?? VisualStudio(
fileSystem: globals.fs,
@@ -52,57 +57,88 @@
logger: globals.logger,
processManager: globals.processManager,
);
- final String vcvarsScript = visualStudio.vcvarsPath;
- if (vcvarsScript == null) {
+ final String cmakePath = visualStudio.cmakePath;
+ if (cmakePath == null) {
throwToolExit('Unable to find suitable Visual Studio toolchain. '
'Please run `flutter doctor` for more details.');
}
- final String buildScript = globals.fs.path.join(
- Cache.flutterRoot,
- 'packages',
- 'flutter_tools',
- 'bin',
- 'vs_build.bat',
- );
-
- final String configuration = toTitleCase(getNameForBuildMode(buildInfo.mode ?? BuildMode.release));
- final String solutionPath = windowsProject.solutionFile.path;
- final Stopwatch sw = Stopwatch()..start();
+ final String buildModeName = getNameForBuildMode(buildInfo.mode ?? BuildMode.release);
+ final Directory buildDirectory = globals.fs.directory(getWindowsBuildDirectory());
final Status status = globals.logger.startProgress(
'Building Windows application...',
timeout: null,
);
+ try {
+ await _runCmakeGeneration(cmakePath, buildDirectory, windowsProject.cmakeFile.parent);
+ await _runBuild(cmakePath, buildDirectory, buildModeName);
+ } finally {
+ status.cancel();
+ }
+}
+
+Future<void> _runCmakeGeneration(String cmakePath, Directory buildDir, Directory sourceDir) async {
+ final Stopwatch sw = Stopwatch()..start();
+
+ await buildDir.create(recursive: true);
int result;
try {
- // Run the script with a relative path to the project using the enclosing
- // directory as the workingDirectory, to avoid hitting the limit on command
- // lengths in batch scripts if the absolute path to the project is long.
result = await processUtils.stream(
<String>[
- buildScript,
- vcvarsScript,
- globals.fs.path.basename(solutionPath),
- configuration,
+ cmakePath,
+ '-S',
+ sourceDir.path,
+ '-B',
+ buildDir.path,
+ '-G',
+ _cmakeVisualStudioGeneratorIdentifier,
+ ],
+ trace: true,
+ );
+ } on ArgumentError {
+ throwToolExit("cmake not found. Run 'flutter doctor' for more information.");
+ }
+ if (result != 0) {
+ throwToolExit('Unable to generate build files');
+ }
+ globals.flutterUsage.sendTiming('build', 'windows-cmake-generation', Duration(milliseconds: sw.elapsedMilliseconds));
+}
+
+Future<void> _runBuild(String cmakePath, Directory buildDir, String buildModeName) async {
+ final Stopwatch sw = Stopwatch()..start();
+
+ int result;
+ try {
+ result = await processUtils.stream(
+ <String>[
+ cmakePath,
+ '--build',
+ buildDir.path,
+ '--config',
+ toTitleCase(buildModeName),
+ '--target',
+ 'INSTALL',
+ if (globals.logger.isVerbose)
+ '--verbose'
],
environment: <String, String>{
if (globals.logger.isVerbose)
'VERBOSE_SCRIPT_LOGGING': 'true'
},
- workingDirectory: globals.fs.path.dirname(solutionPath),
trace: true,
);
- } finally {
- status.cancel();
+ } on ArgumentError {
+ throwToolExit("cmake not found. Run 'flutter doctor' for more information.");
}
if (result != 0) {
- throwToolExit('Build process failed. To view the stack trace, please run `flutter run -d windows -v`.');
+ final String verboseInstructions = globals.logger.isVerbose ? '' : ' To view the stack trace, please run `flutter run -d windows -v`.';
+ throwToolExit('Build process failed.$verboseInstructions');
}
- globals.flutterUsage.sendTiming('build', 'vs_build', Duration(milliseconds: sw.elapsedMilliseconds));
+ globals.flutterUsage.sendTiming('build', 'windows-cmake-build', Duration(milliseconds: sw.elapsedMilliseconds));
}
-/// Writes the generatedPropertySheetFile with the configuration for the given build.
-void _writeGeneratedFlutterProperties(
+/// Writes the generated CMake file with the configuration for the given build.
+void _writeGeneratedFlutterConfig(
WindowsProject windowsProject,
BuildInfo buildInfo,
String target,
@@ -110,7 +146,7 @@
final Map<String, String> environment = <String, String>{
'FLUTTER_ROOT': Cache.flutterRoot,
'FLUTTER_EPHEMERAL_DIR': windowsProject.ephemeralDirectory.path,
- 'PROJECT_DIR': windowsProject.project.directory.path,
+ 'PROJECT_DIR': windowsProject.parent.directory.path,
if (target != null)
'FLUTTER_TARGET': target,
...buildInfo.toEnvironmentConfig(),
@@ -121,10 +157,7 @@
environment['FLUTTER_ENGINE'] = globals.fs.path.dirname(globals.fs.path.dirname(engineOutPath));
environment['LOCAL_ENGINE'] = globals.fs.path.basename(engineOutPath);
}
-
- final File propsFile = windowsProject.generatedPropertySheetFile;
- propsFile.createSync(recursive: true);
- propsFile.writeAsStringSync(PropertySheet(environmentVariables: environment).toString());
+ writeGeneratedCmakeConfig(Cache.flutterRoot, windowsProject, environment);
}
// Checks the template version of [project] against the current template
diff --git a/packages/flutter_tools/lib/src/windows/property_sheet.dart b/packages/flutter_tools/lib/src/windows/property_sheet.dart
deleted file mode 100644
index e088485..0000000
--- a/packages/flutter_tools/lib/src/windows/property_sheet.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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.
-
-import 'package:xml/xml.dart' as xml;
-
-/// A utility class for building property sheet (.props) files for use
-/// with MSBuild/Visual Studio projects.
-class PropertySheet {
- /// Creates a PropertySheet with the given properties.
- const PropertySheet({
- this.environmentVariables,
- this.includePaths,
- this.libraryDependencies,
- });
-
- /// Variables to make available both as build macros and as environment
- /// variables for script steps.
- final Map<String, String> environmentVariables;
-
- /// Directories to search for headers.
- final List<String> includePaths;
-
- /// Libraries to link against.
- final List<String> libraryDependencies;
-
- @override
- String toString() {
- // See https://docs.microsoft.com/en-us/cpp/build/reference/vcxproj-file-structure#property-sheet-layout
-
- final xml.XmlBuilder builder = xml.XmlBuilder();
- builder.processing('xml', 'version="1.0" encoding="utf-8"');
- builder.element('Project', nest: () {
- builder.attribute('ToolsVersion', '4.0');
- builder.attribute(
- 'xmlns', 'http://schemas.microsoft.com/developer/msbuild/2003');
-
- builder.element('ImportGroup', nest: () {
- builder.attribute('Label', 'PropertySheets');
- });
- builder.element('PropertyGroup', nest: () {
- builder.attribute('Label', 'UserMacros');
-
- _addEnviromentVariableUserMacros(builder);
- });
- builder.element('PropertyGroup');
- builder.element('ItemDefinitionGroup', nest: () {
- _addIncludePaths(builder);
- _addLibraryDependencies(builder);
- });
- builder.element('ItemGroup', nest: () {
- _addEnvironmentVariableBuildMacros(builder);
- });
- });
-
- return builder.build().toXmlString(pretty: true, indent: ' ');
- }
-
- /// Adds directories to the header search path.
- ///
- /// Must be called within the context of the ItemDefinitionGroup.
- void _addIncludePaths(xml.XmlBuilder builder) {
- if (includePaths == null || includePaths.isEmpty) {
- return;
- }
- builder.element('ClCompile', nest: () {
- builder.element('AdditionalIncludeDirectories', nest: () {
- builder.text('${includePaths.join(';')};%(AdditionalIncludeDirectories)');
- });
- });
- }
-
- /// Adds libraries to the link step.
- ///
- /// Must be called within the context of the ItemDefinitionGroup.
- void _addLibraryDependencies(xml.XmlBuilder builder) {
- if (libraryDependencies == null || libraryDependencies.isEmpty) {
- return;
- }
- builder.element('Link', nest: () {
- builder.element('AdditionalDependencies', nest: () {
- builder.text('${libraryDependencies.join(';')};%(AdditionalDependencies)');
- });
- });
- }
-
- /// Writes key/value pairs for any environment variables as user macros.
- ///
- /// Must be called within the context of the UserMacros PropertyGroup.
- void _addEnviromentVariableUserMacros(xml.XmlBuilder builder) {
- if (environmentVariables == null) {
- return;
- }
- for (final MapEntry<String, String> variable in environmentVariables.entries) {
- builder.element(variable.key, nest: () {
- builder.text(variable.value);
- });
- }
- }
-
- /// Writes the BuildMacros to expose environment variable UserMacros to the
- /// environment.
- ///
- /// Must be called within the context of the ItemGroup.
- void _addEnvironmentVariableBuildMacros(xml.XmlBuilder builder) {
- if (environmentVariables == null) {
- return;
- }
- for (final String name in environmentVariables.keys) {
- builder.element('BuildMacro', nest: () {
- builder.attribute('Include', name);
- builder.element('Value', nest: () {
- builder.text('\$($name)');
- });
- builder.element('EnvironmentVariable', nest: () {
- builder.text('true');
- });
- });
- }
- }
-}
diff --git a/packages/flutter_tools/lib/src/windows/visual_studio.dart b/packages/flutter_tools/lib/src/windows/visual_studio.dart
index ac2d9fa..6187fee 100644
--- a/packages/flutter_tools/lib/src/windows/visual_studio.dart
+++ b/packages/flutter_tools/lib/src/windows/visual_studio.dart
@@ -147,20 +147,24 @@
return '2019';
}
- /// The path to vcvars64.bat, or null if no Visual Studio installation has
+ /// The path to CMake, or null if no Visual Studio installation has
/// the components necessary to build.
- String get vcvarsPath {
+ String get cmakePath {
final Map<String, dynamic> details = _usableVisualStudioDetails;
if (details.isEmpty) {
return null;
}
- return _fileSystem.path.join(
+ return _fileSystem.path.joinAll(<String>[
_usableVisualStudioDetails[_installationPathKey] as String,
- 'VC',
- 'Auxiliary',
- 'Build',
- 'vcvars64.bat',
- );
+ 'Common7',
+ 'IDE',
+ 'CommonExtensions',
+ 'Microsoft',
+ 'CMake',
+ 'CMake',
+ 'bin',
+ 'cmake.exe',
+ ]);
}
/// The major version of the Visual Studio install, as an integer.
@@ -212,6 +216,8 @@
return <String, String>{
// The C++ toolchain required by the template.
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64': cppToolchainDescription,
+ // CMake
+ 'Microsoft.VisualStudio.Component.VC.CMake.Project': 'C++ CMake tools for Windows',
};
}
diff --git a/packages/flutter_tools/lib/src/windows/visual_studio_project.dart b/packages/flutter_tools/lib/src/windows/visual_studio_project.dart
deleted file mode 100644
index 47a4f87..0000000
--- a/packages/flutter_tools/lib/src/windows/visual_studio_project.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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.
-
-import 'package:meta/meta.dart';
-import 'package:xml/xml.dart' as xml;
-
-import '../base/file_system.dart';
-
-/// A utility class for interacting with Visual Studio project files (e.g.,
-/// .vcxproj).
-class VisualStudioProject {
- /// Creates a project object from the project file at [file].
- VisualStudioProject(this.file, {
- @required FileSystem fileSystem,
- }): _fileSystem = fileSystem {
- try {
- content = xml.parse(file.readAsStringSync());
- } on xml.XmlParserException {
- // Silently continue; formatUnderstood will return false.
- }
- }
-
- final FileSystem _fileSystem;
-
- /// The file corresponding to this object.
- final File file;
-
- /// The content of the project file.
- xml.XmlDocument content;
-
- /// Whether or not the project file was correctly parsed.
- ///
- /// If false, this could indicate that the project file is damaged, or that
- /// it's an unsupported project type.
- bool get formatUnderstood => content != null;
-
- String _guid;
-
- /// Returns the ProjectGuid for the project, or null if it's not present.
- String get guid {
- return _guid ??= _findGuid();
- }
-
- String _findGuid() {
- if (!formatUnderstood) {
- return null;
- }
- try {
- final String guidValue = content.findAllElements('ProjectGuid').single.text.trim();
- // Remove the enclosing {} from the value.
- return guidValue.substring(1, guidValue.length - 1);
- } on StateError {
- // If there is not exactly one ProjectGuid, return null.
- return null;
- }
- }
-
- String _name;
-
- /// Returns the ProjectName for the project.
- ///
- /// If not explicitly set in the project, uses the basename of the project
- /// file.
- String get name {
- return _name ??= _findName();
- }
-
- String _findName() {
- if (!formatUnderstood) {
- return null;
- }
- try {
- return content.findAllElements('ProjectName').first.text.trim();
- } on StateError {
- // If there is no name, fall back to filename.
- return _fileSystem.path.basenameWithoutExtension(file.path);
- }
- }
-}
diff --git a/packages/flutter_tools/lib/src/windows/visual_studio_solution_utils.dart b/packages/flutter_tools/lib/src/windows/visual_studio_solution_utils.dart
deleted file mode 100644
index f5a40fe..0000000
--- a/packages/flutter_tools/lib/src/windows/visual_studio_solution_utils.dart
+++ /dev/null
@@ -1,345 +0,0 @@
-// 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.
-
-import 'package:meta/meta.dart';
-
-import '../base/common.dart';
-import '../base/file_system.dart';
-import '../convert.dart';
-import '../plugins.dart';
-import '../project.dart';
-import 'visual_studio_project.dart';
-
-// Constants corresponding to specific reference types in a solution file.
-// These values are defined by the .sln format.
-const String _kSolutionTypeGuidFolder = '2150E333-8FDC-42A3-9474-1A3956D46DE8';
-const String _kSolutionTypeGuidVcxproj = '8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942';
-
-// The GUID for the folder above, managed by this class. This is an arbitrary
-// value that was randomly generated, but it should not be changed since that
-// would cause issues for existing Flutter projects.
-const String _kFlutterPluginSolutionFolderGuid = '5C2E738A-1DD3-445A-AAC8-EEB9648DD07C';
-// The FlutterBuild project GUID. This is an arbitrary
-// value that was randomly generated, but it should not be changed since that
-// would cause issues for existing Flutter projects.
-const String _kFlutterBuildProjectGuid = '6419BF13-6ECD-4CD2-9E85-E566A1F03F8F';
-
-/// Extracts and stores the plugin name and vcxproj GUID for [plugin].
-class _PluginProjectInfo {
- _PluginProjectInfo(Plugin plugin, {
- @required FileSystem fileSystem,
- }) {
- name = plugin.name;
- final File projectFile = fileSystem.directory(plugin.path).childDirectory('windows').childFile('plugin.vcxproj');
- try {
- guid = VisualStudioProject(projectFile, fileSystem: fileSystem).guid;
- } on FileSystemException {
- throwToolExit('Unable to find a plugin.vcxproj for plugin "$name"');
- }
- if (guid == null) {
- throwToolExit('Unable to find a plugin.vcxproj ID for plugin "$name"');
- }
- }
-
- // The name of the plugin, which is also the name of the symlink folder.
- String name;
-
- // The GUID of the plugin's project.
- String guid;
-}
-
-// TODO(stuartmorgan): Consider replacing this class with a real parser. See
-// https://github.com/flutter/flutter/issues/51430.
-
-class VisualStudioSolutionUtils {
- const VisualStudioSolutionUtils({
- @required WindowsProject project,
- @required FileSystem fileSystem,
- }) : _project = project,
- _fileSystem = fileSystem;
-
- final WindowsProject _project;
- final FileSystem _fileSystem;
-
- /// Updates the solution file for [project] to have the project references and
- /// dependencies to include [plugins], removing any previous plugins from the
- /// solution.
- Future<void> updatePlugins(List<Plugin> plugins) async {
- if (!_project.solutionFile.existsSync()) {
- throwToolExit(
- 'Attempted to update Windows plugins on a project that does not '
- 'support Windows.',
- );
- }
- final String solutionContent = await _project.solutionFile.readAsString();
-
- // Map of GUID to name for the current plugin list.
- final Map<String, String> currentPluginInfo = _getWindowsPluginNamesByGuid(plugins);
-
- // Find any plugins referenced in the project that are no longer used, and
- // any that are new.
- //
- // While the simplest approach to updating the solution would be to remove all
- // entries associated with plugins, and then add all the current plugins in
- // one block, Visual Studio has its own (unknown, likely data-structure-hash
- // based) order that it will use each time it writes out the file due to any
- // solution-level changes made in the UI. To avoid thrashing, and resulting
- // confusion (e.g., in review diffs), this update attempts to instead preserve
- // the ordering that is already there, so that once Visual Studio has
- // reordered the plugins, that order will be stable.
- final Set<String> existingPlugins = _findPreviousPluginGuids(solutionContent);
- final Set<String> currentPlugins = currentPluginInfo.keys.toSet();
- final Set<String> removedPlugins = existingPlugins.difference(currentPlugins);
- final Set<String> addedPlugins = currentPlugins.difference(existingPlugins);
-
- final RegExp projectStartPattern = RegExp(r'^Project\("{' + _kSolutionTypeGuidVcxproj + r'}"\)\s*=\s*".*",\s*"(.*)",\s*"{([A-Fa-f0-9\-]*)}"\s*$');
- final RegExp pluginsFolderProjectStartPattern = RegExp(r'^Project\("{' + _kSolutionTypeGuidFolder + r'}"\)\s*=.*"{' + _kFlutterPluginSolutionFolderGuid + r'}"\s*$');
- final RegExp projectEndPattern = RegExp(r'^EndProject\s*$');
- final RegExp globalStartPattern = RegExp(r'^Global\s*$');
- final RegExp globalEndPattern = RegExp(r'^EndGlobal\s*$');
- final RegExp projectDependenciesStartPattern = RegExp(r'^\s*ProjectSection\(ProjectDependencies\)\s*=\s*postProject\s*$');
- final RegExp globalSectionProjectConfigurationStartPattern = RegExp(r'^\s*GlobalSection\(ProjectConfigurationPlatforms\)\s*=\s*postSolution\s*$');
- final RegExp globalSectionNestedProjectsStartPattern = RegExp(r'^\s*GlobalSection\(NestedProjects\)\s*=\s*preSolution\s*$');
-
- final StringBuffer newSolutionContent = StringBuffer();
- // readAsString drops the BOM; re-add it.
- newSolutionContent.writeCharCode(unicodeBomCharacterRune);
-
- final Iterator<String> lineIterator = solutionContent.split('\n').iterator;
- bool foundFlutterPluginsFolder = false;
- bool foundNestedProjectsSection = false;
- bool foundRunnerProject = false;
- while (lineIterator.moveNext()) {
- final Match projectStartMatch = projectStartPattern.firstMatch(lineIterator.current);
- if (projectStartMatch != null) {
- final String guid = projectStartMatch.group(2);
- if (currentPlugins.contains(guid)) {
- // Write an up-to-date version at this location (in case, e.g., the name
- // has changed).
- _writePluginProjectEntry(guid, currentPluginInfo[guid], newSolutionContent);
- // Drop the old copy.
- _skipUntil(lineIterator, projectEndPattern);
- continue;
- } else if (removedPlugins.contains(guid)) {
- // Drop the stale plugin project.
- _skipUntil(lineIterator, projectEndPattern);
- continue;
- } else if (projectStartMatch.group(1) == _project.vcprojFile.basename) {
- foundRunnerProject = true;
- // Update the Runner project's dependencies on the plugins.
- // Skip to the dependencies section, or if there isn't one the end of
- // the project.
- while (!projectDependenciesStartPattern.hasMatch(lineIterator.current) &&
- !projectEndPattern.hasMatch(lineIterator.current)) {
- newSolutionContent.writeln(lineIterator.current);
- lineIterator.moveNext();
- }
- // Add/update the dependencies section.
- if (projectDependenciesStartPattern.hasMatch(lineIterator.current)) {
- newSolutionContent.writeln(lineIterator.current);
- _processSectionPluginReferences(removedPlugins, addedPlugins, lineIterator, _writeProjectDependency, newSolutionContent);
- } else {
- _writeDependenciesSection(currentPlugins, newSolutionContent);
- }
- }
- }
-
- if (pluginsFolderProjectStartPattern.hasMatch(lineIterator.current)) {
- foundFlutterPluginsFolder = true;
- }
-
- if (globalStartPattern.hasMatch(lineIterator.current)) {
- // The Global section is the end of the project list. Add any new plugins
- // here, since the location VS will use is unknown. They will likely be
- // reordered the next time VS writes the file.
- for (final String guid in addedPlugins) {
- _writePluginProjectEntry(guid, currentPluginInfo[guid], newSolutionContent);
- }
- // Also add the plugins folder if there wasn't already one.
- if (!foundFlutterPluginsFolder) {
- _writePluginFolderProjectEntry(newSolutionContent);
- }
- }
-
- // Update the ProjectConfiguration section once it is reached.
- if (globalSectionProjectConfigurationStartPattern.hasMatch(lineIterator.current)) {
- newSolutionContent.writeln(lineIterator.current);
- _processSectionPluginReferences(removedPlugins, addedPlugins, lineIterator, _writePluginConfigurationEntries, newSolutionContent);
- }
-
- // Update the NestedProjects section once it is reached.
- if (globalSectionNestedProjectsStartPattern.hasMatch(lineIterator.current)) {
- newSolutionContent.writeln(lineIterator.current);
- _processSectionPluginReferences(removedPlugins, addedPlugins, lineIterator, _writePluginNestingEntry, newSolutionContent);
- foundNestedProjectsSection = true;
- }
-
- // If there wasn't a NestedProjects global section, add one at the end.
- if (!foundNestedProjectsSection && globalEndPattern.hasMatch(lineIterator.current)) {
- newSolutionContent.writeln('\tGlobalSection(NestedProjects) = preSolution\r');
- for (final String guid in currentPlugins) {
- _writePluginNestingEntry(guid, newSolutionContent);
- }
- newSolutionContent.writeln('\tEndGlobalSection\r');
- }
-
- // Re-output anything that hasn't been explicitly skipped above.
- newSolutionContent.writeln(lineIterator.current);
- }
-
- if (!foundRunnerProject) {
- throwToolExit(
- 'Could not add plugins to Windows project:\n'
- 'Unable to find a "${_project.vcprojFile.basename}" project in ${_project.solutionFile.path}');
- }
-
- await _project.solutionFile.writeAsString(newSolutionContent.toString().trimRight());
- }
-
- /// Advances [iterator] it reaches an element that matches [pattern].
- ///
- /// Note that the current element at the time of calling is *not* checked.
- void _skipUntil(Iterator<String> iterator, RegExp pattern) {
- while (iterator.moveNext()) {
- if (pattern.hasMatch(iterator.current)) {
- return;
- }
- }
- }
-
- /// Writes the main project entry for the plugin with the given [guid] and
- /// [name].
- void _writePluginProjectEntry(String guid, String name, StringBuffer output) {
- output.write('''
-Project("{$_kSolutionTypeGuidVcxproj}") = "$name", "Flutter\\ephemeral\\.plugin_symlinks\\$name\\windows\\plugin.vcxproj", "{$guid}"\r
-\tProjectSection(ProjectDependencies) = postProject\r
-\t\t{$_kFlutterBuildProjectGuid} = {$_kFlutterBuildProjectGuid}\r
-\tEndProjectSection\r
-EndProject\r
-''');
- }
-
- /// Writes the main project entry for the Flutter Plugins solution folder.
- void _writePluginFolderProjectEntry(StringBuffer output) {
- const String folderName = 'Flutter Plugins';
- output.write('''
-Project("{$_kSolutionTypeGuidFolder}") = "$folderName", "$folderName", "{$_kFlutterPluginSolutionFolderGuid}"\r
-EndProject\r
-''');
- }
-
- /// Writes a project dependencies section, depending on all the GUIDs in
- /// [dependencies].
- void _writeDependenciesSection(Iterable<String> dependencies, StringBuffer output) {
- output.writeln('ProjectSection(ProjectDependencies) = postProject\r');
- for (final String guid in dependencies) {
- _writeProjectDependency(guid, output);
- }
- output.writeln('EndProjectSection\r');
- }
-
- /// Returns the GUIDs of all the Flutter plugin projects in the given solution.
- Set<String> _findPreviousPluginGuids(String solutionContent) {
- // Find the plugin folder's known GUID in ProjectDependencies lines.
- // Each line in that section has the form:
- // {project GUID} = {solution folder GUID}
- final RegExp pluginFolderChildrenPattern = RegExp(
- r'^\s*{([A-Fa-f0-9\-]*)}\s*=\s*{' + _kFlutterPluginSolutionFolderGuid + r'}\s*$',
- multiLine: true,
- );
- return pluginFolderChildrenPattern
- .allMatches(solutionContent)
- .map((Match match) => match.group(1)).toSet();
- }
-
- /// Returns a mapping of plugin project GUID to name for all the Windows plugins
- /// in [plugins].
- Map<String, String> _getWindowsPluginNamesByGuid(List<Plugin> plugins) {
- final Map<String, String> currentPluginInfo = <String, String>{};
- for (final Plugin plugin in plugins) {
- if (plugin.platforms.containsKey(_project.pluginConfigKey)) {
- final _PluginProjectInfo info = _PluginProjectInfo(plugin, fileSystem: _fileSystem);
- if (currentPluginInfo.containsKey(info.guid)) {
- throwToolExit('The plugins "${currentPluginInfo[info.guid]}" and "${info.name}" '
- 'have the same ProjectGuid, which prevents them from being used together.\n\n'
- 'Please contact the plugin authors to resolve this, and/or remove one of the '
- 'plugins from your project.');
- }
- currentPluginInfo[info.guid] = info.name;
- }
- }
- return currentPluginInfo;
- }
-
- /// Walks a GlobalSection or ProjectSection, removing entries related to removed
- /// plugins and adding entries for new plugins at the end using
- /// [newEntryWriter], which takes the guid of the plugin to write entries for.
- ///
- /// The caller is responsible for printing the section start line, which should
- /// be [lineIterator.current] when this is called, and the section end line,
- /// which will be [lineIterator.current] on return.
- void _processSectionPluginReferences(
- Set<String> removedPlugins,
- Set<String> addedPlugins,
- Iterator<String> lineIterator,
- Function(String, StringBuffer) newEntryWriter,
- StringBuffer output,
- ) {
- // Extracts the guid of the project that a line refers to. Currently all
- // sections this function is used for start with "{project guid}", even though
- // the rest of the line varies by section, so the pattern can currently be
- // shared rather than parameterized.
- final RegExp entryPattern = RegExp(r'^\s*{([A-Fa-f0-9\-]*)}');
- final RegExp sectionEndPattern = RegExp(r'^\s*End\w*Section\s*$');
- while (lineIterator.moveNext()) {
- if (sectionEndPattern.hasMatch(lineIterator.current)) {
- // The end of the section; add entries for new plugins, then exit.
- for (final String guid in addedPlugins) {
- newEntryWriter(guid, output);
- }
- return;
- }
- // Otherwise it's the sectino body. Drop any lines associated with old
- // plugins, but pass everything else through as output.
- final Match entryMatch = entryPattern.firstMatch(lineIterator.current);
- if (entryMatch != null && removedPlugins.contains(entryMatch.group(1))) {
- continue;
- }
- output.writeln(lineIterator.current);
- }
- }
-
- /// Writes all the configuration entries for the plugin project with the given
- /// [guid].
- ///
- /// Should be called within the context of writing
- /// GlobalSection(ProjectConfigurationPlatforms).
- void _writePluginConfigurationEntries(String guid, StringBuffer output) {
- final List<String> configurations = <String>['Debug', 'Profile', 'Release'];
- final List<String> entryTypes = <String>['ActiveCfg', 'Build.0'];
- for (final String configuration in configurations) {
- for (final String entryType in entryTypes) {
- output.writeln('\t\t{$guid}.$configuration|x64.$entryType = $configuration|x64\r');
- }
- }
- }
-
- /// Writes the entries to nest the plugin projects with the given [guid] under
- /// the Flutter Plugins solution folder.
- ///
- /// Should be called within the context of writing
- /// GlobalSection(NestedProjects).
- void _writePluginNestingEntry(String guid, StringBuffer output) {
- output.writeln('\t\t{$guid} = {$_kFlutterPluginSolutionFolderGuid}\r');
- }
-
- /// Writes the entrie to make a project depend on another project with the
- /// given [guid].
- ///
- /// Should be called within the context of writing
- /// ProjectSection(ProjectDependencies).
- void _writeProjectDependency(String guid, StringBuffer output) {
- output.writeln('\t\t{$guid} = {$guid}\r');
- }
-}
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/AppConfiguration.props.tmpl b/packages/flutter_tools/templates/app/windows.tmpl/AppConfiguration.props.tmpl
deleted file mode 100644
index 9ba9108..0000000
--- a/packages/flutter_tools/templates/app/windows.tmpl/AppConfiguration.props.tmpl
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <TargetName>{{projectName}}</TargetName>
- </PropertyGroup>
-</Project>
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/CMakeLists.txt.tmpl b/packages/flutter_tools/templates/app/windows.tmpl/CMakeLists.txt.tmpl
new file mode 100644
index 0000000..7c0065f
--- /dev/null
+++ b/packages/flutter_tools/templates/app/windows.tmpl/CMakeLists.txt.tmpl
@@ -0,0 +1,95 @@
+cmake_minimum_required(VERSION 3.15)
+project({{projectName}} LANGUAGES CXX)
+
+set(BINARY_NAME "{{projectName}}")
+
+cmake_policy(SET CMP0063 NEW)
+
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
+
+# Configure build options.
+get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(IS_MULTICONFIG)
+ set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
+ CACHE STRING "" FORCE)
+else()
+ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
+ STRING "Flutter build mode" FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ "Debug" "Profile" "Release")
+ endif()
+endif()
+
+set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
+set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
+set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
+set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
+
+# Use Unicode for all projects.
+add_definitions(-DUNICODE -D_UNICODE)
+
+# Compilation settings that should be applied to most targets.
+function(APPLY_STANDARD_SETTINGS TARGET)
+ target_compile_features(${TARGET} PUBLIC cxx_std_17)
+ target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
+ target_compile_options(${TARGET} PRIVATE /EHsc)
+ target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
+ target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
+endfunction()
+
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+
+# Flutter library and tool build rules.
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# Application build
+add_subdirectory("runner")
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# Support files are copied into place next to the executable, so that it can
+# run in place. This is done instead of making a separate bundle (as on Linux)
+# so that building and running from within Visual Studio will work.
+set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>")
+# Make the "install" step default, as it's required to run.
+set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+
+if(PLUGIN_BUNDLED_LIBRARIES)
+ install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endif()
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+ " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ CONFIGURATIONS Profile;Release
+ COMPONENT Runtime)
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/FlutterBuild.vcxproj b/packages/flutter_tools/templates/app/windows.tmpl/FlutterBuild.vcxproj
deleted file mode 100644
index 8ef93f9..0000000
--- a/packages/flutter_tools/templates/app/windows.tmpl/FlutterBuild.vcxproj
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Profile|x64">
- <Configuration>Profile</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>15.0</VCProjectVersion>
- <ProjectGuid>{6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}</ProjectGuid>
- <ProjectName>Flutter Build</ProjectName>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Label="Configuration">
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets">
- <Import Project="flutter\ephemeral\Generated.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup />
- <ItemDefinitionGroup>
- <CustomBuildStep>
- <Command>"$(ProjectDir)scripts\prepare_dependencies" $(Configuration)</Command>
- <Message>Running Flutter backend build</Message>
- <Outputs>force_to_run_every_time</Outputs>
- </CustomBuildStep>
- </ItemDefinitionGroup>
- <ItemGroup>
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/Runner.sln b/packages/flutter_tools/templates/app/windows.tmpl/Runner.sln
deleted file mode 100644
index 00fb3d3..0000000
--- a/packages/flutter_tools/templates/app/windows.tmpl/Runner.sln
+++ /dev/null
@@ -1,39 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29709.97
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Runner", "Runner.vcxproj", "{5A827760-CF8B-408A-99A3-B6C0AD2271E7}"
- ProjectSection(ProjectDependencies) = postProject
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Flutter Build", "FlutterBuild.vcxproj", "{6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Profile|x64 = Profile|x64
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Debug|x64.ActiveCfg = Debug|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Debug|x64.Build.0 = Debug|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Profile|x64.ActiveCfg = Profile|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Profile|x64.Build.0 = Profile|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Release|x64.ActiveCfg = Release|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Release|x64.Build.0 = Release|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.ActiveCfg = Debug|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.Build.0 = Debug|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.ActiveCfg = Profile|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.Build.0 = Profile|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.ActiveCfg = Release|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {B8A69CB0-A974-4774-9EBD-1E5EECACD186}
- EndGlobalSection
-EndGlobal
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/Runner.vcxproj.filters b/packages/flutter_tools/templates/app/windows.tmpl/Runner.vcxproj.filters
deleted file mode 100644
index 761db86..0000000
--- a/packages/flutter_tools/templates/app/windows.tmpl/Runner.vcxproj.filters
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
- <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
- <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
- </Filter>
- <Filter Include="Source Files\Client Wrapper">
- <UniqueIdentifier>{2761a4b5-57b2-4d50-a677-d20ddc17a7f1}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="runner\main.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="runner\run_loop.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="runner\flutter_window.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="runner\utils.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="runner\win32_window.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="runner\window_configuration.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="flutter\generated_plugin_registrant.cc">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\engine_method_result.cc">
- <Filter>Source Files\Client Wrapper</Filter>
- </ClCompile>
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\flutter_view_controller.cc">
- <Filter>Source Files\Client Wrapper</Filter>
- </ClCompile>
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\plugin_registrar.cc">
- <Filter>Source Files\Client Wrapper</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="runner\run_loop.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="runner\flutter_window.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="runner\utils.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="runner\win32_window.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="runner\window_configuration.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="runner\resource.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="flutter\generated_plugin_registrant.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <Manifest Include="runner.exe.manifest" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="Runner.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- </ItemGroup>
- <ItemGroup>
- <Image Include="resources\app_icon.ico">
- <Filter>Resource Files</Filter>
- </Image>
- </ItemGroup>
-</Project>
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/Runner.vcxproj.tmpl b/packages/flutter_tools/templates/app/windows.tmpl/Runner.vcxproj.tmpl
deleted file mode 100644
index 38a9213..0000000
--- a/packages/flutter_tools/templates/app/windows.tmpl/Runner.vcxproj.tmpl
+++ /dev/null
@@ -1,262 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Profile|x64">
- <Configuration>Profile</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>15.0</VCProjectVersion>
- <ProjectGuid>{5A827760-CF8B-408A-99A3-B6C0AD2271E7}</ProjectGuid>
- <RootNamespace>{{projectName}}</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="flutter\ephemeral\Generated.props" />
- <Import Project="AppConfiguration.props" />
- <Import Project="flutter\GeneratedPlugins.props" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="flutter\ephemeral\Generated.props" />
- <Import Project="AppConfiguration.props" />
- <Import Project="flutter\GeneratedPlugins.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="flutter\ephemeral\Generated.props" />
- <Import Project="AppConfiguration.props" />
- <Import Project="flutter\GeneratedPlugins.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>$(ProjectDir)..\build\windows\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir>
- <IntDir>$(ProjectDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>$(ProjectDir)..\build\windows\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir>
- <IntDir>$(ProjectDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
- <OutDir>$(ProjectDir)..\build\windows\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir>
- <IntDir>$(ProjectDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>Disabled</Optimization>
- <SDLCheck>true</SDLCheck>
- <ConformanceMode>true</ConformanceMode>
- <AdditionalIncludeDirectories>$(ProjectDir);$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_MBCS;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <TreatWarningAsError>true</TreatWarningAsError>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
- </ClCompile>
- <Link>
- <AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(FLUTTER_EPHEMERAL_DIR);$(OutDir)..\Plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- <PreBuildEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreBuildEvent>
- <PreLinkEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreLinkEvent>
- <PostBuildEvent>
- <Command>
- </Command>
- </PostBuildEvent>
- <PostBuildEvent>
- <Message>
- </Message>
- </PostBuildEvent>
- <CustomBuildStep>
- <Command>"$(ProjectDir)scripts\bundle_assets_and_deps" "$(FLUTTER_EPHEMERAL_DIR)\" "$(OutputPath)" "$(OutputPath)..\Plugins\" "$(TargetFileName)" "$(Configuration)"</Command>
- </CustomBuildStep>
- <CustomBuildStep>
- <Message>Bundling dependencies</Message>
- <Outputs>Dummy_Run_Always</Outputs>
- <Inputs>
- </Inputs>
- </CustomBuildStep>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <ConformanceMode>true</ConformanceMode>
- <AdditionalIncludeDirectories>$(ProjectDir);$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_MBCS;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <TreatWarningAsError>true</TreatWarningAsError>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
- </ClCompile>
- <Link>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(FLUTTER_EPHEMERAL_DIR);$(OutDir)..\Plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- <PreBuildEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreBuildEvent>
- <PreLinkEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreLinkEvent>
- <PostBuildEvent>
- <Command>
- </Command>
- </PostBuildEvent>
- <PostBuildEvent>
- <Message>
- </Message>
- </PostBuildEvent>
- <CustomBuildStep>
- <Command>"$(ProjectDir)scripts\bundle_assets_and_deps" "$(FLUTTER_EPHEMERAL_DIR)\" "$(OutputPath)" "$(OutputPath)..\Plugins\" "$(TargetFileName)" "$(Configuration)"</Command>
- </CustomBuildStep>
- <CustomBuildStep>
- <Message>Bundling dependencies</Message>
- <Outputs>Dummy_Run_Always</Outputs>
- <Inputs>
- </Inputs>
- </CustomBuildStep>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <ConformanceMode>true</ConformanceMode>
- <AdditionalIncludeDirectories>$(ProjectDir);$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_MBCS;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <TreatWarningAsError>true</TreatWarningAsError>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
- </ClCompile>
- <Link>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(FLUTTER_EPHEMERAL_DIR);$(OutDir)..\Plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- <PreBuildEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreBuildEvent>
- <PreLinkEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreLinkEvent>
- <PostBuildEvent>
- <Command>
- </Command>
- </PostBuildEvent>
- <PostBuildEvent>
- <Message>
- </Message>
- </PostBuildEvent>
- <CustomBuildStep>
- <Command>"$(ProjectDir)scripts\bundle_assets_and_deps" "$(FLUTTER_EPHEMERAL_DIR)\" "$(OutputPath)" "$(OutputPath)..\Plugins\" "$(TargetFileName)" "$(Configuration)"</Command>
- </CustomBuildStep>
- <CustomBuildStep>
- <Message>Bundling dependencies</Message>
- <Outputs>Dummy_Run_Always</Outputs>
- <Inputs>
- </Inputs>
- </CustomBuildStep>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="runner\main.cpp" />
- <ClCompile Include="flutter\generated_plugin_registrant.cc" />
- <ClCompile Include="runner\run_loop.cpp" />
- <ClCompile Include="runner\utils.cpp" />
- <ClCompile Include="runner\window_configuration.cpp" />
- <ClCompile Include="runner\win32_window.cpp" />
- <ClCompile Include="runner\flutter_window.cpp" />
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\engine_method_result.cc" />
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\flutter_view_controller.cc" />
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\plugin_registrar.cc" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="flutter\generated_plugin_registrant.h" />
- <ClInclude Include="runner\resource.h" />
- <ClInclude Include="runner\run_loop.h" />
- <ClInclude Include="runner\utils.h" />
- <ClInclude Include="runner\win32_window.h" />
- <ClInclude Include="runner\flutter_window.h" />
- <ClInclude Include="runner\window_configuration.h" />
- </ItemGroup>
- <ItemGroup>
- <Manifest Include="runner\runner.exe.manifest" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="runner\Runner.rc" />
- </ItemGroup>
- <ItemGroup>
- <Image Include="runner\resources\app_icon.ico" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
- <PropertyGroup>
- <LocalDebuggerWorkingDirectory>$(SolutionDir)</LocalDebuggerWorkingDirectory>
- </PropertyGroup>
-</Project>
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/flutter/.template_version b/packages/flutter_tools/templates/app/windows.tmpl/flutter/.template_version
index 00750ed..b8626c4 100644
--- a/packages/flutter_tools/templates/app/windows.tmpl/flutter/.template_version
+++ b/packages/flutter_tools/templates/app/windows.tmpl/flutter/.template_version
@@ -1 +1 @@
-3
+4
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/flutter/CMakeLists.txt b/packages/flutter_tools/templates/app/windows.tmpl/flutter/CMakeLists.txt
new file mode 100644
index 0000000..3c1726f
--- /dev/null
+++ b/packages/flutter_tools/templates/app/windows.tmpl/flutter/CMakeLists.txt
@@ -0,0 +1,98 @@
+cmake_minimum_required(VERSION 3.15)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
+
+# === Flutter Library ===
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+ "flutter_export.h"
+ "flutter_windows.h"
+ "flutter_messenger.h"
+ "flutter_plugin_registrar.h"
+)
+list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+ "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
+add_dependencies(flutter flutter_assemble)
+
+# === Wrapper ===
+list(APPEND CPP_WRAPPER_SOURCES_CORE
+ "engine_method_result.cc"
+ "standard_codec.cc"
+)
+list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
+list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
+ "plugin_registrar.cc"
+)
+list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
+list(APPEND CPP_WRAPPER_SOURCES_APP
+ "flutter_view_controller.cc"
+)
+list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
+
+# Wrapper sources needed for a plugin.
+add_library(flutter_wrapper_plugin STATIC
+ ${CPP_WRAPPER_SOURCES_CORE}
+ ${CPP_WRAPPER_SOURCES_PLUGIN}
+)
+apply_standard_settings(flutter_wrapper_plugin)
+set_target_properties(flutter_wrapper_plugin PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+set_target_properties(flutter_wrapper_plugin PROPERTIES
+ CXX_VISIBILITY_PRESET hidden)
+target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
+target_include_directories(flutter_wrapper_plugin PUBLIC
+ "${WRAPPER_ROOT}/include"
+)
+add_dependencies(flutter_wrapper_plugin flutter_assemble)
+
+# Wrapper sources needed for the runner.
+add_library(flutter_wrapper_app STATIC
+ ${CPP_WRAPPER_SOURCES_CORE}
+ ${CPP_WRAPPER_SOURCES_APP}
+)
+apply_standard_settings(flutter_wrapper_app)
+target_link_libraries(flutter_wrapper_app PUBLIC flutter)
+target_include_directories(flutter_wrapper_app PUBLIC
+ "${WRAPPER_ROOT}/include"
+)
+add_dependencies(flutter_wrapper_app flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+add_custom_command(
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+ ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
+ ${CPP_WRAPPER_SOURCES_APP}
+ ${CMAKE_CURRENT_BINARY_DIR}/_phony_
+ COMMAND ${CMAKE_COMMAND} -E env
+ ${FLUTTER_TOOL_ENVIRONMENT}
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
+ windows-x64 $<CONFIG>
+)
+add_custom_target(flutter_assemble DEPENDS
+ "${FLUTTER_LIBRARY}"
+ ${FLUTTER_LIBRARY_HEADERS}
+ ${CPP_WRAPPER_SOURCES_CORE}
+ ${CPP_WRAPPER_SOURCES_PLUGIN}
+ ${CPP_WRAPPER_SOURCES_APP}
+)
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/runner/CMakeLists.txt b/packages/flutter_tools/templates/app/windows.tmpl/runner/CMakeLists.txt
new file mode 100644
index 0000000..83e5acaa
--- /dev/null
+++ b/packages/flutter_tools/templates/app/windows.tmpl/runner/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.15)
+project(runner LANGUAGES CXX)
+
+add_executable(${BINARY_NAME} WIN32
+ "flutter_window.cpp"
+ "main.cpp"
+ "run_loop.cpp"
+ "utils.cpp"
+ "win32_window.cpp"
+ "window_configuration.cpp"
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+ "Runner.rc"
+ "runner.exe.manifest"
+)
+apply_standard_settings(${BINARY_NAME})
+target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
+target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
+add_dependencies(${BINARY_NAME} flutter_assemble)
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/scripts/bundle_assets_and_deps.bat b/packages/flutter_tools/templates/app/windows.tmpl/scripts/bundle_assets_and_deps.bat
deleted file mode 100644
index 9efa28f..0000000
--- a/packages/flutter_tools/templates/app/windows.tmpl/scripts/bundle_assets_and_deps.bat
+++ /dev/null
@@ -1,44 +0,0 @@
-@echo off
-
-set FLUTTER_CACHE_DIR=%~1
-set BUNDLE_DIR=%~2
-set PLUGIN_DIR=%~3
-set EXE_NAME=%~4
-set BUILD_MODE=%~5
-
-set DATA_DIR=%BUNDLE_DIR%data
-
-if not exist "%DATA_DIR%" call mkdir "%DATA_DIR%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-:: Write the executable name to the location expected by the Flutter tool.
-echo %EXE_NAME%>"%FLUTTER_CACHE_DIR%exe_filename"
-
-:: Copy the Flutter assets to the data directory.
-set FLUTTER_BUILD_DIR=%~dp0..\..\build\
-set ASSET_DIR_NAME=flutter_assets
-set TARGET_ASSET_DIR=%DATA_DIR%\%ASSET_DIR_NAME%
-if exist "%TARGET_ASSET_DIR%" call rmdir /s /q "%TARGET_ASSET_DIR%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-call xcopy /s /e /i /q "%FLUTTER_BUILD_DIR%%ASSET_DIR_NAME%" "%TARGET_ASSET_DIR%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-:: Copy the icudtl.dat file from the Flutter tree to the data directory.
-call xcopy /y /d /q "%FLUTTER_CACHE_DIR%icudtl.dat" "%DATA_DIR%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-:: For non-debug modes, copy app.so into the data directory.
-if not %BUILD_MODE% == "Debug" (
- call xcopy /y /d /q "%FLUTTER_BUILD_DIR%windows\app.so" "%DATA_DIR%"
- if %errorlevel% neq 0 exit /b %errorlevel%
-)
-
-:: Copy the Flutter DLL to the target location.
-call xcopy /y /d /q "%FLUTTER_CACHE_DIR%flutter_windows.dll" "%BUNDLE_DIR%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-:: Copy any Plugin DLLs to the target location.
-if exist "%PLUGIN_DIR%" (
- call xcopy /y /d /q "%PLUGIN_DIR%"*.dll "%BUNDLE_DIR%"
- if %errorlevel% neq 0 exit /b %errorlevel%
-)
diff --git a/packages/flutter_tools/templates/app/windows.tmpl/scripts/prepare_dependencies.bat b/packages/flutter_tools/templates/app/windows.tmpl/scripts/prepare_dependencies.bat
deleted file mode 100644
index d05238b..0000000
--- a/packages/flutter_tools/templates/app/windows.tmpl/scripts/prepare_dependencies.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-@echo off
-
-:: Run flutter tool backend.
-set BUILD_MODE=%~1
-"%FLUTTER_ROOT%\packages\flutter_tools\bin\tool_backend" windows-x64 %BUILD_MODE%
diff --git a/packages/flutter_tools/templates/plugin/windows.tmpl/CMakeLists.txt.tmpl b/packages/flutter_tools/templates/plugin/windows.tmpl/CMakeLists.txt.tmpl
new file mode 100644
index 0000000..1399a82
--- /dev/null
+++ b/packages/flutter_tools/templates/plugin/windows.tmpl/CMakeLists.txt.tmpl
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.15)
+set(PROJECT_NAME "{{projectName}}")
+project(${PROJECT_NAME} LANGUAGES CXX)
+
+set(PLUGIN_NAME "${PROJECT_NAME}_plugin")
+
+add_library(${PLUGIN_NAME} SHARED
+ "${PLUGIN_NAME}.cpp"
+)
+apply_standard_settings(${PLUGIN_NAME})
+set_target_properties(${PLUGIN_NAME} PROPERTIES
+ CXX_VISIBILITY_PRESET hidden)
+target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
+target_include_directories(${PLUGIN_NAME} INTERFACE
+ "${CMAKE_CURRENT_SOURCE_DIR}/include")
+target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
+
+# List of absolute paths to libraries that should be bundled with the plugin
+set({{projectName}}_bundled_libraries
+ ""
+ PARENT_SCOPE
+)
diff --git a/packages/flutter_tools/templates/plugin/windows.tmpl/PluginInfo.props.tmpl b/packages/flutter_tools/templates/plugin/windows.tmpl/PluginInfo.props.tmpl
deleted file mode 100644
index 636a88b..0000000
--- a/packages/flutter_tools/templates/plugin/windows.tmpl/PluginInfo.props.tmpl
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ImportGroup Label="PropertySheets" />
- <PropertyGroup Label="UserMacros">
- <FlutterPluginName>{{projectName}}</FlutterPluginName>
- </PropertyGroup>
- <PropertyGroup />
- <ItemDefinitionGroup />
- <ItemGroup>
- <BuildMacro Include="FlutterPluginName">
- <Value>$(FlutterPluginName)</Value>
- </BuildMacro>
- </ItemGroup>
-</Project>
diff --git a/packages/flutter_tools/templates/plugin/windows.tmpl/projectName_plugin.h.tmpl b/packages/flutter_tools/templates/plugin/windows.tmpl/include/projectName.tmpl/projectName_plugin.h.tmpl
similarity index 89%
rename from packages/flutter_tools/templates/plugin/windows.tmpl/projectName_plugin.h.tmpl
rename to packages/flutter_tools/templates/plugin/windows.tmpl/include/projectName.tmpl/projectName_plugin.h.tmpl
index 35eef89..68c1a61 100644
--- a/packages/flutter_tools/templates/plugin/windows.tmpl/projectName_plugin.h.tmpl
+++ b/packages/flutter_tools/templates/plugin/windows.tmpl/include/projectName.tmpl/projectName_plugin.h.tmpl
@@ -1,5 +1,5 @@
#ifndef FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_
-#defineFLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_
+#define FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_
#include <flutter_plugin_registrar.h>
diff --git a/packages/flutter_tools/templates/plugin/windows.tmpl/plugin.vcxproj.filters b/packages/flutter_tools/templates/plugin/windows.tmpl/plugin.vcxproj.filters
deleted file mode 100644
index 0f8c708..0000000
--- a/packages/flutter_tools/templates/plugin/windows.tmpl/plugin.vcxproj.filters
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
- <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
- <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
- </Filter>
- <Filter Include="Source Files\cpp_client_wrapper">
- <UniqueIdentifier>{dbe2dac9-4a21-4849-bef5-2069d695609d}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="stdafx.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="targetver.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="$(FlutterPluginName)_plugin.h">
- <Filter>Source Files</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\plugin_registrar.cc">
- <Filter>Source Files\cpp_client_wrapper</Filter>
- </ClCompile>
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\standard_codec.cc">
- <Filter>Source Files\cpp_client_wrapper</Filter>
- </ClCompile>
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\engine_method_result.cc">
- <Filter>Source Files\cpp_client_wrapper</Filter>
- </ClCompile>
- <ClCompile Include="$(FlutterPluginName)_plugin.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- </ItemGroup>
-</Project>
diff --git a/packages/flutter_tools/templates/plugin/windows.tmpl/plugin.vcxproj.tmpl b/packages/flutter_tools/templates/plugin/windows.tmpl/plugin.vcxproj.tmpl
deleted file mode 100644
index c9e56be..0000000
--- a/packages/flutter_tools/templates/plugin/windows.tmpl/plugin.vcxproj.tmpl
+++ /dev/null
@@ -1,247 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Profile|x64">
- <Configuration>Profile</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>15.0</VCProjectVersion>
- <ProjectGuid>{{{pluginProjectUUID}}}</ProjectGuid>
- <Keyword>Win32Proj</Keyword>
- <RootNamespace>{{projectName}}</RootNamespace>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- <ProjectName>{{projectName}}</ProjectName>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
- <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="$(SolutionDir)flutter\ephemeral\Generated.props" />
- <Import Project="PluginInfo.props" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="$(SolutionDir)flutter\ephemeral\Generated.props" />
- <Import Project="PluginInfo.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="$(SolutionDir)flutter\ephemeral\Generated.props" />
- <Import Project="PluginInfo.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- <OutDir>$(SolutionDir)..\build\windows\$(Platform)\$(Configuration)\Plugins\</OutDir>
- <IntDir>$(SolutionDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
- <CustomBuildBeforeTargets>
- </CustomBuildBeforeTargets>
- <TargetName>$(ProjectName)_plugin</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- <OutDir>$(SolutionDir)..\build\windows\$(Platform)\$(Configuration)\Plugins\</OutDir>
- <IntDir>$(SolutionDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
- <CustomBuildBeforeTargets>
- </CustomBuildBeforeTargets>
- <TargetName>$(ProjectName)_plugin</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
- <LinkIncremental>false</LinkIncremental>
- <OutDir>$(SolutionDir)..\build\windows\$(Platform)\$(Configuration)\Plugins\</OutDir>
- <IntDir>$(SolutionDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
- <CustomBuildBeforeTargets />
- <TargetName>$(ProjectName)_plugin</TargetName>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>Disabled</Optimization>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;FLUTTER_PLUGIN_IMPL;_WINDOWS;_USRDLL;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <ExceptionHandling>false</ExceptionHandling>
- <TreatWarningAsError>true</TreatWarningAsError>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
- <AdditionalIncludeDirectories>$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(FLUTTER_EPHEMERAL_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- <PreBuildEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreBuildEvent>
- <CustomBuildStep>
- <Command>
- </Command>
- </CustomBuildStep>
- <CustomBuildStep>
- <Message>
- </Message>
- <Outputs>
- </Outputs>
- </CustomBuildStep>
- <PostBuildEvent>
- <Command>
- </Command>
- </PostBuildEvent>
- <PostBuildEvent>
- <Message>
- </Message>
- </PostBuildEvent>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;FLUTTER_PLUGIN_IMPL;_WINDOWS;_USRDLL;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <ExceptionHandling>false</ExceptionHandling>
- <TreatWarningAsError>true</TreatWarningAsError>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
- <AdditionalIncludeDirectories>$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(FLUTTER_EPHEMERAL_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- <PreBuildEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreBuildEvent>
- <CustomBuildStep>
- <Command>
- </Command>
- </CustomBuildStep>
- <CustomBuildStep>
- <Message>
- </Message>
- <Outputs>
- </Outputs>
- </CustomBuildStep>
- <PostBuildEvent>
- <Command>
- </Command>
- </PostBuildEvent>
- <PostBuildEvent>
- <Message>
- </Message>
- </PostBuildEvent>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;FLUTTER_PLUGIN_IMPL;_WINDOWS;_USRDLL;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <ConformanceMode>true</ConformanceMode>
- <ExceptionHandling>false</ExceptionHandling>
- <TreatWarningAsError>true</TreatWarningAsError>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
- <AdditionalIncludeDirectories>$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(FLUTTER_EPHEMERAL_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- <PreBuildEvent>
- <Command>
- </Command>
- <Message>
- </Message>
- </PreBuildEvent>
- <CustomBuildStep>
- <Command>
- </Command>
- </CustomBuildStep>
- <CustomBuildStep>
- <Message>
- </Message>
- <Outputs>
- </Outputs>
- </CustomBuildStep>
- <PostBuildEvent>
- <Command>
- </Command>
- </PostBuildEvent>
- <PostBuildEvent>
- <Message>
- </Message>
- </PostBuildEvent>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClInclude Include="$(FlutterPluginName)_plugin.h" />
- <ClInclude Include="stdafx.h" />
- <ClInclude Include="targetver.h" />
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="$(FlutterPluginName)_plugin.cpp" />
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\engine_method_result.cc" />
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\plugin_registrar.cc" />
- <ClCompile Include="$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\standard_codec.cc" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>
diff --git a/packages/flutter_tools/templates/plugin/windows.tmpl/projectName_plugin.cpp.tmpl b/packages/flutter_tools/templates/plugin/windows.tmpl/projectName_plugin.cpp.tmpl
index 665c916..a2af158 100644
--- a/packages/flutter_tools/templates/plugin/windows.tmpl/projectName_plugin.cpp.tmpl
+++ b/packages/flutter_tools/templates/plugin/windows.tmpl/projectName_plugin.cpp.tmpl
@@ -1,4 +1,4 @@
-#include "{{projectName}}_plugin.h"
+#include "include/{{projectName}}/{{projectName}}_plugin.h"
// This must be included before many other Windows headers.
#include <windows.h>
diff --git a/packages/flutter_tools/templates/template_manifest.json b/packages/flutter_tools/templates/template_manifest.json
index cf8779c..cbd09dd 100644
--- a/packages/flutter_tools/templates/template_manifest.json
+++ b/packages/flutter_tools/templates/template_manifest.json
@@ -122,9 +122,10 @@
"templates/app/web/index.html.tmpl",
"templates/app/web/manifest.json.tmpl",
"templates/app/windows.tmpl/.gitignore",
- "templates/app/windows.tmpl/AppConfiguration.props.tmpl",
+ "templates/app/windows.tmpl/CMakeLists.txt.tmpl",
"templates/app/windows.tmpl/flutter/.template_version",
- "templates/app/windows.tmpl/FlutterBuild.vcxproj",
+ "templates/app/windows.tmpl/flutter/CMakeLists.txt",
+ "templates/app/windows.tmpl/runner/CMakeLists.txt",
"templates/app/windows.tmpl/runner/flutter_window.cpp",
"templates/app/windows.tmpl/runner/flutter_window.h",
"templates/app/windows.tmpl/runner/main.cpp",
@@ -140,11 +141,6 @@
"templates/app/windows.tmpl/runner/win32_window.h",
"templates/app/windows.tmpl/runner/window_configuration.cpp.tmpl",
"templates/app/windows.tmpl/runner/window_configuration.h",
- "templates/app/windows.tmpl/Runner.sln",
- "templates/app/windows.tmpl/Runner.vcxproj.filters",
- "templates/app/windows.tmpl/Runner.vcxproj.tmpl",
- "templates/app/windows.tmpl/scripts/bundle_assets_and_deps.bat",
- "templates/app/windows.tmpl/scripts/prepare_dependencies.bat",
"templates/cocoapods/Podfile-ios-objc",
"templates/cocoapods/Podfile-ios-swift",
"templates/cocoapods/Podfile-macos",
@@ -281,11 +277,9 @@
"templates/plugin/README.md.tmpl",
"templates/plugin/test/projectName_test.dart.tmpl",
"templates/plugin/windows.tmpl/.gitignore",
- "templates/plugin/windows.tmpl/plugin.vcxproj.filters",
- "templates/plugin/windows.tmpl/plugin.vcxproj.tmpl",
- "templates/plugin/windows.tmpl/PluginInfo.props.tmpl",
+ "templates/plugin/windows.tmpl/CMakeLists.txt.tmpl",
+ "templates/plugin/windows.tmpl/include/projectName.tmpl/projectName_plugin.h.tmpl",
"templates/plugin/windows.tmpl/projectName_plugin.cpp.tmpl",
- "templates/plugin/windows.tmpl/projectName_plugin.h.tmpl",
"templates/plugin/lib/projectName_web.dart.tmpl"
]
-}
\ No newline at end of file
+}
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart
index 184a3b3..d6959a2 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart
@@ -9,10 +9,10 @@
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/utils.dart';
import 'package:flutter_tools/src/cache.dart';
+import 'package:flutter_tools/src/cmake.dart';
import 'package:flutter_tools/src/commands/build.dart';
import 'package:flutter_tools/src/commands/build_linux.dart';
import 'package:flutter_tools/src/features.dart';
-import 'package:flutter_tools/src/linux/cmake.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:process/process.dart';
@@ -267,7 +267,7 @@
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
});
- testUsingContext('Linux build configures Makefile exports', () async {
+ testUsingContext('Linux build configures CMake exports', () async {
final BuildCommand command = BuildCommand();
setUpMockProjectFilesForBuild();
processManager = FakeProcessManager.list(<FakeCommand>[
@@ -305,8 +305,8 @@
final List<String> configLines = cmakeConfig.readAsLinesSync();
expect(configLines, containsAll(<String>[
- 'set(FLUTTER_ROOT "$_kTestFlutterRoot")',
- 'set(PROJECT_DIR "${fileSystem.currentDirectory.path}")',
+ 'file(TO_CMAKE_PATH "$_kTestFlutterRoot" FLUTTER_ROOT)',
+ 'file(TO_CMAKE_PATH "${fileSystem.currentDirectory.path}" PROJECT_DIR)',
' "DART_DEFINES=\\"foo.bar%3D2,fizz.far%3D3\\""',
' "DART_OBFUSCATION=\\"true\\""',
' "EXTRA_FRONT_END_OPTIONS=\\"--enable-experiment%3Dnon-nullable\\""',
@@ -314,8 +314,8 @@
' "SPLIT_DEBUG_INFO=\\"foo/\\""',
' "TRACK_WIDGET_CREATION=\\"true\\""',
' "TREE_SHAKE_ICONS=\\"true\\""',
- ' "FLUTTER_ROOT=\\"\${FLUTTER_ROOT}\\""',
- ' "PROJECT_DIR=\\"\${PROJECT_DIR}\\""',
+ ' "FLUTTER_ROOT=\\"$_kTestFlutterRoot\\""',
+ ' "PROJECT_DIR=\\"${fileSystem.currentDirectory.path}\\""',
' "FLUTTER_TARGET=\\"lib/other.dart\\""',
' "BUNDLE_SKSL_PATH=\\"foo/bar.sksl.json\\""',
]));
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart
index 36bb208..e6fc64c 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart
@@ -9,12 +9,10 @@
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build_windows.dart';
-import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/windows/visual_studio.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
-import 'package:xml/xml.dart' as xml;
import '../../src/common.dart';
import '../../src/context.dart';
@@ -22,9 +20,9 @@
import '../../src/testbed.dart';
const String flutterRoot = r'C:\flutter';
-const String solutionPath = r'C:\windows\Runner.sln';
+const String buildFilePath = r'C:\windows\CMakeLists.txt';
const String visualStudioPath = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community';
-const String vcvarsPath = visualStudioPath + r'\VC\Auxiliary\Build\vcvars64.bat';
+const String cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
final Platform windowsPlatform = FakePlatform(
operatingSystem: 'windows',
@@ -43,8 +41,7 @@
void main() {
FileSystem fileSystem;
- MockProcessManager mockProcessManager;
- MockProcess mockProcess;
+ ProcessManager processManager;
MockVisualStudio mockVisualStudio;
setUpAll(() {
@@ -54,18 +51,7 @@
setUp(() {
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
Cache.flutterRoot = flutterRoot;
- mockProcessManager = MockProcessManager();
- mockProcess = MockProcess();
mockVisualStudio = MockVisualStudio();
- when(mockProcess.exitCode).thenAnswer((Invocation invocation) async {
- return 0;
- });
- when(mockProcess.stderr).thenAnswer((Invocation invocation) {
- return const Stream<List<int>>.empty();
- });
- when(mockProcess.stdout).thenAnswer((Invocation invocation) {
- return Stream<List<int>>.fromIterable(<List<int>>[utf8.encode('STDOUT STUFF')]);
- });
});
// Creates the mock files necessary to look like a Flutter project.
@@ -77,7 +63,7 @@
// Creates the mock files necessary to run a build.
void setUpMockProjectFilesForBuild({int templateVersion}) {
- fileSystem.file(solutionPath).createSync(recursive: true);
+ fileSystem.file(buildFilePath).createSync(recursive: true);
setUpMockCoreProjectFiles();
final String versionFileSubpath = fileSystem.path.join('flutter', '.template_version');
@@ -101,6 +87,50 @@
projectTemplateVersionFile.writeAsStringSync(templateVersion.toString());
}
+ // Returns the command matching the build_windows call to generate CMake
+ // files.
+ FakeCommand cmakeGenerationCommand({void Function() onRun}) {
+ return FakeCommand(
+ command: <String>[
+ cmakePath,
+ '-S',
+ fileSystem.path.dirname(buildFilePath),
+ '-B',
+ r'build\windows',
+ '-G',
+ 'Visual Studio 16 2019',
+ ],
+ onRun: onRun,
+ );
+ }
+
+ // Returns the command matching the build_windows call to build.
+ FakeCommand buildCommand(String buildMode, {
+ bool verbose = false,
+ void Function() onRun,
+ String stdout = '',
+ }) {
+ return FakeCommand(
+ command: <String>[
+ cmakePath,
+ '--build',
+ r'build\windows',
+ '--config',
+ buildMode,
+ '--target',
+ 'INSTALL',
+ if (verbose)
+ '--verbose'
+ ],
+ environment: <String, String>{
+ if (verbose)
+ 'VERBOSE_SCRIPT_LOGGING': 'true'
+ },
+ onRun: onRun,
+ stdout: stdout,
+ );
+ }
+
testUsingContext('Windows build fails when there is no vcvars64.bat', () async {
final BuildWindowsCommand command = BuildWindowsCommand()
..visualStudioOverride = mockVisualStudio;
@@ -122,7 +152,7 @@
..visualStudioOverride = mockVisualStudio;
applyMocksToCommand(command);
setUpMockCoreProjectFiles();
- when(mockVisualStudio.vcvarsPath).thenReturn(vcvarsPath);
+ when(mockVisualStudio.cmakePath).thenReturn(cmakePath);
expect(createTestCommandRunner(command).run(
const <String>['windows', '--no-pub']
@@ -139,7 +169,7 @@
..visualStudioOverride = mockVisualStudio;
applyMocksToCommand(command);
setUpMockProjectFilesForBuild();
- when(mockVisualStudio.vcvarsPath).thenReturn(vcvarsPath);
+ when(mockVisualStudio.cmakePath).thenReturn(cmakePath);
expect(createTestCommandRunner(command).run(
const <String>['windows', '--no-pub']
@@ -188,19 +218,14 @@
..visualStudioOverride = mockVisualStudio;
applyMocksToCommand(command);
setUpMockProjectFilesForBuild();
- when(mockVisualStudio.vcvarsPath).thenReturn(vcvarsPath);
+ when(mockVisualStudio.cmakePath).thenReturn(cmakePath);
- when(mockProcessManager.start(<String>[
- fileSystem.path.join(flutterRoot, 'packages', 'flutter_tools', 'bin', 'vs_build.bat'),
- vcvarsPath,
- fileSystem.path.basename(solutionPath),
- 'Release',
- ],
- environment: <String, String>{},
- workingDirectory: fileSystem.path.dirname(solutionPath))
- ).thenAnswer((Invocation invocation) async {
- return mockProcess;
- });
+ processManager = FakeProcessManager.list(<FakeCommand>[
+ cmakeGenerationCommand(),
+ buildCommand('Release',
+ stdout: 'STDOUT STUFF',
+ ),
+ ]);
await createTestCommandRunner(command).run(
const <String>['windows', '--no-pub']
@@ -209,7 +234,7 @@
expect(testLogger.traceText, contains('STDOUT STUFF'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
- ProcessManager: () => mockProcessManager,
+ ProcessManager: () => processManager,
Platform: () => windowsPlatform,
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
@@ -219,21 +244,15 @@
..visualStudioOverride = mockVisualStudio;
applyMocksToCommand(command);
setUpMockProjectFilesForBuild();
- when(mockVisualStudio.vcvarsPath).thenReturn(vcvarsPath);
+ when(mockVisualStudio.cmakePath).thenReturn(cmakePath);
- when(mockProcessManager.start(<String>[
- fileSystem.path.join(flutterRoot, 'packages', 'flutter_tools', 'bin', 'vs_build.bat'),
- vcvarsPath,
- fileSystem.path.basename(solutionPath),
- 'Release',
- ],
- environment: <String, String>{
- 'VERBOSE_SCRIPT_LOGGING': 'true',
- },
- workingDirectory: fileSystem.path.dirname(solutionPath))
- ).thenAnswer((Invocation invocation) async {
- return mockProcess;
- });
+ processManager = FakeProcessManager.list(<FakeCommand>[
+ cmakeGenerationCommand(),
+ buildCommand('Release',
+ verbose: true,
+ stdout: 'STDOUT STUFF',
+ ),
+ ]);
await createTestCommandRunner(command).run(
const <String>['windows', '--no-pub', '-v']
@@ -242,29 +261,24 @@
expect(testLogger.traceText, isNot(contains('STDOUT STUFF')));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
- ProcessManager: () => mockProcessManager,
+ ProcessManager: () => processManager,
Platform: () => windowsPlatform,
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
- testUsingContext('Windows build invokes msbuild and writes generated files', () async {
+ testUsingContext('Windows build invokes build and writes generated files', () async {
final BuildWindowsCommand command = BuildWindowsCommand()
..visualStudioOverride = mockVisualStudio;
applyMocksToCommand(command);
setUpMockProjectFilesForBuild();
- when(mockVisualStudio.vcvarsPath).thenReturn(vcvarsPath);
+ when(mockVisualStudio.cmakePath).thenReturn(cmakePath);
- when(mockProcessManager.start(<String>[
- fileSystem.path.join(flutterRoot, 'packages', 'flutter_tools', 'bin', 'vs_build.bat'),
- vcvarsPath,
- fileSystem.path.basename(solutionPath),
- 'Release',
- ],
- environment: <String, String>{},
- workingDirectory: fileSystem.path.dirname(solutionPath))
- ).thenAnswer((Invocation invocation) async {
- return mockProcess;
- });
+ processManager = FakeProcessManager.list(<FakeCommand>[
+ cmakeGenerationCommand(),
+ buildCommand('Release'),
+ ]);
+ fileSystem.file(fileSystem.path.join('lib', 'other.dart'))
+ .createSync(recursive: true);
await createTestCommandRunner(command).run(
const <String>[
@@ -278,30 +292,40 @@
'--dart-define=foo=a',
'--dart-define=bar=b',
r'--bundle-sksl-path=foo\bar.sksl.json',
- r'--target=lib\main.dart',
+ r'--target=lib\other.dart',
]
);
- // Spot-check important elements from the properties file.
- final File propsFile = fileSystem.file(r'C:\windows\flutter\ephemeral\Generated.props');
- expect(propsFile, exists);
+ final File cmakeConfig = fileSystem.currentDirectory
+ .childDirectory('windows')
+ .childDirectory('flutter')
+ .childDirectory('ephemeral')
+ .childFile('generated_config.cmake');
- final xml.XmlDocument props = xml.parse(propsFile.readAsStringSync());
- expect(props.findAllElements('PropertyGroup').first.getAttribute('Label'), 'UserMacros');
- expect(props.findAllElements('ItemGroup').length, 1);
- expect(props.findAllElements('FLUTTER_ROOT').first.text, flutterRoot);
- expect(props.findAllElements('TRACK_WIDGET_CREATION').first.text, 'true');
- expect(props.findAllElements('TREE_SHAKE_ICONS').first.text, 'true');
- expect(props.findAllElements('EXTRA_GEN_SNAPSHOT_OPTIONS').first.text, '--enable-experiment%3Dnon-nullable');
- expect(props.findAllElements('EXTRA_FRONT_END_OPTIONS').first.text, '--enable-experiment%3Dnon-nullable');
- expect(props.findAllElements('DART_DEFINES').first.text, 'foo%3Da,bar%3Db');
- expect(props.findAllElements('DART_OBFUSCATION').first.text, 'true');
- expect(props.findAllElements('SPLIT_DEBUG_INFO').first.text, r'C:\foo\');
- expect(props.findAllElements('FLUTTER_TARGET').first.text, r'lib\main.dart');
- expect(props.findAllElements('BUNDLE_SKSL_PATH').first.text, r'foo\bar.sksl.json');
+ expect(cmakeConfig, exists);
+
+ final List<String> configLines = cmakeConfig.readAsLinesSync();
+
+ // Backslashes are escaped in the file, which is why this uses both raw
+ // strings and double backslashes.
+ expect(configLines, containsAll(<String>[
+ r'file(TO_CMAKE_PATH "C:\\flutter" FLUTTER_ROOT)',
+ r'file(TO_CMAKE_PATH "C:\\" PROJECT_DIR)',
+ r' "DART_DEFINES=\"foo%3Da,bar%3Db\""',
+ r' "DART_OBFUSCATION=\"true\""',
+ r' "EXTRA_FRONT_END_OPTIONS=\"--enable-experiment%3Dnon-nullable\""',
+ r' "EXTRA_GEN_SNAPSHOT_OPTIONS=\"--enable-experiment%3Dnon-nullable\""',
+ r' "SPLIT_DEBUG_INFO=\"C:\\foo\\\""',
+ r' "TRACK_WIDGET_CREATION=\"true\""',
+ r' "TREE_SHAKE_ICONS=\"true\""',
+ r' "FLUTTER_ROOT=\"C:\\flutter\""',
+ r' "PROJECT_DIR=\"C:\\\""',
+ r' "FLUTTER_TARGET=\"lib\\other.dart\""',
+ r' "BUNDLE_SKSL_PATH=\"foo\\bar.sksl.json\""',
+ ]));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
- ProcessManager: () => mockProcessManager,
+ ProcessManager: () => processManager,
Platform: () => windowsPlatform,
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
@@ -311,26 +335,19 @@
..visualStudioOverride = mockVisualStudio;
applyMocksToCommand(command);
setUpMockProjectFilesForBuild();
- when(mockVisualStudio.vcvarsPath).thenReturn(vcvarsPath);
+ when(mockVisualStudio.cmakePath).thenReturn(cmakePath);
- when(mockProcessManager.start(<String>[
- fileSystem.path.join(flutterRoot, 'packages', 'flutter_tools', 'bin', 'vs_build.bat'),
- vcvarsPath,
- fileSystem.path.basename(solutionPath),
- 'Profile',
- ],
- environment: <String, String>{},
- workingDirectory: fileSystem.path.dirname(solutionPath))
- ).thenAnswer((Invocation invocation) async {
- return mockProcess;
- });
+ processManager = FakeProcessManager.list(<FakeCommand>[
+ cmakeGenerationCommand(),
+ buildCommand('Profile'),
+ ]);
await createTestCommandRunner(command).run(
const <String>['windows', '--profile', '--no-pub']
);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
- ProcessManager: () => mockProcessManager,
+ ProcessManager: () => processManager,
Platform: () => windowsPlatform,
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
diff --git a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
index 2f52ae0..8f39a74 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart
@@ -777,7 +777,7 @@
await runner.run(<String>['create', '--no-pub', projectDir.path]);
- expect(projectDir.childDirectory('windows').childFile('Runner.sln').existsSync(), true);
+ expect(projectDir.childDirectory('windows').childFile('CMakeLists.txt').existsSync(), true);
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
@@ -792,7 +792,7 @@
await runner.run(<String>['create', '--no-pub', projectDir.path]);
- expect(projectDir.childDirectory('windows').childFile('Runner.sln').existsSync(), false);
+ expect(projectDir.childDirectory('windows').childFile('CMakeLists.txt').existsSync(), false);
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: false),
});
@@ -807,7 +807,7 @@
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=windows', projectDir.path]);
- expect(projectDir.childDirectory('windows').childFile('plugin.vcxproj').existsSync(), true);
+ expect(projectDir.childDirectory('windows').childFile('CMakeLists.txt').existsSync(), true);
expect(projectDir.childDirectory('example').childDirectory('windows').existsSync(), true);
validatePubspecForPlugin(projectDir: projectDir.absolute.path, expectedPlatforms: const <String>[
'windows'
@@ -827,7 +827,7 @@
await runner.run(<String>['create', '--no-pub', '--template=plugin', projectDir.path]);
- expect(projectDir.childDirectory('windows').childFile('plugin.vcxproj').existsSync(), false);
+ expect(projectDir.childDirectory('windows').childFile('CMakeLists.txt').existsSync(), false);
expect(projectDir.childDirectory('example').childDirectory('windows').existsSync(), false);
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: false),
diff --git a/packages/flutter_tools/test/general.shard/plugins_test.dart b/packages/flutter_tools/test/general.shard/plugins_test.dart
index 3710040..d155b36 100644
--- a/packages/flutter_tools/test/general.shard/plugins_test.dart
+++ b/packages/flutter_tools/test/general.shard/plugins_test.dart
@@ -80,10 +80,9 @@
when(windowsProject.pluginConfigKey).thenReturn('windows');
final Directory windowsManagedDirectory = flutterProject.directory.childDirectory('windows').childDirectory('flutter');
when(windowsProject.managedDirectory).thenReturn(windowsManagedDirectory);
- when(windowsProject.vcprojFile).thenReturn(windowsManagedDirectory.parent.childFile('Runner.vcxproj'));
- when(windowsProject.solutionFile).thenReturn(windowsManagedDirectory.parent.childFile('Runner.sln'));
+ when(windowsProject.cmakeFile).thenReturn(windowsManagedDirectory.parent.childFile('CMakeLists.txt'));
+ when(windowsProject.generatedPluginCmakeFile).thenReturn(windowsManagedDirectory.childFile('generated_plugins.mk'));
when(windowsProject.pluginSymlinkDirectory).thenReturn(windowsManagedDirectory.childDirectory('ephemeral').childDirectory('.plugin_symlinks'));
- when(windowsProject.generatedPluginPropertySheetFile).thenReturn(windowsManagedDirectory.childFile('GeneratedPlugins.props'));
when(windowsProject.existsSync()).thenReturn(false);
linuxProject = MockLinuxProject();
when(flutterProject.linux).thenReturn(linuxProject);
@@ -323,44 +322,6 @@
project.podManifestLock.createSync(recursive: true);
}
- // Creates a Windows solution file sufficient to allow plugin injection
- // to run without failing.
- void createDummyWindowsSolutionFile() {
- windowsProject.solutionFile.createSync(recursive: true);
- // This isn't a valid solution file, but it's just enough to work with the
- // plugin injection.
- windowsProject.solutionFile.writeAsStringSync('''
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Runner", "Runner.vcxproj", "{3842E94C-E348-463A-ADBE-625A2B69B628}"
- ProjectSection(ProjectDependencies) = postProject
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- EndProjectSection
-EndProject
-Global
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- EndGlobalSection
-EndGlobal''');
- }
-
- // Creates a Windows project file for dummyPackageDirectory sufficient to
- // allow plugin injection to run without failing.
- void createDummyPluginWindowsProjectFile() {
- final File projectFile = dummyPackageDirectory
- .parent
- .childDirectory('windows')
- .childFile('plugin.vcxproj');
- projectFile.createSync(recursive: true);
- // This isn't a valid project file, but it's just enough to work with the
- // plugin injection.
- projectFile.writeAsStringSync('''
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Label="Globals">
- <ProjectGuid>{5919689F-A5D5-462C-AF50-D405CCEF89B8}</ProjectGuid>'}
- <ProjectName>apackage</ProjectName>
- </PropertyGroup>
-</Project>''');
- }
-
group('refreshPlugins', () {
testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () async {
await refreshPluginsList(flutterProject);
@@ -1051,8 +1012,6 @@
when(featureFlags.isWindowsEnabled).thenReturn(true);
when(flutterProject.isModule).thenReturn(false);
configureDummyPackageAsPlugin();
- createDummyWindowsSolutionFile();
- createDummyPluginWindowsProjectFile();
await injectPlugins(flutterProject, checkProjects: true);
@@ -1083,9 +1042,6 @@
dartPluginClass: SomePlugin
''');
- createDummyWindowsSolutionFile();
- createDummyPluginWindowsProjectFile();
-
await injectPlugins(flutterProject, checkProjects: true);
final File registrantImpl = windowsProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@@ -1114,9 +1070,6 @@
dartPluginClass: SomePlugin
''');
- createDummyWindowsSolutionFile();
- createDummyPluginWindowsProjectFile();
-
await injectPlugins(flutterProject, checkProjects: true);
final File registrantImpl = windowsProject.managedDirectory.childFile('generated_plugin_registrant.cc');
@@ -1130,39 +1083,22 @@
FeatureFlags: () => featureFlags,
});
- testUsingContext('Injecting creates generated Windows plugin properties', () async {
+ testUsingContext('Injecting creates generated Windows plugin CMake file', () async {
when(windowsProject.existsSync()).thenReturn(true);
when(featureFlags.isWindowsEnabled).thenReturn(true);
when(flutterProject.isModule).thenReturn(false);
configureDummyPackageAsPlugin();
- createDummyWindowsSolutionFile();
- createDummyPluginWindowsProjectFile();
await injectPlugins(flutterProject, checkProjects: true);
- final File properties = windowsProject.generatedPluginPropertySheetFile;
- final String includePath = fs.path.join('flutter', 'ephemeral', '.plugin_symlinks', 'apackage', 'windows');
+ final File pluginMakefile = windowsProject.generatedPluginCmakeFile;
- expect(properties.existsSync(), isTrue);
- expect(properties.readAsStringSync(), contains('apackage_plugin.lib'));
- expect(properties.readAsStringSync(), contains('>$includePath;'));
- }, overrides: <Type, Generator>{
- FileSystem: () => fs,
- ProcessManager: () => FakeProcessManager.any(),
- FeatureFlags: () => featureFlags,
- });
-
- testUsingContext('Injecting updates Windows solution file', () async {
- when(windowsProject.existsSync()).thenReturn(true);
- when(featureFlags.isWindowsEnabled).thenReturn(true);
- when(flutterProject.isModule).thenReturn(false);
- configureDummyPackageAsPlugin();
- createDummyWindowsSolutionFile();
- createDummyPluginWindowsProjectFile();
-
- await injectPlugins(flutterProject, checkProjects: true);
-
- expect(windowsProject.solutionFile.readAsStringSync(), contains(r'apackage\windows\plugin.vcxproj'));
+ expect(pluginMakefile.existsSync(), isTrue);
+ final String contents = pluginMakefile.readAsStringSync();
+ expect(contents, contains('apackage'));
+ expect(contents, contains('target_link_libraries(\${BINARY_NAME} PRIVATE \${plugin}_plugin)'));
+ expect(contents, contains('list(APPEND PLUGIN_BUNDLED_LIBRARIES \$<TARGET_FILE:\${plugin}_plugin>)'));
+ expect(contents, contains('list(APPEND PLUGIN_BUNDLED_LIBRARIES \${\${plugin}_bundled_libraries})'));
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
diff --git a/packages/flutter_tools/test/general.shard/project_test.dart b/packages/flutter_tools/test/general.shard/project_test.dart
index 21b8f35..52bc3d6 100644
--- a/packages/flutter_tools/test/general.shard/project_test.dart
+++ b/packages/flutter_tools/test/general.shard/project_test.dart
@@ -223,7 +223,7 @@
});
testUsingContext('injects plugins for Linux', () async {
final FlutterProject project = await someProject();
- project.linux.managedDirectory.createSync(recursive: true);
+ project.linux.cmakeFile.createSync(recursive: true);
await project.ensureReadyForPlatformSpecificTooling();
expectExists(project.linux.managedDirectory.childFile('generated_plugin_registrant.h'));
expectExists(project.linux.managedDirectory.childFile('generated_plugin_registrant.cc'));
@@ -238,21 +238,7 @@
});
testUsingContext('injects plugins for Windows', () async {
final FlutterProject project = await someProject();
- project.windows.managedDirectory.createSync(recursive: true);
- project.windows.solutionFile.createSync(recursive: true);
- // Just enough solution file to allow injection to pass.
- // TODO(stuartmorgan): Consider allowing injecting a mock solution util
- // class into the test environment instead.
- project.windows.solutionFile.writeAsStringSync('''
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Runner", "Runner.vcxproj", "{3842E94C-E348-463A-ADBE-625A2B69B628}"
- ProjectSection(ProjectDependencies) = postProject
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- EndProjectSection
-EndProject
-Global
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- EndGlobalSection
-EndGlobal''');
+ project.windows.cmakeFile.createSync(recursive: true);
await project.ensureReadyForPlatformSpecificTooling();
expectExists(project.windows.managedDirectory.childFile('generated_plugin_registrant.h'));
expectExists(project.windows.managedDirectory.childFile('generated_plugin_registrant.cc'));
diff --git a/packages/flutter_tools/test/general.shard/windows/property_sheet_test.dart b/packages/flutter_tools/test/general.shard/windows/property_sheet_test.dart
deleted file mode 100644
index 8b9fec2..0000000
--- a/packages/flutter_tools/test/general.shard/windows/property_sheet_test.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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.
-
-import 'package:flutter_tools/src/windows/property_sheet.dart';
-
-import '../../src/common.dart';
-
-void main() {
- group('Property Sheet', () {
- test('Base file matches expected format', () async {
- const String baseFile = '''
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ImportGroup Label="PropertySheets"/>
- <PropertyGroup Label="UserMacros"/>
- <PropertyGroup/>
- <ItemDefinitionGroup/>
- <ItemGroup/>
-</Project>''';
- const PropertySheet sheet = PropertySheet();
- expect(sheet.toString(), baseFile);
- });
-
- test('Environment variable generate the correct elements', () async {
- const Map<String, String> environment = <String, String>{'FOO': 'Bar'};
- const PropertySheet sheet = PropertySheet(environmentVariables: environment);
- final String propsContent = sheet.toString();
- expect(propsContent, contains('<FOO>Bar</FOO>'));
- expect(propsContent, contains('''
- <BuildMacro Include="FOO">
- <Value>\$(FOO)</Value>
- <EnvironmentVariable>true</EnvironmentVariable>
- </BuildMacro>'''));
- });
-
- test('Include paths generate the correct elements', () async {
- const PropertySheet sheet = PropertySheet(includePaths: <String>['foo/bar', 'baz']);
- final String propsContent = sheet.toString();
- expect(propsContent, contains('<AdditionalIncludeDirectories>foo/bar;baz;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>'));
- });
-
- test('Library dependencies generate the correct elements', () async {
- const PropertySheet sheet = PropertySheet(libraryDependencies: <String>['foo.lib', 'bar.lib']);
- final String propsContent = sheet.toString();
- expect(propsContent, contains('<AdditionalDependencies>foo.lib;bar.lib;%(AdditionalDependencies)</AdditionalDependencies>'));
- });
- });
-}
diff --git a/packages/flutter_tools/test/general.shard/windows/visual_studio_project_test.dart b/packages/flutter_tools/test/general.shard/windows/visual_studio_project_test.dart
deleted file mode 100644
index 47abaeb..0000000
--- a/packages/flutter_tools/test/general.shard/windows/visual_studio_project_test.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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.
-
-import 'package:file/memory.dart';
-import 'package:file_testing/file_testing.dart';
-import 'package:flutter_tools/src/base/file_system.dart';
-import 'package:flutter_tools/src/windows/visual_studio_project.dart';
-
-import '../../src/common.dart';
-
-void main() {
- group('Visual Studio Project', () {
- String generateProjectContents({String guid, String name}) {
- // A bare-bones project.
- return '''
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>15.0</VCProjectVersion>
- ${guid == null ? '' : '<ProjectGuid>{$guid}</ProjectGuid>'}
- ${name == null ? '' : '<ProjectName>$name</ProjectName>'}
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
- <PropertyGroup Label="Configuration">
- <PlatformToolset>v142</PlatformToolset>
- </PropertyGroup>
- <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" />
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup />
- <ItemDefinitionGroup />
- <ItemGroup>
- </ItemGroup>
- <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>''';
- }
-
- test('Property extraction works on a simple vcxproj', () async {
- final FileSystem fileSystem = MemoryFileSystem();
- const String guid = '017C4BAC-FEBA-406D-8A2C-3099FFE9D811';
- const String name = 'Test';
- final File projectFile = fileSystem.file('aproject.vcxproj');
- projectFile.writeAsStringSync(generateProjectContents(guid: guid, name: name));
-
- final VisualStudioProject project = VisualStudioProject(projectFile, fileSystem: fileSystem);
- expect(project.formatUnderstood, true);
- expect(project.guid, guid);
- expect(project.name, name);
- });
-
- test('Missing GUID returns null', () async {
- final FileSystem fileSystem = MemoryFileSystem();
- final File projectFile = fileSystem.file('aproject.vcxproj');
- projectFile.writeAsStringSync(generateProjectContents());
-
- final VisualStudioProject project = VisualStudioProject(projectFile, fileSystem: fileSystem);
- expect(project.formatUnderstood, true);
- expect(project.guid, null);
- });
-
- test('Missing project name uses filename', () async {
- final FileSystem fileSystem = MemoryFileSystem();
- final File projectFile = fileSystem.file('aproject.vcxproj');
- projectFile.writeAsStringSync(generateProjectContents());
-
- final VisualStudioProject project = VisualStudioProject(projectFile, fileSystem: fileSystem);
- expect(project.formatUnderstood, true);
- expect(project.name, 'aproject');
- });
-
- test('Unknown file contents creates an object, and return false for formatUnderstood', () async {
- final FileSystem fileSystem = MemoryFileSystem();
- final File projectFile = fileSystem.file('aproject.vcxproj');
- projectFile.writeAsStringSync('This is not XML!');
-
- final VisualStudioProject project = VisualStudioProject(projectFile, fileSystem: fileSystem);
- expect(project.formatUnderstood, false);
- });
-
- test('Missing project file throws on creation', () async {
- final FileSystem fileSystem = MemoryFileSystem();
- final File projectFile = fileSystem.file('aproject.vcxproj');
-
- expect(() => VisualStudioProject(projectFile, fileSystem: fileSystem), throwsFileSystemException());
- });
- });
-}
diff --git a/packages/flutter_tools/test/general.shard/windows/visual_studio_solution_utils_test.dart b/packages/flutter_tools/test/general.shard/windows/visual_studio_solution_utils_test.dart
deleted file mode 100644
index 2a0ea4f..0000000
--- a/packages/flutter_tools/test/general.shard/windows/visual_studio_solution_utils_test.dart
+++ /dev/null
@@ -1,454 +0,0 @@
-// 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.
-
-import 'package:file/memory.dart';
-import 'package:file_testing/file_testing.dart';
-import 'package:flutter_tools/src/base/file_system.dart';
-import 'package:flutter_tools/src/convert.dart';
-import 'package:flutter_tools/src/plugins.dart';
-import 'package:flutter_tools/src/platform_plugins.dart';
-import 'package:flutter_tools/src/project.dart';
-import 'package:flutter_tools/src/windows/visual_studio_solution_utils.dart';
-import 'package:mockito/mockito.dart';
-
-import '../../src/common.dart';
-
-void main() {
- group('Visual Studio Solution Utils', () {
- // Magic values; see visual_studio_solution_utils.dart.
- const String solutionTypeGuidFolder = '2150E333-8FDC-42A3-9474-1A3956D46DE8';
- const String solutionTypeGuidVcxproj = '8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942';
- const String flutterPluginSolutionFolderGuid = '5C2E738A-1DD3-445A-AAC8-EEB9648DD07C';
-
- // Arbitrary random GUIDs to use for fake plugins.
- const String pluginAGuid = '9F200BC4-A747-43D1-8B72-B778F2C4D048';
- const String pluginBGuid = '39AC79B8-28A6-4526-B5FF-9C83F59B3AF0';
- const String pluginCGuid = '8E010714-28FF-416A-BC6F-9CDE336A02A7';
- const String pluginDGuid = '304F1860-7E8B-4C99-8E1D-F5E55259F5C3';
-
- FileSystem fileSystem;
- MockWindowsProject project;
-
- setUp(() async {
- fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
-
- project = MockWindowsProject();
- when(project.pluginConfigKey).thenReturn('windows');
- final Directory windowsManagedDirectory = fileSystem.directory('C:').childDirectory('windows').childDirectory('flutter');
- when(project.solutionFile).thenReturn(windowsManagedDirectory.parent.childFile('Runner.sln'));
- when(project.vcprojFile).thenReturn(windowsManagedDirectory.parent.childFile('Runner.vcxproj'));
- when(project.pluginSymlinkDirectory).thenReturn(windowsManagedDirectory.childDirectory('ephemeral').childDirectory('.plugin_symlinks'));
- });
-
- // Returns a solution file contents for a solution without any plugins.
- void writeSolutionWithoutPlugins() {
- project.solutionFile.createSync(recursive: true);
- project.solutionFile.writeAsStringSync('''
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29709.97
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Runner", "Runner.vcxproj", "{3842E94C-E348-463A-ADBE-625A2B69B628}"
- ProjectSection(ProjectDependencies) = postProject
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Flutter Build", "FlutterBuild.vcxproj", "{6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Profile|x64 = Profile|x64
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {3842E94C-E348-463A-ADBE-625A2B69B628}.Debug|x64.ActiveCfg = Debug|x64
- {3842E94C-E348-463A-ADBE-625A2B69B628}.Debug|x64.Build.0 = Debug|x64
- {3842E94C-E348-463A-ADBE-625A2B69B628}.Profile|x64.ActiveCfg = Profile|x64
- {3842E94C-E348-463A-ADBE-625A2B69B628}.Profile|x64.Build.0 = Profile|x64
- {3842E94C-E348-463A-ADBE-625A2B69B628}.Release|x64.ActiveCfg = Release|x64
- {3842E94C-E348-463A-ADBE-625A2B69B628}.Release|x64.Build.0 = Release|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.ActiveCfg = Debug|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.Build.0 = Debug|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.ActiveCfg = Profile|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.Build.0 = Profile|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.ActiveCfg = Release|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {B8A69CB0-A974-4774-9EBD-1E5EECACD186}
- EndGlobalSection
-EndGlobal''');
- }
-
- // Returns a solution file contents for a solution with plugins A, B, and C
- // already added.
- void writeSolutionWithPlugins() {
- const String pluginSymlinkSubdirPath = r'Flutter\ephemeral\.plugin_symlinks';
- const String pluginProjectSubpath = r'windows\plugin.vcxproj';
- project.solutionFile.createSync(recursive: true);
- project.solutionFile.writeAsStringSync('''
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29709.97
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Runner", "Runner.vcxproj", "{5A827760-CF8B-408A-99A3-B6C0AD2271E7}"
- ProjectSection(ProjectDependencies) = postProject
- {$pluginAGuid} = {$pluginAGuid}
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- {$pluginBGuid} = {$pluginBGuid}
- {$pluginCGuid} = {$pluginCGuid}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin_a", "$pluginSymlinkSubdirPath\\plugin_a\\$pluginProjectSubpath", "{$pluginAGuid}"
- ProjectSection(ProjectDependencies) = postProject
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Flutter Build", "FlutterBuild.vcxproj", "{6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin_b", "$pluginSymlinkSubdirPath\\plugin_b\\$pluginProjectSubpath", "{$pluginBGuid}"
- ProjectSection(ProjectDependencies) = postProject
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin_c", "$pluginSymlinkSubdirPath\\plugin_c\\$pluginProjectSubpath", "{$pluginCGuid}"
- ProjectSection(ProjectDependencies) = postProject
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Flutter Plugins", "Flutter Plugins", "{5C2E738A-1DD3-445A-AAC8-EEB9648DD07C}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Profile|x64 = Profile|x64
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Debug|x64.ActiveCfg = Debug|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Debug|x64.Build.0 = Debug|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Profile|x64.ActiveCfg = Profile|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Profile|x64.Build.0 = Profile|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Release|x64.ActiveCfg = Release|x64
- {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Release|x64.Build.0 = Release|x64
- {$pluginAGuid}.Debug|x64.ActiveCfg = Debug|x64
- {$pluginAGuid}.Debug|x64.Build.0 = Debug|x64
- {$pluginAGuid}.Profile|x64.ActiveCfg = Profile|x64
- {$pluginAGuid}.Profile|x64.Build.0 = Profile|x64
- {$pluginAGuid}.Release|x64.ActiveCfg = Release|x64
- {$pluginAGuid}.Release|x64.Build.0 = Release|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.ActiveCfg = Debug|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.Build.0 = Debug|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.ActiveCfg = Profile|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.Build.0 = Profile|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.ActiveCfg = Release|x64
- {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.Build.0 = Release|x64
- {$pluginBGuid}.Debug|x64.ActiveCfg = Debug|x64
- {$pluginBGuid}.Debug|x64.Build.0 = Debug|x64
- {$pluginBGuid}.Profile|x64.ActiveCfg = Profile|x64
- {$pluginBGuid}.Profile|x64.Build.0 = Profile|x64
- {$pluginBGuid}.Release|x64.ActiveCfg = Release|x64
- {$pluginBGuid}.Release|x64.Build.0 = Release|x64
- {$pluginCGuid}.Debug|x64.ActiveCfg = Debug|x64
- {$pluginCGuid}.Debug|x64.Build.0 = Debug|x64
- {$pluginCGuid}.Profile|x64.ActiveCfg = Profile|x64
- {$pluginCGuid}.Profile|x64.Build.0 = Profile|x64
- {$pluginCGuid}.Release|x64.ActiveCfg = Release|x64
- {$pluginCGuid}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {$pluginCGuid} = {$flutterPluginSolutionFolderGuid}
- {$pluginBGuid} = {$flutterPluginSolutionFolderGuid}
- {$pluginAGuid} = {$flutterPluginSolutionFolderGuid}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {6C8A8041-10D8-4BEB-B73D-C02BCE62120B}
- EndGlobalSection
-EndGlobal''');
- }
-
- void writeDummyPluginProject(String pluginName, String guid) {
- final File pluginProjectFile = project.pluginSymlinkDirectory
- .childDirectory(pluginName)
- .childDirectory('windows')
- .childFile('plugin.vcxproj');
- pluginProjectFile.createSync(recursive: true);
- pluginProjectFile.writeAsStringSync('''
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>15.0</VCProjectVersion>
- <ProjectGuid>{$guid}</ProjectGuid>
- <ProjectName>$pluginName</ProjectName>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
- <PropertyGroup Label="Configuration">
- <PlatformToolset>v142</PlatformToolset>
- </PropertyGroup>
- <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" />
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup />
- <ItemDefinitionGroup />
- <ItemGroup>
- </ItemGroup>
- <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>''');
- }
-
- // Configures and returns a mock plugin with the given name and GUID in the
- // project's plugin symlink directory.
- Plugin getMockPlugin(String name, String guid, {bool createProject = true}) {
- final MockPlugin plugin = MockPlugin();
- when(plugin.platforms).thenReturn(<String, PluginPlatform>{project.pluginConfigKey: null});
- when(plugin.name).thenReturn(name);
- when(plugin.path).thenReturn(project.pluginSymlinkDirectory.childDirectory(name).path);
- if (createProject) {
- writeDummyPluginProject(name, guid);
- }
- return plugin;
- }
-
- test('Adding the first plugin to a solution adds the expected references', () async {
- writeSolutionWithoutPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- getMockPlugin('plugin_a', pluginAGuid),
- ];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
-
- final String newSolutionContents = project.solutionFile.readAsStringSync();
-
- // Check for:
- // - Plugin project.
- final String pluginSubpath = fileSystem.path.join('Flutter', 'ephemeral', '.plugin_symlinks', 'plugin_a', 'windows', 'plugin.vcxproj');
- expect(newSolutionContents, contains('Project("{$solutionTypeGuidVcxproj}") = "plugin_a", "$pluginSubpath", "{$pluginAGuid}"'));
- // - A dependency on the plugin project (from the Runner).
- expect(newSolutionContents, contains('{$pluginAGuid} = {$pluginAGuid}'));
- // - Plugin project configurations.
- expect(newSolutionContents, contains('{$pluginAGuid}.Debug|x64.ActiveCfg = Debug|x64'));
- expect(newSolutionContents, contains('{$pluginAGuid}.Debug|x64.Build.0 = Debug|x64'));
- expect(newSolutionContents, contains('{$pluginAGuid}.Profile|x64.ActiveCfg = Profile|x64'));
- expect(newSolutionContents, contains('{$pluginAGuid}.Profile|x64.Build.0 = Profile|x64'));
- expect(newSolutionContents, contains('{$pluginAGuid}.Release|x64.ActiveCfg = Release|x64'));
- expect(newSolutionContents, contains('{$pluginAGuid}.Release|x64.Build.0 = Release|x64'));
- // - A plugin folder, and a child reference for the plugin.
- expect(newSolutionContents, contains('Project("{$solutionTypeGuidFolder}") = "Flutter Plugins", "Flutter Plugins", "{$flutterPluginSolutionFolderGuid}"'));
- expect(newSolutionContents, contains('{$pluginAGuid} = {$flutterPluginSolutionFolderGuid}'));
- });
-
- test('Removing a plugin removes entries as expected', () async {
- writeSolutionWithPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- getMockPlugin('plugin_a', pluginAGuid),
- getMockPlugin('plugin_c', pluginCGuid),
- ];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
-
- final String newSolutionContents = project.solutionFile.readAsStringSync();
-
- // There should be no references to plugin B anywhere.
- expect(newSolutionContents.contains(pluginBGuid), false);
-
- // All the plugin A & C references should still be present in modified
- // sections.
- for (final String guid in <String>[pluginAGuid, pluginCGuid]) {
- expect(newSolutionContents, contains('{$guid} = {$guid}'));
- expect(newSolutionContents, contains('{$guid}.Debug|x64.ActiveCfg = Debug|x64'));
- expect(newSolutionContents, contains('{$guid} = {$flutterPluginSolutionFolderGuid}'));
- }
- });
-
- test('Removing all plugins works', () async {
- writeSolutionWithPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- ];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins( plugins);
-
- final String newSolutionContents = project.solutionFile.readAsStringSync();
-
- // There should be no references to any of the plugins.
- expect(newSolutionContents.contains(pluginAGuid), false);
- expect(newSolutionContents.contains(pluginBGuid), false);
- expect(newSolutionContents.contains(pluginCGuid), false);
- // Nor any plugins in the Flutter Plugins folder.
- expect(newSolutionContents.contains('= {$flutterPluginSolutionFolderGuid}'), false);
- });
-
- test('Adjusting the plugin list by adding and removing adjusts entries as expected', () async {
- writeSolutionWithPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- getMockPlugin('plugin_b', pluginBGuid),
- getMockPlugin('plugin_c', pluginCGuid),
- getMockPlugin('plugin_d', pluginDGuid),
- ];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
-
- final String newSolutionContents = project.solutionFile.readAsStringSync();
-
- // There should be no references to plugin A anywhere.
- expect(newSolutionContents.contains(pluginAGuid), false);
-
- // All the plugin B & C references should still be present in modified
- // sections.
- for (final String guid in <String>[pluginBGuid, pluginCGuid]) {
- expect(newSolutionContents, contains('{$guid} = {$guid}'));
- expect(newSolutionContents, contains('{$guid}.Debug|x64.ActiveCfg = Debug|x64'));
- expect(newSolutionContents, contains('{$guid} = {$flutterPluginSolutionFolderGuid}'));
- }
-
- // All the plugin D values should be added:
- // - Plugin project.
- final String pluginSubpath = fileSystem.path.join('Flutter', 'ephemeral', '.plugin_symlinks', 'plugin_d', 'windows', 'plugin.vcxproj');
- expect(newSolutionContents, contains('Project("{$solutionTypeGuidVcxproj}") = "plugin_d", "$pluginSubpath", "{$pluginDGuid}"'));
- // - A dependency on the plugin project (from the Runner).
- expect(newSolutionContents, contains('{$pluginDGuid} = {$pluginDGuid}'));
- // - Plugin project configurations.
- expect(newSolutionContents, contains('{$pluginDGuid}.Debug|x64.ActiveCfg = Debug|x64'));
- expect(newSolutionContents, contains('{$pluginDGuid}.Debug|x64.Build.0 = Debug|x64'));
- expect(newSolutionContents, contains('{$pluginDGuid}.Profile|x64.ActiveCfg = Profile|x64'));
- expect(newSolutionContents, contains('{$pluginDGuid}.Profile|x64.Build.0 = Profile|x64'));
- expect(newSolutionContents, contains('{$pluginDGuid}.Release|x64.ActiveCfg = Release|x64'));
- expect(newSolutionContents, contains('{$pluginDGuid}.Release|x64.Build.0 = Release|x64'));
- // - A child reference for the plugin in the Flutter Plugins folder.
- expect(newSolutionContents, contains('{$pluginDGuid} = {$flutterPluginSolutionFolderGuid}'));
- });
-
- test('Adding plugins doesn\'t create duplicate entries', () async {
- writeSolutionWithPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- getMockPlugin('plugin_a', pluginAGuid),
- getMockPlugin('plugin_b', pluginBGuid),
- getMockPlugin('plugin_c', pluginCGuid),
- getMockPlugin('plugin_d', pluginDGuid),
- ];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
-
- final String newSolutionContents = project.solutionFile.readAsStringSync();
- // There should only be:
- // - one Flutter Plugins folder.
- expect('Project("{$solutionTypeGuidFolder}")'.allMatches(newSolutionContents).length, 1);
- // - one copy of plugin A's project.
- expect('Project("{$solutionTypeGuidVcxproj}") = "plugin_a"'.allMatches(newSolutionContents).length, 1);
- // - one copy of plugin A's configuration entries.
- expect('{$pluginAGuid}.Debug|x64.ActiveCfg = Debug|x64'.allMatches(newSolutionContents).length, 1);
- // - one dependency from the Runner to plugin A.
- expect('{$pluginAGuid} = {$pluginAGuid}'.allMatches(newSolutionContents).length, 1);
- // - one copy of plugin A in Flutter Plugins.
- expect('{$pluginAGuid} = {$flutterPluginSolutionFolderGuid}'.allMatches(newSolutionContents).length, 1);
- });
-
- test('Adding plugins doesn\'t change ordering', () async {
- writeSolutionWithPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- getMockPlugin('plugin_a', pluginAGuid),
- getMockPlugin('plugin_b', pluginBGuid),
- getMockPlugin('plugin_c', pluginCGuid),
- getMockPlugin('plugin_d', pluginDGuid),
- ];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
-
- final String newSolutionContents = project.solutionFile.readAsStringSync();
- // Plugin A should still be before Flutter Build in the Runner dependencies.
- expect(newSolutionContents.indexOf('{$pluginAGuid} = {$pluginAGuid}'),
- lessThan(newSolutionContents.indexOf('{6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}')));
- // ... and in the build configuration list.
- expect(newSolutionContents.indexOf('{$pluginAGuid}.Debug|x64.ActiveCfg = Debug|x64'),
- lessThan(newSolutionContents.indexOf('{6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.ActiveCfg = Debug|x64')));
- // And plugin C should still be before plugin A in the Flutter Plugins nesting list.
- expect(newSolutionContents.indexOf('{$pluginCGuid} = {$flutterPluginSolutionFolderGuid}'),
- lessThan(newSolutionContents.indexOf('{$pluginAGuid} = {$flutterPluginSolutionFolderGuid}')));
- });
-
- test('Updating solution preserves BOM', () async {
- writeSolutionWithPlugins();
-
- final List<Plugin> plugins = <Plugin>[];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
-
- // Visual Studio expects sln files to start with a BOM.
- final List<int> solutionStartingBytes = project.solutionFile.readAsBytesSync().take(3).toList();
- final List<int> bomBytes = utf8.encode(String.fromCharCode(unicodeBomCharacterRune));
- expect(solutionStartingBytes, bomBytes);
- });
-
- test('Updating solution dosen\'t introduce unexpected whitespace', () async {
- writeSolutionWithPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- getMockPlugin('plugin_a', pluginAGuid),
- getMockPlugin('plugin_b', pluginBGuid),
- ];
- await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
-
- final String newSolutionContents = project.solutionFile.readAsStringSync();
- // Project, EndProject, Global, and EndGlobal should be at the start of
- // lines.
- expect(RegExp(r'^[ \t]+Project\(', multiLine: true).hasMatch(newSolutionContents), false);
- expect(RegExp(r'^[ \t]+EndProject\s*$', multiLine: true).hasMatch(newSolutionContents), false);
- expect(RegExp(r'^[ \t]+Global\s*$', multiLine: true).hasMatch(newSolutionContents), false);
- expect(RegExp(r'^[ \t]+EndGlobal\s*$', multiLine: true).hasMatch(newSolutionContents), false);
- // ProjectSection, GlobalSection, and their ends should be indented
- // exactly one tab.
- expect(RegExp(r'^([ \t]+\t|\t[ \t]+)ProjectSection\(', multiLine: true).hasMatch(newSolutionContents), false);
- expect(RegExp(r'^([ \t]+\t|\t[ \t]+)EndProjectSection\s*$', multiLine: true).hasMatch(newSolutionContents), false);
- expect(RegExp(r'^([ \t]+\t|\t[ \t]+)GlobalSection\(\s*$', multiLine: true).hasMatch(newSolutionContents), false);
- expect(RegExp(r'^([ \t]+\t|\t[ \t]+)EndGlobalSection\s*$', multiLine: true).hasMatch(newSolutionContents), false);
- });
-
- test('A plugin without a project exits without crashing', () async {
- writeSolutionWithoutPlugins();
-
- final List<Plugin> plugins = <Plugin>[
- getMockPlugin('plugin_a', pluginAGuid, createProject: false),
- ];
- expect(() => VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins),
- throwsToolExit());
- });
-
- test('A Windows project with a missing Runner.sln file throws a ToolExit', () async {
- final MockWindowsProject windowsProject = MockWindowsProject();
- final File file = fileSystem.file('does_not_exist');
-
- expect(file, isNot(exists));
-
- when(windowsProject.solutionFile).thenReturn(file);
-
- expect(() async => await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem)
- .updatePlugins(<Plugin>[]), throwsToolExit());
- });
- });
-}
-
-class MockWindowsProject extends Mock implements WindowsProject {}
-class MockPlugin extends Mock implements Plugin {}
diff --git a/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart b/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart
index 42b9b04..6eac769 100644
--- a/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart
+++ b/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart
@@ -17,7 +17,7 @@
const String programFilesPath = r'C:\Program Files (x86)';
const String visualStudioPath = programFilesPath + r'\Microsoft Visual Studio\2017\Community';
-const String vcvarsPath = visualStudioPath + r'\VC\Auxiliary\Build\vcvars64.bat';
+const String cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
const String vswherePath = programFilesPath + r'\Microsoft Visual Studio\Installer\vswhere.exe';
final Platform windowsPlatform = FakePlatform(
@@ -71,6 +71,7 @@
const List<String> _requirements = <String>[
'Microsoft.VisualStudio.Workload.NativeDesktop',
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
+ 'Microsoft.VisualStudio.Component.VC.CMake.Project',
];
// Sets up the mock environment so that searching for Visual Studio with
@@ -85,7 +86,7 @@
String responseOverride,
]) {
fileSystem.file(vswherePath).createSync(recursive: true);
- fileSystem.file(vcvarsPath).createSync(recursive: true);
+ fileSystem.file(cmakePath).createSync(recursive: true);
final String finalResponse = responseOverride
?? json.encode(<Map<String, dynamic>>[response]);
final List<String> requirementArguments = requiredComponents == null
@@ -249,7 +250,7 @@
expect(visualStudio.isInstalled, false);
});
- testWithoutContext('vcvarsPath returns null when vswhere is missing', () {
+ testWithoutContext('cmakePath returns null when vswhere is missing', () {
final MockProcessManager mockProcessManager = MockProcessManager();
when(mockProcessManager.runSync(
any,
@@ -265,7 +266,7 @@
processManager: mockProcessManager,
);
- expect(visualStudio.vcvarsPath, isNull);
+ expect(visualStudio.cmakePath, isNull);
});
testWithoutContext(
@@ -587,7 +588,7 @@
expect(visualStudio.hasNecessaryComponents, false);
});
- testWithoutContext('vcvarsPath returns null when VS is present but missing components', () {
+ testWithoutContext('cmakePath returns null when VS is present but missing components', () {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
@@ -607,10 +608,10 @@
fixture.processManager,
);
- expect(visualStudio.vcvarsPath, isNull);
+ expect(visualStudio.cmakePath, isNull);
});
- testWithoutContext('vcvarsPath returns null when VS is present but with require components but installation is faulty', () {
+ testWithoutContext('cmakePath returns null when VS is present but with require components but installation is faulty', () {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
@@ -627,7 +628,7 @@
fixture.processManager,
);
- expect(visualStudio.vcvarsPath, isNull);
+ expect(visualStudio.cmakePath, isNull);
});
testWithoutContext('hasNecessaryComponents returns false when VS is present with required components but installation is faulty', () {
@@ -676,7 +677,7 @@
expect(visualStudio.fullVersion, equals('16.2.29306.81'));
});
- testWithoutContext('vcvarsPath returns null when VS is present but when vswhere returns invalid JSON', () {
+ testWithoutContext('cmakePath returns null when VS is present but when vswhere returns invalid JSON', () {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
@@ -696,7 +697,7 @@
fixture.processManager,
);
- expect(visualStudio.vcvarsPath, isNull);
+ expect(visualStudio.cmakePath, isNull);
});
testWithoutContext('Everything returns good values when VS is present with all components', () {
@@ -722,7 +723,7 @@
expect(visualStudio.isInstalled, true);
expect(visualStudio.isAtLeastMinimumVersion, true);
expect(visualStudio.hasNecessaryComponents, true);
- expect(visualStudio.vcvarsPath, equals(vcvarsPath));
+ expect(visualStudio.cmakePath, equals(cmakePath));
});
testWithoutContext('Metadata is for compatible version when latest is missing components', () {
diff --git a/packages/flutter_tools/test/general.shard/windows/windows_device_test.dart b/packages/flutter_tools/test/general.shard/windows/windows_device_test.dart
index 2641677..18f0f6b 100644
--- a/packages/flutter_tools/test/general.shard/windows/windows_device_test.dart
+++ b/packages/flutter_tools/test/general.shard/windows/windows_device_test.dart
@@ -71,7 +71,7 @@
globals.fs.file('pubspec.yaml').createSync();
globals.fs.file('.packages').createSync();
globals.fs.directory('windows').createSync();
- globals.fs.file(globals.fs.path.join('windows', 'Runner.sln')).createSync();
+ globals.fs.file(globals.fs.path.join('windows', 'CMakeLists.txt')).createSync();
final FlutterProject flutterProject = FlutterProject.current();
expect(WindowsDevice().isSupportedForProject(flutterProject), true);
@@ -91,7 +91,7 @@
ProcessManager: () => FakeProcessManager.any(),
});
- testUsingContext('isSupportedForProject is false with no Runner.sln', () async {
+ testUsingContext('isSupportedForProject is false with no build file', () async {
globals.fs.file('pubspec.yaml').createSync();
globals.fs.file('.packages').createSync();
globals.fs.directory('windows').createSync();