Unverified Commit 2dd87fbd authored by Mouad Debbar's avatar Mouad Debbar Committed by GitHub

Fix --local-engine for the new web/wasm mode (#113759)

parent 903e9fb5
......@@ -768,24 +768,22 @@ class CachedLocalEngineArtifacts implements LocalEngineArtifacts {
@override
FileSystemEntity getHostArtifact(
HostArtifact artifact,
) {
FileSystemEntity getHostArtifact(HostArtifact artifact) {
switch (artifact) {
case HostArtifact.engineDartSdkPath:
final String path = _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk');
final String path = _getDartSdkPath();
return _fileSystem.directory(path);
case HostArtifact.engineDartBinary:
final String path = _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', _hostArtifactToFileName(artifact, _platform));
final String path = _fileSystem.path.join(_getDartSdkPath(), 'bin', _hostArtifactToFileName(artifact, _platform));
return _fileSystem.file(path);
case HostArtifact.dart2jsSnapshot:
final String path = _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform));
final String path = _fileSystem.path.join(_getDartSdkPath(), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform));
return _fileSystem.file(path);
case HostArtifact.dartdevcSnapshot:
final String path = _fileSystem.path.join(_dartSdkPath(_cache), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform));
final String path = _fileSystem.path.join(_getDartSdkPath(), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform));
return _fileSystem.file(path);
case HostArtifact.kernelWorkerSnapshot:
final String path = _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform));
final String path = _fileSystem.path.join(_getDartSdkPath(), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform));
return _fileSystem.file(path);
case HostArtifact.flutterWebSdk:
final String path = _getFlutterWebSdkPath();
......@@ -908,7 +906,7 @@ class CachedLocalEngineArtifacts implements LocalEngineArtifacts {
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
case Artifact.frontendServerSnapshotForEngineDartSdk:
return _fileSystem.path.join(
_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName,
_getDartSdkPath(), 'bin', 'snapshots', artifactFileName,
);
}
}
......@@ -923,6 +921,51 @@ class CachedLocalEngineArtifacts implements LocalEngineArtifacts {
buildMode == BuildMode.release ? 'flutter_patched_sdk_product' : 'flutter_patched_sdk');
}
String _getDartSdkPath() {
final String builtPath = _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk');
if (_fileSystem.isDirectorySync(_fileSystem.path.join(builtPath, 'bin'))) {
return builtPath;
}
// If we couldn't find a built dart sdk, let's look for a prebuilt one.
final String prebuiltPath = _fileSystem.path.join(_getFlutterPrebuiltsPath(), _getPrebuiltTarget(), 'dart-sdk');
if (_fileSystem.isDirectorySync(prebuiltPath)) {
return prebuiltPath;
}
throw ToolExit('Unable to find a built dart sdk at: "$builtPath" or a prebuilt dart sdk at: "$prebuiltPath"');
}
String _getFlutterPrebuiltsPath() {
final String engineSrcPath = _fileSystem.path.dirname(_fileSystem.path.dirname(_hostEngineOutPath));
return _fileSystem.path.join(engineSrcPath, 'flutter', 'prebuilts');
}
String _getPrebuiltTarget() {
final TargetPlatform hostPlatform = _currentHostPlatform(_platform, _operatingSystemUtils);
switch (hostPlatform) {
case TargetPlatform.darwin:
return 'macos-x64';
case TargetPlatform.linux_arm64:
return 'linux-arm64';
case TargetPlatform.linux_x64:
return 'linux-x64';
case TargetPlatform.windows_x64:
return 'windows-x64';
case TargetPlatform.ios:
case TargetPlatform.android:
case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
case TargetPlatform.fuchsia_arm64:
case TargetPlatform.fuchsia_x64:
case TargetPlatform.web_javascript:
case TargetPlatform.tester:
throwToolExit('Unsupported host platform: $hostPlatform');
}
}
String _getFlutterWebSdkPath() {
return _fileSystem.path.join(engineOutPath, 'flutter_web_sdk');
}
......
......@@ -252,6 +252,7 @@ class ManifestAssetBundle implements AssetBundle {
flutterManifest,
wildcardDirectories,
assetBasePath,
targetPlatform,
);
if (assetVariants == null) {
......@@ -316,6 +317,7 @@ class ManifestAssetBundle implements AssetBundle {
// Do not track wildcard directories for dependencies.
<Uri>[],
packageBasePath,
targetPlatform,
packageName: package.name,
attributedPackage: package,
);
......@@ -407,10 +409,11 @@ class ManifestAssetBundle implements AssetBundle {
final List<_Asset> materialAssets = <_Asset>[
if (flutterManifest.usesMaterialDesign)
..._getMaterialFonts(),
// Include the shaders unconditionally. They are small, and whether
// they're used is determined only by the app source code and not by
// the Flutter manifest.
..._getMaterialShaders(),
// For non-web platforms, include the shaders unconditionally. They are
// small, and whether they're used is determined only by the app source
// code and not by the Flutter manifest.
if (targetPlatform != TargetPlatform.web_javascript)
..._getMaterialShaders(),
];
for (final _Asset asset in materialAssets) {
final File assetFile = asset.lookupAssetFile(_fileSystem);
......@@ -716,7 +719,8 @@ class ManifestAssetBundle implements AssetBundle {
PackageConfig packageConfig,
FlutterManifest flutterManifest,
List<Uri> wildcardDirectories,
String assetBase, {
String assetBase,
TargetPlatform? targetPlatform, {
String? packageName,
Package? attributedPackage,
}) {
......@@ -750,18 +754,21 @@ class ManifestAssetBundle implements AssetBundle {
}
}
for (final Uri shaderUri in flutterManifest.shaders) {
_parseAssetFromFile(
packageConfig,
flutterManifest,
assetBase,
cache,
result,
shaderUri,
packageName: packageName,
attributedPackage: attributedPackage,
assetKind: AssetKind.shader,
);
// No shader compilation for the web.
if (targetPlatform != TargetPlatform.web_javascript) {
for (final Uri shaderUri in flutterManifest.shaders) {
_parseAssetFromFile(
packageConfig,
flutterManifest,
assetBase,
cache,
result,
shaderUri,
packageName: packageName,
attributedPackage: attributedPackage,
assetKind: AssetKind.shader,
);
}
}
// Add assets referenced in the fonts section of the manifest.
......
......@@ -150,6 +150,11 @@ class LocalEngineLocator {
// Determine the host engine directory associated with the local engine:
// Strip '_sim_' since there are no host simulator builds.
String _getHostEngineBasename(String localEngineBasename) {
if (localEngineBasename.startsWith('web_') || localEngineBasename.startsWith('wasm_')) {
// Don't modify the web local engine's basename.
return localEngineBasename;
}
String tmpBasename = localEngineBasename.replaceFirst('_sim_', '_');
tmpBasename = tmpBasename.substring(tmpBasename.indexOf('_') + 1);
// Strip suffix for various archs.
......
......@@ -273,6 +273,13 @@ void main() {
.childDirectory('ios-arm64_armv7')
.childDirectory('Flutter.framework')
.createSync(recursive: true);
fileSystem
.directory('out')
.childDirectory('host_debug_unopt')
.childDirectory('dart-sdk')
.childDirectory('bin')
.createSync(recursive: true);
expect(
artifacts.getArtifactPath(
Artifact.flutterFramework,
......@@ -325,6 +332,75 @@ void main() {
);
});
testWithoutContext('falls back to prebuilt dart sdk', () {
final String failureMessage = 'Unable to find a built dart sdk at:'
' "${fileSystem.path.join('/out', 'host_debug_unopt', 'dart-sdk')}"'
' or a prebuilt dart sdk at:'
' "${fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk')}"';
expect(
() => artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
throwsToolExit(message: failureMessage),
);
expect(
() => artifacts.getHostArtifact(HostArtifact.engineDartSdkPath),
throwsToolExit(message: failureMessage),
);
expect(
() => artifacts.getHostArtifact(HostArtifact.engineDartBinary),
throwsToolExit(message: failureMessage),
);
expect(
() => artifacts.getHostArtifact(HostArtifact.dart2jsSnapshot),
throwsToolExit(message: failureMessage),
);
expect(
() => artifacts.getHostArtifact(HostArtifact.dartdevcSnapshot),
throwsToolExit(message: failureMessage),
);
expect(
() => artifacts.getHostArtifact(HostArtifact.kernelWorkerSnapshot),
throwsToolExit(message: failureMessage),
);
fileSystem
.directory('flutter')
.childDirectory('prebuilts')
.childDirectory('linux-x64')
.childDirectory('dart-sdk')
.childDirectory('bin')
.createSync(recursive: true);
expect(
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk', 'bin',
'snapshots', 'frontend_server.dart.snapshot'),
);
expect(
artifacts.getHostArtifact(HostArtifact.engineDartSdkPath).path,
fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk'),
);
expect(
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk', 'bin', 'dart'),
);
expect(
artifacts.getHostArtifact(HostArtifact.dart2jsSnapshot).path,
fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk',
'bin', 'snapshots', 'dart2js.dart.snapshot'),
);
expect(
artifacts.getHostArtifact(HostArtifact.dartdevcSnapshot).path,
fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk',
'bin', 'snapshots', 'dartdevc.dart.snapshot'),
);
expect(
artifacts.getHostArtifact(HostArtifact.kernelWorkerSnapshot).path,
fileSystem.path.join('/flutter', 'prebuilts', 'linux-x64', 'dart-sdk',
'bin', 'snapshots', 'kernel_worker.dart.snapshot'),
);
});
testWithoutContext('getEngineType', () {
expect(
artifacts.getEngineType(TargetPlatform.android_arm, BuildMode.debug),
......@@ -351,11 +427,81 @@ void main() {
operatingSystemUtils: FakeOperatingSystemUtils(),
);
expect(artifacts.getHostArtifact(HostArtifact.engineDartBinary).path, contains('.exe'));
fileSystem
.directory('out')
.childDirectory('host_debug_unopt')
.childDirectory('dart-sdk')
.childDirectory('bin')
.createSync(recursive: true);
expect(
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
fileSystem.path.join('/out', 'host_debug_unopt', 'dart-sdk', 'bin', 'dart.exe'),
);
});
testWithoutContext('Looks up dart on linux platforms', () async {
expect(artifacts.getHostArtifact(HostArtifact.engineDartBinary).path, isNot(contains('.exe')));
fileSystem
.directory('/out')
.childDirectory('host_debug_unopt')
.childDirectory('dart-sdk')
.childDirectory('bin')
.createSync(recursive: true);
expect(
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
fileSystem.path.join('/out', 'host_debug_unopt', 'dart-sdk', 'bin', 'dart'),
);
});
testWithoutContext('Finds dart-sdk in windows prebuilts', () async {
artifacts = LocalEngineArtifacts(
fileSystem.path.join(fileSystem.currentDirectory.path, 'out', 'android_debug_unopt'),
fileSystem.path.join(fileSystem.currentDirectory.path, 'out', 'host_debug_unopt'),
cache: cache,
fileSystem: fileSystem,
platform: FakePlatform(operatingSystem: 'windows'),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(),
);
fileSystem
.directory('/flutter')
.childDirectory('prebuilts')
.childDirectory('windows-x64')
.childDirectory('dart-sdk')
.childDirectory('bin')
.createSync(recursive: true);
expect(
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
fileSystem.path.join('/flutter', 'prebuilts', 'windows-x64', 'dart-sdk', 'bin', 'dart.exe'),
);
});
testWithoutContext('Finds dart-sdk in macos prebuilts', () async {
artifacts = LocalEngineArtifacts(
fileSystem.path.join(fileSystem.currentDirectory.path, 'out', 'android_debug_unopt'),
fileSystem.path.join(fileSystem.currentDirectory.path, 'out', 'host_debug_unopt'),
cache: cache,
fileSystem: fileSystem,
platform: FakePlatform(operatingSystem: 'macos'),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(),
);
fileSystem
.directory('/flutter')
.childDirectory('prebuilts')
.childDirectory('macos-x64')
.childDirectory('dart-sdk')
.childDirectory('bin')
.createSync(recursive: true);
expect(
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
fileSystem.path.join('/flutter', 'prebuilts', 'macos-x64', 'dart-sdk', 'bin', 'dart'),
);
});
});
}
......@@ -9,6 +9,7 @@ import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/bundle_builder.dart';
import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
......@@ -457,6 +458,82 @@ flutter:
),
]),
});
testUsingContext('Included shaders are not compiled for the web', () async {
fileSystem.file('.packages').createSync();
fileSystem.file('pubspec.yaml')
..createSync()
..writeAsStringSync(r'''
name: example
flutter:
shaders:
- assets/shader.frag
''');
final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
expect(await bundle.build(packagesPath: '.packages', targetPlatform: TargetPlatform.web_javascript), 0);
await writeBundle(
output,
bundle.entries,
bundle.entryKinds,
loggerOverride: testLogger,
);
}, overrides: <Type, Generator>{
Artifacts: () => artifacts,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
// No impeller commands are expected here because shader compilation is
// not supposed to happen for the web.
]),
});
testUsingContext('Material shaders are not compiled for the web', () async {
fileSystem.file('.packages').createSync();
final String materialIconsPath = fileSystem.path.join(
getFlutterRoot(),
'bin', 'cache', 'artifacts', 'material_fonts',
'MaterialIcons-Regular.otf',
);
fileSystem.file(materialIconsPath).createSync(recursive: true);
final String materialPath = fileSystem.path.join(
getFlutterRoot(),
'packages', 'flutter', 'lib', 'src', 'material',
);
final Directory materialDir = fileSystem.directory(materialPath)..createSync(recursive: true);
for (final String shader in kMaterialShaders) {
materialDir.childFile(shader).createSync(recursive: true);
}
fileSystem.file('pubspec.yaml')
..createSync()
..writeAsStringSync(r'''
name: example
flutter:
uses-material-design: true
''');
final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
expect(await bundle.build(packagesPath: '.packages', targetPlatform: TargetPlatform.web_javascript), 0);
await writeBundle(
output,
bundle.entries,
bundle.entryKinds,
loggerOverride: testLogger,
);
}, overrides: <Type, Generator>{
Artifacts: () => artifacts,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
// No impeller commands are expected here because shader compilation is
// not supposed to happen for the web.
]),
});
});
testUsingContext('Does not insert dummy file into additionalDependencies '
......
......@@ -216,6 +216,52 @@ void main() {
contains('Unable to detect local Flutter engine src directory'),
);
});
testWithoutContext('works for local web engine', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final Directory localWasmEngine = fileSystem
.directory('$kArbitraryEngineRoot/src/out/wasm_whatever/')
..createSync(recursive: true);
final Directory localWebEngine = fileSystem
.directory('$kArbitraryEngineRoot/src/out/web_whatever/')
..createSync(recursive: true);
final BufferLogger wasmLogger = BufferLogger.test();
final LocalEngineLocator localWasmEngineLocator = LocalEngineLocator(
fileSystem: fileSystem,
flutterRoot: 'flutter/flutter',
logger: wasmLogger,
userMessages: UserMessages(),
platform: FakePlatform(environment: <String, String>{}),
);
expect(
await localWasmEngineLocator.findEnginePath(null, localWasmEngine.path, null),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/wasm_whatever',
targetEngine: '/arbitrary/engine/src/out/wasm_whatever',
),
);
expect(wasmLogger.traceText, contains('Local engine source at /arbitrary/engine/src'));
final BufferLogger webLogger = BufferLogger.test();
final LocalEngineLocator localWebEngineLocator = LocalEngineLocator(
fileSystem: fileSystem,
flutterRoot: 'flutter/flutter',
logger: webLogger,
userMessages: UserMessages(),
platform: FakePlatform(environment: <String, String>{}),
);
expect(
await localWebEngineLocator.findEnginePath(null, localWebEngine.path, null),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/web_whatever',
targetEngine: '/arbitrary/engine/src/out/web_whatever',
),
);
expect(webLogger.traceText, contains('Local engine source at /arbitrary/engine/src'));
});
}
Matcher matchesEngineBuildPaths({
......
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