Unverified Commit e364e30c authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

[tool] Prefer installing multi-arch Win32 binaries (#82668)

Depending on the user's build configuration, we may output
multi-architecture or single-architecture binaries. Prefer to install
the multi-architecture binary if built, otherwise fall back to the
single-architecture binary.
parent 7c5857d3
......@@ -161,7 +161,7 @@ Future<void> buildWindowsUwp(WindowsUwpProject windowsProject, BuildInfo buildIn
final String buildModeName = getNameForBuildMode(buildInfo.mode ?? BuildMode.release);
final Status status = globals.logger.startProgress(
'Building Windows application...',
'Building Windows UWP application...',
);
try {
// The Cmake re-entrant build does not work for UWP, so the flutter build is
......
......@@ -173,6 +173,16 @@ class WindowsUWPDevice extends Device {
return _getPackagePaths(depsDirectory);
}
String _getPackageName(String binaryName, String version, String config, {String/*?*/ architecture}) {
final List<String> components = <String>[
binaryName,
version,
if (architecture != null) architecture,
config,
];
return components.join('_');
}
@override
Future<bool> installApp(covariant BuildableUwpApp app, {String userIdentifier}) async {
/// The cmake build generates an install powershell script.
......@@ -182,18 +192,40 @@ class WindowsUWPDevice extends Device {
if (packageVersion == null) {
return false;
}
final String binaryDir = _fileSystem.path.absolute(
_fileSystem.path.join('build', 'winuwp', 'runner_uwp', 'AppPackages', binaryName));
final String config = toTitleCase(getNameForBuildMode(_buildMode ?? BuildMode.debug));
const String arch = 'x64';
final String generatedDir = '${binaryName}_${packageVersion}_${arch}_${config}_Test';
final String generatedApp = '${binaryName}_${packageVersion}_${arch}_$config';
final String buildDirectory = _fileSystem.path.absolute(_fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', binaryName, generatedDir));
// If a multi-architecture package exists, install that; otherwise install
// the single-architecture package.
final List<String> packageNames = <String>[
// Multi-archtitecture package.
_getPackageName(binaryName, packageVersion, config),
// Single-archtitecture package.
_getPackageName(binaryName, packageVersion, config, architecture: 'x64'),
];
String packageName;
String buildDirectory;
String packagePath;
for (final String name in packageNames) {
packageName = name;
buildDirectory = _fileSystem.path.join(binaryDir, '${packageName}_Test');
if (_fileSystem.isDirectorySync(buildDirectory)) {
packagePath = _getAppPackagePath(buildDirectory);
if (packagePath != null && _fileSystem.isFileSync(packagePath)) {
break;
}
}
}
if (packagePath == null) {
_logger.printError('Failed to locate app package to install');
return false;
}
// Verify package signature.
final String packagePath = _getAppPackagePath(buildDirectory);
if (!await _uwptool.isSignatureValid(packagePath)) {
// If signature is invalid, install the developer certificate.
final String certificatePath = _fileSystem.path.join(buildDirectory, '$generatedApp.cer');
final String certificatePath = _fileSystem.path.join(buildDirectory, '$packageName.cer');
if (_logger.terminal.stdinHasTerminal) {
final String response = await _logger.terminal.promptForCharInput(
<String>['Y', 'y', 'N', 'n'],
......@@ -221,7 +253,7 @@ class WindowsUWPDevice extends Device {
// Install the application and dependencies.
final String packageUri = Uri.file(packagePath).toString();
final List<String> dependencyUris = _getDependencyPaths(buildDirectory, arch)
final List<String> dependencyUris = _getDependencyPaths(buildDirectory, 'x64')
.map((String path) => Uri.file(path).toString())
.toList();
return _uwptool.installApp(packageUri.toString(), dependencyUris);
......
......@@ -176,6 +176,99 @@ void main() {
expect(windowsDevice.executablePathForDevice(fakeApp, BuildMode.release), 'release/executable');
});
testWithoutContext('WinUWPDevice installs cert if not installed', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
uwptool.hasValidSignature = false;
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installCertRequests, hasLength(1));
expect(uwptool.installAppRequests, hasLength(1));
});
testWithoutContext('WinUWPDevice does not install cert if not installed', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
uwptool.hasValidSignature = true;
final String packagePath = fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
);
fileSystem.file(packagePath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installCertRequests, isEmpty);
expect(uwptool.installAppRequests, hasLength(1));
});
testWithoutContext('WinUWPDevice prefers installing multi-arch binaries', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
final String singleArchPath = fileSystem.path.absolute(fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
));
fileSystem.file(singleArchPath).createSync(recursive:true);
final String multiArchPath = fileSystem.path.absolute(fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_Debug_Test', 'testapp_1.2.3.4_Debug.msix',
));
fileSystem.file(multiArchPath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installAppRequests.single.packageUri, Uri.file(multiArchPath).toString());
});
testWithoutContext('WinUWPDevice falls back to installing single-arch binaries', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
final FileSystem fileSystem = MemoryFileSystem.test();
final WindowsUWPDevice windowsDevice = setUpWindowsUwpDevice(
fileSystem: fileSystem,
uwptool: uwptool,
);
final FakeBuildableUwpApp package = FakeBuildableUwpApp();
final String singleArchPath = fileSystem.path.absolute(fileSystem.path.join(
'build', 'winuwp', 'runner_uwp', 'AppPackages', 'testapp',
'testapp_1.2.3.4_x64_Debug_Test', 'testapp_1.2.3.4_x64_Debug.msix',
));
fileSystem.file(singleArchPath).createSync(recursive:true);
final bool result = await windowsDevice.installApp(package);
expect(result, isTrue);
expect(uwptool.installAppRequests.single.packageUri, Uri.file(singleArchPath).toString());
});
testWithoutContext('WinUWPDevice can launch application if cert is installed', () async {
Cache.flutterRoot = '';
final FakeUwpTool uwptool = FakeUwpTool();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment