blob: f816d2cbd70bba7d8ba704afdc172ba9b50dfa95 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file
import 'package:xml/xml.dart' as xml;
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/platform.dart';
import '../base/process_manager.dart';
/// The supported versions of Visual Studio.
const List<String> _visualStudioVersions = <String>['2017', '2019'];
/// The supported flavors of Visual Studio.
const List<String> _visualStudioFlavors = <String>[
'Community',
'Professional',
'Enterprise',
'Preview'
];
/// Returns the path to an installed vcvars64.bat script if found, or null.
Future<String> findVcvars() async {
final String programDir = platform.environment['PROGRAMFILES(X86)'];
final String pathPrefix = fs.path.join(programDir, 'Microsoft Visual Studio');
const String vcvarsScriptName = 'vcvars64.bat';
final String pathSuffix =
fs.path.join('VC', 'Auxiliary', 'Build', vcvarsScriptName);
for (final String version in _visualStudioVersions) {
for (final String flavor in _visualStudioFlavors) {
final String testPath =
fs.path.join(pathPrefix, version, flavor, pathSuffix);
if (fs.file(testPath).existsSync()) {
return testPath;
}
}
}
// If it can't be found manually, check the path.
final ProcessResult whereResult = await processManager.run(<String>[
'where.exe',
vcvarsScriptName,
]);
if (whereResult.exitCode == 0) {
return whereResult.stdout.trim();
}
return null;
}
/// Writes a property sheet (.props) file to expose all of the key/value
/// pairs in [variables] as enivornment variables.
void writePropertySheet(File propertySheetFile, Map<String, String> variables) {
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');
});
_addUserMacros(builder, variables);
builder.element('PropertyGroup');
builder.element('ItemDefinitionGroup');
_addItemGroup(builder, variables);
});
propertySheetFile.createSync(recursive: true);
propertySheetFile.writeAsStringSync(
builder.build().toXmlString(pretty: true, indent: ' '));
}
/// Adds the UserMacros PropertyGroup that defines [variables] to [builder].
void _addUserMacros(xml.XmlBuilder builder, Map<String, String> variables) {
builder.element('PropertyGroup', nest: () {
builder.attribute('Label', 'UserMacros');
for (final MapEntry<String, String> variable in variables.entries) {
builder.element(variable.key, nest: () {
builder.text(variable.value);
});
}
});
}
/// Adds the ItemGroup to expose the given [variables] as environment variables
/// to [builder].
void _addItemGroup(xml.XmlBuilder builder, Map<String, String> variables) {
builder.element('ItemGroup', nest: () {
for (final String name in variables.keys) {
builder.element('BuildMacro', nest: () {
builder.attribute('Include', name);
builder.element('Value', nest: () {
builder.text('\$($name)');
});
builder.element('EnvironmentVariable', nest: () {
builder.text('true');
});
});
}
});
}