Add support for Visual Studio 2022 (#93426)
This commit is contained in:
parent
9cc47c2b74
commit
7e05d103e9
@ -20,11 +20,6 @@ import '../migrations/cmake_custom_command_migration.dart';
|
||||
import 'install_manifest.dart';
|
||||
import 'visual_studio.dart';
|
||||
|
||||
// From https://cmake.org/cmake/help/v3.14/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';
|
||||
|
||||
/// Update the string when non-backwards compatible changes are made to the UWP template.
|
||||
const int kCurrentUwpTemplateVersion = 0;
|
||||
|
||||
@ -61,7 +56,8 @@ Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, {
|
||||
processManager: globals.processManager,
|
||||
);
|
||||
final String? cmakePath = visualStudio.cmakePath;
|
||||
if (cmakePath == null) {
|
||||
final String? cmakeGenerator = visualStudio.cmakeGenerator;
|
||||
if (cmakePath == null || cmakeGenerator == null) {
|
||||
throwToolExit('Unable to find suitable Visual Studio toolchain. '
|
||||
'Please run `flutter doctor` for more details.');
|
||||
}
|
||||
@ -72,7 +68,12 @@ Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, {
|
||||
'Building Windows application...',
|
||||
);
|
||||
try {
|
||||
await _runCmakeGeneration(cmakePath, buildDirectory, windowsProject.cmakeFile.parent);
|
||||
await _runCmakeGeneration(
|
||||
cmakePath: cmakePath,
|
||||
generator: cmakeGenerator,
|
||||
buildDir: buildDirectory,
|
||||
sourceDir: windowsProject.cmakeFile.parent,
|
||||
);
|
||||
await _runBuild(cmakePath, buildDirectory, buildModeName);
|
||||
} finally {
|
||||
status.cancel();
|
||||
@ -152,7 +153,8 @@ Future<void> buildWindowsUwp(WindowsUwpProject windowsProject, BuildInfo buildIn
|
||||
processManager: globals.processManager,
|
||||
);
|
||||
final String? cmakePath = visualStudio.cmakePath;
|
||||
if (cmakePath == null) {
|
||||
final String? cmakeGenerator = visualStudio.cmakeGenerator;
|
||||
if (cmakePath == null || cmakeGenerator == null) {
|
||||
throwToolExit('Unable to find suitable Visual Studio toolchain. '
|
||||
'Please run `flutter doctor` for more details.');
|
||||
}
|
||||
@ -165,7 +167,12 @@ Future<void> buildWindowsUwp(WindowsUwpProject windowsProject, BuildInfo buildIn
|
||||
// The Cmake re-entrant build does not work for UWP, so the flutter build is
|
||||
// run in advance.
|
||||
await _runFlutterBuild(buildDirectory, buildInfo, target);
|
||||
await _runCmakeGeneration(cmakePath, buildDirectory, windowsProject.cmakeFile.parent);
|
||||
await _runCmakeGeneration(
|
||||
cmakePath: cmakePath,
|
||||
generator: cmakeGenerator,
|
||||
buildDir: buildDirectory,
|
||||
sourceDir: windowsProject.cmakeFile.parent,
|
||||
);
|
||||
await _runBuild(cmakePath, buildDirectory, buildModeName, install: false);
|
||||
} finally {
|
||||
status.cancel();
|
||||
@ -232,7 +239,12 @@ Future<void> _runFlutterBuild(Directory buildDirectory, BuildInfo buildInfo, Str
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _runCmakeGeneration(String cmakePath, Directory buildDir, Directory sourceDir) async {
|
||||
Future<void> _runCmakeGeneration({
|
||||
required String cmakePath,
|
||||
required String generator,
|
||||
required Directory buildDir,
|
||||
required Directory sourceDir,
|
||||
}) async {
|
||||
final Stopwatch sw = Stopwatch()..start();
|
||||
|
||||
await buildDir.create(recursive: true);
|
||||
@ -246,7 +258,7 @@ Future<void> _runCmakeGeneration(String cmakePath, Directory buildDir, Directory
|
||||
'-B',
|
||||
buildDir.path,
|
||||
'-G',
|
||||
_cmakeVisualStudioGeneratorIdentifier,
|
||||
generator,
|
||||
],
|
||||
trace: true,
|
||||
);
|
||||
|
@ -167,6 +167,19 @@ class VisualStudio {
|
||||
]);
|
||||
}
|
||||
|
||||
/// The generator string to pass to CMake to select this Visual Studio
|
||||
/// version.
|
||||
String? get cmakeGenerator {
|
||||
// From https://cmake.org/cmake/help/v3.22/manual/cmake-generators.7.html#visual-studio-generators
|
||||
switch (_majorVersion) {
|
||||
case 17:
|
||||
return 'Visual Studio 17 2022';
|
||||
case 16:
|
||||
default:
|
||||
return 'Visual Studio 16 2019';
|
||||
}
|
||||
}
|
||||
|
||||
/// The major version of the Visual Studio install, as an integer.
|
||||
int? get _majorVersion => fullVersion != null ? int.tryParse(fullVersion!.split('.')[0]) : null;
|
||||
|
||||
|
@ -25,7 +25,8 @@ const String flutterRoot = r'C:\flutter';
|
||||
const String buildFilePath = r'C:\windows\CMakeLists.txt';
|
||||
const String buildUwpFilePath = r'C:\winuwp\CMakeLists.txt';
|
||||
const String visualStudioPath = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community';
|
||||
const String cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
|
||||
const String _cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
|
||||
const String _defaultGenerator = 'Visual Studio 16 2019';
|
||||
|
||||
final Platform windowsPlatform = FakePlatform(
|
||||
operatingSystem: 'windows',
|
||||
@ -45,7 +46,6 @@ void main() {
|
||||
FileSystem fileSystem;
|
||||
|
||||
ProcessManager processManager;
|
||||
FakeVisualStudio fakeVisualStudio;
|
||||
TestUsage usage;
|
||||
|
||||
setUpAll(() {
|
||||
@ -56,7 +56,6 @@ void main() {
|
||||
setUp(() {
|
||||
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
|
||||
Cache.flutterRoot = flutterRoot;
|
||||
fakeVisualStudio = FakeVisualStudio();
|
||||
usage = TestUsage();
|
||||
});
|
||||
|
||||
@ -83,10 +82,14 @@ void main() {
|
||||
|
||||
// Returns the command matching the build_windows call to generate CMake
|
||||
// files.
|
||||
FakeCommand cmakeGenerationCommand({void Function() onRun, bool winuwp = false}) {
|
||||
FakeCommand cmakeGenerationCommand({
|
||||
void Function() onRun,
|
||||
bool winuwp = false,
|
||||
String generator = _defaultGenerator,
|
||||
}) {
|
||||
return FakeCommand(
|
||||
command: <String>[
|
||||
cmakePath,
|
||||
_cmakePath,
|
||||
'-S',
|
||||
fileSystem.path.dirname(winuwp ? buildUwpFilePath : buildFilePath),
|
||||
'-B',
|
||||
@ -95,7 +98,7 @@ void main() {
|
||||
else
|
||||
r'build\windows',
|
||||
'-G',
|
||||
'Visual Studio 16 2019',
|
||||
generator,
|
||||
],
|
||||
onRun: onRun,
|
||||
);
|
||||
@ -110,7 +113,7 @@ void main() {
|
||||
}) {
|
||||
return FakeCommand(
|
||||
command: <String>[
|
||||
cmakePath,
|
||||
_cmakePath,
|
||||
'--build',
|
||||
if (winuwp)
|
||||
r'build\winuwp'
|
||||
@ -132,9 +135,9 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testUsingContext('Windows build fails when there is no vcvars64.bat', () async {
|
||||
testUsingContext('Windows build fails when there is no cmake path', () async {
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
..visualStudioOverride = FakeVisualStudio(cmakePath: null);
|
||||
setUpMockProjectFilesForBuild();
|
||||
|
||||
expect(createTestCommandRunner(command).run(
|
||||
@ -148,7 +151,7 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('Windows build fails when there is no windows project', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockCoreProjectFiles();
|
||||
@ -166,7 +169,7 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('Windows build fails on non windows platform', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -182,7 +185,7 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('Windows build fails when feature is disabled', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -198,7 +201,7 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('Windows build does not spew stdout to status logger', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -223,7 +226,7 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('Windows build extracts errors from stdout', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -281,7 +284,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows verbose build sets VERBOSE_SCRIPT_LOGGING', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -307,7 +310,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows build invokes build and writes generated files', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -372,7 +375,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows profile build passes Profile configuration', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -392,6 +395,29 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('Windows build passes correct generator', () async {
|
||||
const String generator = 'A different generator';
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(
|
||||
cmakeGenerator: generator);
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
cmakeGenerationCommand(generator: generator),
|
||||
buildCommand('Release'),
|
||||
]);
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>['windows', '--release', '--no-pub']
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
Platform: () => windowsPlatform,
|
||||
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
|
||||
});
|
||||
|
||||
testUsingContext('hidden when not enabled on Windows host', () {
|
||||
expect(BuildWindowsCommand().hidden, true);
|
||||
}, overrides: <Type, Generator>{
|
||||
@ -407,7 +433,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Performs code size analysis and sends analytics', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsCommand command = BuildWindowsCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -455,7 +481,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows build fails when there is no windows project', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockCoreProjectFiles();
|
||||
@ -473,7 +499,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows build fails on non windows platform', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockUwpFilesForBuild(0);
|
||||
@ -489,7 +515,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows UWP uild fails on non windows platform', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -505,7 +531,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows UWP build fails when the project version is out of date', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockUwpFilesForBuild(-1);
|
||||
@ -522,7 +548,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows UWP build fails when feature is disabled', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockProjectFilesForBuild();
|
||||
@ -540,7 +566,7 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
});
|
||||
|
||||
testUsingContext('Windows UWP build completes successfully', () async {
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio(cmakePath);
|
||||
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
|
||||
final BuildWindowsUwpCommand command = BuildWindowsUwpCommand()
|
||||
..visualStudioOverride = fakeVisualStudio;
|
||||
setUpMockUwpFilesForBuild(0);
|
||||
@ -575,8 +601,14 @@ C:\foo\windows\runner\main.cpp(17,1): error C2065: 'Baz': undeclared identifier
|
||||
}
|
||||
|
||||
class FakeVisualStudio extends Fake implements VisualStudio {
|
||||
FakeVisualStudio([this.cmakePath]);
|
||||
FakeVisualStudio({
|
||||
this.cmakePath = _cmakePath,
|
||||
this.cmakeGenerator = 'Visual Studio 16 2019',
|
||||
});
|
||||
|
||||
@override
|
||||
final String cmakePath;
|
||||
|
||||
@override
|
||||
final String cmakeGenerator;
|
||||
}
|
||||
|
@ -39,6 +39,20 @@ const Map<String, dynamic> _defaultResponse = <String, dynamic>{
|
||||
},
|
||||
};
|
||||
|
||||
// A minimum version of a response where a VS 2022 installation was found.
|
||||
const Map<String, dynamic> _vs2022Response = <String, dynamic>{
|
||||
'installationPath': visualStudioPath,
|
||||
'displayName': 'Visual Studio Community 2022',
|
||||
'installationVersion': '17.0.31903.59',
|
||||
'isRebootRequired': false,
|
||||
'isComplete': true,
|
||||
'isLaunchable': true,
|
||||
'isPrerelease': false,
|
||||
'catalog': <String, dynamic>{
|
||||
'productDisplayVersion': '17.0.0',
|
||||
},
|
||||
};
|
||||
|
||||
// A minimum version of a response where a Build Tools installation was found.
|
||||
const Map<String, dynamic> _defaultBuildToolsResponse = <String, dynamic>{
|
||||
'installationPath': visualStudioPath,
|
||||
@ -732,6 +746,7 @@ void main() {
|
||||
expect(visualStudio.isAtLeastMinimumVersion, true);
|
||||
expect(visualStudio.hasNecessaryComponents, true);
|
||||
expect(visualStudio.cmakePath, equals(cmakePath));
|
||||
expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019'));
|
||||
});
|
||||
|
||||
testWithoutContext('Everything returns good values when Build Tools is present with all components', () {
|
||||
@ -755,6 +770,23 @@ void main() {
|
||||
expect(visualStudio.cmakePath, equals(cmakePath));
|
||||
});
|
||||
|
||||
testWithoutContext('properties return the right value for Visual Studio 2022', () {
|
||||
final VisualStudioFixture fixture = setUpVisualStudio();
|
||||
final VisualStudio visualStudio = fixture.visualStudio;
|
||||
|
||||
setMockCompatibleVisualStudioInstallation(
|
||||
_vs2022Response,
|
||||
fixture.fileSystem,
|
||||
fixture.processManager,
|
||||
);
|
||||
|
||||
expect(visualStudio.isInstalled, true);
|
||||
expect(visualStudio.isAtLeastMinimumVersion, true);
|
||||
expect(visualStudio.hasNecessaryComponents, true);
|
||||
expect(visualStudio.cmakePath, equals(cmakePath));
|
||||
expect(visualStudio.cmakeGenerator, equals('Visual Studio 17 2022'));
|
||||
});
|
||||
|
||||
testWithoutContext('Metadata is for compatible version when latest is missing components', () {
|
||||
final VisualStudioFixture fixture = setUpVisualStudio();
|
||||
final VisualStudio visualStudio = fixture.visualStudio;
|
||||
|
Loading…
x
Reference in New Issue
Block a user