Unverified Commit db1c3e20 authored by Jackson Gardner's avatar Jackson Gardner Committed by GitHub

Platform binaries reland (#115502)

You can now specify a --local-web-sdk flag to point to a wasm_release folder. This will make it so that only artifacts that pertain to the web sdk are overridden to point to the wasm_release folder. Other artifacts (such as impellerc) will pull from the cache, or from the --local-engine path if that is specified.

This also uses precompiled platform kernel files for both ddc and dart2js
parent 08a2635e
......@@ -107,7 +107,7 @@ Future<void> main(List<String> args) async {
// devtools source code.
DevtoolsLauncher: () => DevtoolsServerLauncher(
processManager: globals.processManager,
dartExecutable: globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
dartExecutable: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
logger: globals.logger,
botDetector: globals.botDetector,
),
......
......@@ -277,22 +277,22 @@ class AndroidGradleBuilder implements AndroidBuilder {
if (!buildInfo.androidGradleDaemon) {
command.add('--no-daemon');
}
if (_artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = _artifacts as LocalEngineArtifacts;
final LocalEngineInfo? localEngineInfo = _artifacts.localEngineInfo;
if (localEngineInfo != null) {
final Directory localEngineRepo = _getLocalEngineRepo(
engineOutPath: localEngineArtifacts.engineOutPath,
engineOutPath: localEngineInfo.engineOutPath,
androidBuildInfo: androidBuildInfo,
fileSystem: _fileSystem,
);
_logger.printTrace(
'Using local engine: ${localEngineArtifacts.engineOutPath}\n'
'Using local engine: ${localEngineInfo.engineOutPath}\n'
'Local Maven repo: ${localEngineRepo.path}'
);
command.add('-Plocal-engine-repo=${localEngineRepo.path}');
command.add('-Plocal-engine-build-mode=${buildInfo.modeName}');
command.add('-Plocal-engine-out=${localEngineArtifacts.engineOutPath}');
command.add('-Plocal-engine-out=${localEngineInfo.engineOutPath}');
command.add('-Ptarget-platform=${_getTargetPlatformByLocalEnginePath(
localEngineArtifacts.engineOutPath)}');
localEngineInfo.engineOutPath)}');
} else if (androidBuildInfo.targetArchs.isNotEmpty) {
final String targetPlatforms = androidBuildInfo
.targetArchs
......@@ -611,20 +611,20 @@ class AndroidGradleBuilder implements AndroidBuilder {
);
}
if (_artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = _artifacts as LocalEngineArtifacts;
final LocalEngineInfo? localEngineInfo = _artifacts.localEngineInfo;
if (localEngineInfo != null) {
final Directory localEngineRepo = _getLocalEngineRepo(
engineOutPath: localEngineArtifacts.engineOutPath,
engineOutPath: localEngineInfo.engineOutPath,
androidBuildInfo: androidBuildInfo,
fileSystem: _fileSystem,
);
_logger.printTrace(
'Using local engine: ${localEngineArtifacts.engineOutPath}\n'
'Using local engine: ${localEngineInfo.engineOutPath}\n'
'Local Maven repo: ${localEngineRepo.path}'
);
command.add('-Plocal-engine-repo=${localEngineRepo.path}');
command.add('-Plocal-engine-build-mode=${buildInfo.modeName}');
command.add('-Plocal-engine-out=${localEngineArtifacts.engineOutPath}');
command.add('-Plocal-engine-out=${localEngineInfo.engineOutPath}');
// Copy the local engine repo in the output directory.
try {
......@@ -639,7 +639,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
);
}
command.add('-Ptarget-platform=${_getTargetPlatformByLocalEnginePath(
localEngineArtifacts.engineOutPath)}');
localEngineInfo.engineOutPath)}');
} else if (androidBuildInfo.targetArchs.isNotEmpty) {
final String targetPlatforms = androidBuildInfo.targetArchs
.map(getPlatformNameForAndroidArch).join(',');
......
......@@ -310,10 +310,12 @@ class UserMessages {
'Unable to detect a Flutter engine build directory in $engineSourcePath.\n'
"Please ensure that $engineSourcePath is a Flutter engine 'src' directory and that "
"you have compiled the engine in that directory, which should produce an 'out' directory";
String get runnerLocalEngineRequired =>
'You must specify --local-engine if you are using a locally built engine.';
String get runnerLocalEngineOrWebSdkRequired =>
'You must specify --local-engine or --local-web-sdk if you are using a locally built engine or web sdk.';
String runnerNoEngineBuild(String engineBuildPath) =>
'No Flutter engine build found at $engineBuildPath.';
String runnerNoWebSdk(String webSdkPath) =>
'No Flutter web sdk found at $webSdkPath.';
String runnerWrongFlutterInstance(String flutterRoot, String currentDir) =>
"Warning: the 'flutter' tool you are currently running is not the one from the current directory:\n"
' running Flutter : $flutterRoot\n'
......
......@@ -13,6 +13,7 @@ import 'base/os.dart';
import 'base/utils.dart';
import 'convert.dart';
import 'globals.dart' as globals;
import 'web/compile.dart';
/// Whether icon font subsetting is enabled by default.
const bool kIconTreeShakerEnabledDefault = true;
......@@ -35,6 +36,7 @@ class BuildInfo {
List<String>? dartDefines,
this.bundleSkSLPath,
List<String>? dartExperiments,
this.webRenderer = WebRendererMode.autoDetect,
required this.treeShakeIcons,
this.performanceMeasurementFile,
this.dartDefineConfigJsonMap,
......@@ -124,6 +126,9 @@ class BuildInfo {
/// A list of Dart experiments.
final List<String> dartExperiments;
/// When compiling to web, which web renderer mode we are using (html, canvaskit, auto)
final WebRendererMode webRenderer;
/// The name of a file where flutter assemble will output performance
/// information in a JSON format.
///
......@@ -606,8 +611,9 @@ List<DarwinArch> defaultIOSArchsForEnvironment(
Artifacts artifacts,
) {
// Handle single-arch local engines.
if (artifacts is LocalEngineArtifacts) {
final String localEngineName = artifacts.localEngineName;
final LocalEngineInfo? localEngineInfo = artifacts.localEngineInfo;
if (localEngineInfo != null) {
final String localEngineName = localEngineInfo.localEngineName;
if (localEngineName.contains('_arm64')) {
return <DarwinArch>[ DarwinArch.arm64 ];
}
......@@ -628,8 +634,9 @@ List<DarwinArch> defaultIOSArchsForEnvironment(
/// The default set of macOS device architectures to build for.
List<DarwinArch> defaultMacOSArchsForEnvironment(Artifacts artifacts) {
// Handle single-arch local engines.
if (artifacts is LocalEngineArtifacts) {
if (artifacts.localEngineName.contains('_arm64')) {
final LocalEngineInfo? localEngineInfo = artifacts.localEngineInfo;
if (localEngineInfo != null) {
if (localEngineInfo.localEngineName.contains('_arm64')) {
return <DarwinArch>[ DarwinArch.arm64 ];
}
return <DarwinArch>[ DarwinArch.x86_64 ];
......@@ -855,6 +862,10 @@ HostPlatform getCurrentHostPlatform() {
return HostPlatform.linux_x64;
}
FileSystemEntity getWebPlatformBinariesDirectory(Artifacts artifacts, WebRendererMode webRenderer) {
return artifacts.getHostArtifact(HostArtifact.webPlatformKernelFolder);
}
/// Returns the top-level build output directory.
String getBuildDirectory([Config? config, FileSystem? fileSystem]) {
// TODO(johnmccutchan): Stop calling this function as part of setting
......
......@@ -182,7 +182,7 @@ class AndroidAot extends AotElfBase {
List<Source> get inputs => <Source>[
const Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/android.dart'),
const Source.pattern('{BUILD_DIR}/app.dill'),
const Source.hostArtifact(HostArtifact.engineDartBinary),
const Source.artifact(Artifact.engineDartBinary),
const Source.artifact(Artifact.skyEnginePath),
Source.artifact(Artifact.genSnapshot,
mode: buildMode,
......
......@@ -132,7 +132,7 @@ class KernelSnapshot extends Target {
Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
Source.artifact(Artifact.platformKernelDill),
Source.hostArtifact(HostArtifact.engineDartBinary),
Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.frontendServerSnapshotForEngineDartSdk),
];
......@@ -317,7 +317,7 @@ class AotElfProfile extends AotElfBase {
List<Source> get inputs => <Source>[
const Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
const Source.pattern('{BUILD_DIR}/app.dill'),
const Source.hostArtifact(HostArtifact.engineDartBinary),
const Source.artifact(Artifact.engineDartBinary),
const Source.artifact(Artifact.skyEnginePath),
Source.artifact(Artifact.genSnapshot,
platform: targetPlatform,
......@@ -349,7 +349,7 @@ class AotElfRelease extends AotElfBase {
List<Source> get inputs => <Source>[
const Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
const Source.pattern('{BUILD_DIR}/app.dill'),
const Source.hostArtifact(HostArtifact.engineDartBinary),
const Source.artifact(Artifact.engineDartBinary),
const Source.artifact(Artifact.skyEnginePath),
Source.artifact(Artifact.genSnapshot,
platform: targetPlatform,
......
......@@ -106,7 +106,7 @@ class IconTreeShaker {
_artifacts.getArtifactPath(Artifact.constFinder),
);
final File dart = _fs.file(
_artifacts.getHostArtifact(HostArtifact.engineDartBinary),
_artifacts.getArtifactPath(Artifact.engineDartBinary),
);
final Map<String, List<int>> iconData = await _findConstants(
......
......@@ -142,7 +142,7 @@ class AotAssemblyRelease extends AotAssemblyBase {
List<Source> get inputs => const <Source>[
Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/ios.dart'),
Source.pattern('{BUILD_DIR}/app.dill'),
Source.hostArtifact(HostArtifact.engineDartBinary),
Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.skyEnginePath),
// TODO(zanderso): cannot reference gen_snapshot with artifacts since
// it resolves to a file (ios/gen_snapshot) that never exists. This was
......@@ -177,7 +177,7 @@ class AotAssemblyProfile extends AotAssemblyBase {
List<Source> get inputs => const <Source>[
Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/ios.dart'),
Source.pattern('{BUILD_DIR}/app.dill'),
Source.hostArtifact(HostArtifact.engineDartBinary),
Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.skyEnginePath),
// TODO(zanderso): cannot reference gen_snapshot with artifacts since
// it resolves to a file (ios/gen_snapshot) that never exists. This was
......
......@@ -18,6 +18,7 @@ import '../../dart/package_map.dart';
import '../../flutter_plugins.dart';
import '../../globals.dart' as globals;
import '../../project.dart';
import '../../web/compile.dart';
import '../../web/file_generators/flutter_js.dart' as flutter_js;
import '../../web/file_generators/flutter_service_worker_js.dart';
import '../../web/file_generators/main_dart.dart' as main_dart;
......@@ -141,7 +142,9 @@ class WebEntrypointTarget extends Target {
/// Compiles a web entry point with dart2js.
class Dart2JSTarget extends Target {
const Dart2JSTarget();
const Dart2JSTarget(this.webRenderer);
final WebRendererMode webRenderer;
@override
String get name => 'dart2js';
......@@ -155,8 +158,8 @@ class Dart2JSTarget extends Target {
@override
List<Source> get inputs => const <Source>[
Source.hostArtifact(HostArtifact.flutterWebSdk),
Source.hostArtifact(HostArtifact.dart2jsSnapshot),
Source.hostArtifact(HostArtifact.engineDartBinary),
Source.artifact(Artifact.dart2jsSnapshot),
Source.artifact(Artifact.engineDartBinary),
Source.pattern('{BUILD_DIR}/main.dart'),
Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
];
......@@ -189,12 +192,12 @@ class Dart2JSTarget extends Target {
final bool sourceMapsEnabled = environment.defines[kSourceMapsEnabled] == 'true';
final bool nativeNullAssertions = environment.defines[kNativeNullAssertions] == 'true';
final Artifacts artifacts = globals.artifacts!;
final String librariesSpec = (artifacts.getHostArtifact(HostArtifact.flutterWebSdk) as Directory).childFile('libraries.json').path;
final String platformBinariesPath = getWebPlatformBinariesDirectory(artifacts, webRenderer).path;
final List<String> sharedCommandOptions = <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary, platform: TargetPlatform.web_javascript),
'--disable-dart-dev',
artifacts.getHostArtifact(HostArtifact.dart2jsSnapshot).path,
'--libraries-spec=$librariesSpec',
artifacts.getArtifactPath(Artifact.dart2jsSnapshot, platform: TargetPlatform.web_javascript),
'--platform-binaries=$platformBinariesPath',
...decodeCommaSeparated(environment.defines, kExtraFrontEndOptions),
if (nativeNullAssertions)
'--native-null-assertions',
......@@ -269,14 +272,16 @@ class Dart2JSTarget extends Target {
/// Unpacks the dart2js compilation and resources to a given output directory.
class WebReleaseBundle extends Target {
const WebReleaseBundle();
const WebReleaseBundle(this.webRenderer);
final WebRendererMode webRenderer;
@override
String get name => 'web_release_bundle';
@override
List<Target> get dependencies => const <Target>[
Dart2JSTarget(),
List<Target> get dependencies => <Target>[
Dart2JSTarget(webRenderer),
];
@override
......@@ -454,18 +459,19 @@ class WebBuiltInAssets extends Target {
/// Generate a service worker for a web target.
class WebServiceWorker extends Target {
const WebServiceWorker(this.fileSystem, this.cache);
const WebServiceWorker(this.fileSystem, this.cache, this.webRenderer);
final FileSystem fileSystem;
final Cache cache;
final WebRendererMode webRenderer;
@override
String get name => 'web_service_worker';
@override
List<Target> get dependencies => <Target>[
const Dart2JSTarget(),
const WebReleaseBundle(),
Dart2JSTarget(webRenderer),
WebReleaseBundle(webRenderer),
WebBuiltInAssets(fileSystem, cache),
];
......
......@@ -84,7 +84,7 @@ abstract class AnalyzeBase {
if (dartSdk != null) {
return dartSdk;
}
return artifacts.getHostArtifact(HostArtifact.engineDartSdkPath).path;
return artifacts.getArtifactPath(Artifact.engineDartSdkPath);
}
bool get isBenchmarking => argResults['benchmark'] as bool;
String? get protocolTrafficLog => argResults['protocol-traffic-log'] as String?;
......
......@@ -18,7 +18,6 @@ import '../build_system/targets/deferred_components.dart';
import '../build_system/targets/ios.dart';
import '../build_system/targets/linux.dart';
import '../build_system/targets/macos.dart';
import '../build_system/targets/web.dart';
import '../build_system/targets/windows.dart';
import '../cache.dart';
import '../convert.dart';
......@@ -48,8 +47,6 @@ List<Target> _kDefaultTargets = <Target>[
const ProfileBundleLinuxAssets(TargetPlatform.linux_arm64),
const ReleaseBundleLinuxAssets(TargetPlatform.linux_x64),
const ReleaseBundleLinuxAssets(TargetPlatform.linux_arm64),
// Web targets
WebServiceWorker(globals.fs, globals.cache),
const ReleaseAndroidApplication(),
// This is a one-off rule for bundle and aot compat.
const CopyFlutterBundle(),
......
......@@ -237,7 +237,7 @@ class DriveCommand extends RunCommandBase {
applicationPackageFactory: ApplicationPackageFactory.instance!,
logger: _logger,
processUtils: globals.processUtils,
dartSdkPath: globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
dartSdkPath: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
devtoolsLauncher: DevtoolsLauncher.instance!,
);
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
......
......@@ -45,7 +45,7 @@ class FormatCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final String dartBinary = globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path;
final String dartBinary = globals.artifacts!.getArtifactPath(Artifact.engineDartBinary);
final List<String> command = <String>[
dartBinary,
'format',
......
......@@ -301,7 +301,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
if (outputFileList.isEmpty) {
return FlutterCommandResult.success();
}
final String dartBinary = _artifacts.getHostArtifact(HostArtifact.engineDartBinary).path;
final String dartBinary = _artifacts.getArtifactPath(Artifact.engineDartBinary);
final List<String> command = <String>[dartBinary, 'format', ...outputFileList];
final ProcessResult result = await _processManager.run(command);
if (result.exitCode != 0) {
......
......@@ -248,14 +248,16 @@ class KernelCompiler {
required List<String> dartDefines,
required PackageConfig packageConfig,
}) async {
final TargetPlatform? platform = targetModel == TargetModel.dartdevc ? TargetPlatform.web_javascript : null;
final String frontendServer = _artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk
Artifact.frontendServerSnapshotForEngineDartSdk,
platform: platform,
);
// This is a URI, not a file path, so the forward slash is correct even on Windows.
if (!sdkRoot.endsWith('/')) {
sdkRoot = '$sdkRoot/';
}
final String engineDartPath = _artifacts.getHostArtifact(HostArtifact.engineDartBinary).path;
final String engineDartPath = _artifacts.getArtifactPath(Artifact.engineDartBinary, platform: platform);
if (!_processManager.canRun(engineDartPath)) {
throwToolExit('Unable to find Dart binary at $engineDartPath');
}
......@@ -740,11 +742,13 @@ class DefaultResidentCompiler implements ResidentCompiler {
String? outputPath,
{String? additionalSourceUri}
) async {
final TargetPlatform? platform = (targetModel == TargetModel.dartdevc) ? TargetPlatform.web_javascript : null;
final String frontendServer = _artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk
Artifact.frontendServerSnapshotForEngineDartSdk,
platform: platform,
);
final List<String> command = <String>[
_artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
_artifacts.getArtifactPath(Artifact.engineDartBinary, platform: platform),
'--disable-dart-dev',
frontendServer,
'--sdk-root',
......
......@@ -208,7 +208,7 @@ Future<T> runInContext<T>(
),
DevtoolsLauncher: () => DevtoolsServerLauncher(
processManager: globals.processManager,
dartExecutable: globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
dartExecutable: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
logger: globals.logger,
botDetector: globals.botDetector,
),
......
......@@ -70,7 +70,7 @@ class FuchsiaKernelCompiler {
'$multiRootScheme:///$target',
];
final String? engineDartBinaryPath = globals.artifacts?.getHostArtifact(HostArtifact.engineDartBinary).path;
final String? engineDartBinaryPath = globals.artifacts?.getArtifactPath(Artifact.engineDartBinary);
if (engineDartBinaryPath == null) {
throwToolExit('Engine dart binary not found at "$engineDartBinaryPath"');
}
......
......@@ -170,13 +170,12 @@ Future<List<String>> _xcodeBuildSettingsLines({
final String buildNumber = parsedBuildNumber(manifest: project.manifest, buildInfo: buildInfo) ?? '1';
xcodeBuildSettings.add('FLUTTER_BUILD_NUMBER=$buildNumber');
final Artifacts? artifacts = globals.artifacts;
if (artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = artifacts;
final String engineOutPath = localEngineArtifacts.engineOutPath;
final LocalEngineInfo? localEngineInfo = globals.artifacts?.localEngineInfo;
if (localEngineInfo != null) {
final String engineOutPath = localEngineInfo.engineOutPath;
xcodeBuildSettings.add('FLUTTER_ENGINE=${globals.fs.path.dirname(globals.fs.path.dirname(engineOutPath))}');
final String localEngineName = localEngineArtifacts.localEngineName;
final String localEngineName = localEngineInfo.localEngineName;
xcodeBuildSettings.add('LOCAL_ENGINE=$localEngineName');
// Tell Xcode not to build universal binaries for local engines, which are
......
......@@ -561,8 +561,9 @@ class WebAssetServer implements AssetReader {
// Otherwise it must be a Dart SDK source or a Flutter Web SDK source.
final Directory dartSdkParent = globals.fs
.directory(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath))
.directory(globals.artifacts!.getArtifactPath(
Artifact.engineDartSdkPath,
platform: TargetPlatform.web_javascript))
.parent;
final File dartSdkFile = globals.fs.file(dartSdkParent.uri.resolve(path));
if (dartSdkFile.existsSync()) {
......@@ -926,7 +927,7 @@ class WebDevFS implements DevFS {
@visibleForTesting
final File requireJS = globals.fs.file(globals.fs.path.join(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartSdkPath, platform: TargetPlatform.web_javascript),
'lib',
'dev_compiler',
'kernel',
......@@ -936,7 +937,7 @@ class WebDevFS implements DevFS {
@visibleForTesting
final File stackTraceMapper = globals.fs.file(globals.fs.path.join(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartSdkPath, platform: TargetPlatform.web_javascript),
'lib',
'dev_compiler',
'web',
......
......@@ -24,8 +24,8 @@ class SdkWebConfigurationProvider extends SdkConfigurationProvider {
Future<SdkConfiguration> get configuration async {
if (_configuration == null) {
final String sdkDir = _artifacts.getHostArtifact(HostArtifact.flutterWebSdk).path;
final String unsoundSdkSummaryPath = _artifacts.getHostArtifact(HostArtifact.webPlatformKernelDill).path;
final String soundSdkSummaryPath = _artifacts.getHostArtifact(HostArtifact.webPlatformSoundKernelDill).path;
final String unsoundSdkSummaryPath = _artifacts.getHostArtifact(HostArtifact.webPlatformDDCKernelDill).path;
final String soundSdkSummaryPath = _artifacts.getHostArtifact(HostArtifact.webPlatformDDCSoundKernelDill).path;
final String librariesPath = _artifacts.getHostArtifact(HostArtifact.flutterWebLibrariesJson).path;
_configuration = SdkConfiguration(
......
......@@ -53,12 +53,11 @@ Future<void> buildLinux(
// step.
final Map<String, String> environmentConfig = buildInfo.toEnvironmentConfig();
environmentConfig['FLUTTER_TARGET'] = target;
final Artifacts? artifacts = globals.artifacts;
if (artifacts is LocalEngineArtifacts) {
final LocalEngineArtifacts localEngineArtifacts = artifacts;
final String engineOutPath = localEngineArtifacts.engineOutPath;
final LocalEngineInfo? localEngineInfo = globals.artifacts?.localEngineInfo;
if (localEngineInfo != null) {
final String engineOutPath = localEngineInfo.engineOutPath;
environmentConfig['FLUTTER_ENGINE'] = globals.fs.path.dirname(globals.fs.path.dirname(engineOutPath));
environmentConfig['LOCAL_ENGINE'] = localEngineArtifacts.localEngineName;
environmentConfig['LOCAL_ENGINE'] = localEngineInfo.localEngineName;
}
writeGeneratedCmakeConfig(Cache.flutterRoot!, linuxProject, buildInfo, environmentConfig);
......
......@@ -107,15 +107,15 @@ class FlutterDevice {
// used to file a bug, but the compiler will still start up correctly.
if (targetPlatform == TargetPlatform.web_javascript) {
// TODO(zanderso): consistently provide these flags across platforms.
late HostArtifact platformDillArtifact;
late String platformDillName;
final List<String> extraFrontEndOptions = List<String>.of(buildInfo.extraFrontEndOptions);
if (buildInfo.nullSafetyMode == NullSafetyMode.unsound) {
platformDillArtifact = HostArtifact.webPlatformKernelDill;
platformDillName = 'ddc_outline.dill';
if (!extraFrontEndOptions.contains('--no-sound-null-safety')) {
extraFrontEndOptions.add('--no-sound-null-safety');
}
} else if (buildInfo.nullSafetyMode == NullSafetyMode.sound) {
platformDillArtifact = HostArtifact.webPlatformSoundKernelDill;
platformDillName = 'ddc_outline_sound.dill';
if (!extraFrontEndOptions.contains('--sound-null-safety')) {
extraFrontEndOptions.add('--sound-null-safety');
}
......@@ -123,6 +123,11 @@ class FlutterDevice {
assert(false);
}
final String platformDillPath = globals.fs.path.join(
getWebPlatformBinariesDirectory(globals.artifacts!, buildInfo.webRenderer).path,
platformDillName
);
generator = ResidentCompiler(
globals.artifacts!.getHostArtifact(HostArtifact.flutterWebSdk).path,
buildMode: buildInfo.mode,
......@@ -139,9 +144,7 @@ class FlutterDevice {
assumeInitializeFromDillUpToDate: buildInfo.assumeInitializeFromDillUpToDate,
targetModel: TargetModel.dartdevc,
extraFrontEndOptions: extraFrontEndOptions,
platformDill: globals.fs.file(globals.artifacts!
.getHostArtifact(platformDillArtifact))
.absolute.uri.toString(),
platformDill: globals.fs.file(platformDillPath).absolute.uri.toString(),
dartDefines: buildInfo.dartDefines,
librariesSpec: globals.fs.file(globals.artifacts!
.getHostArtifact(HostArtifact.flutterWebLibrariesJson)).uri.toString(),
......
......@@ -29,6 +29,7 @@ import '../features.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../reporting/reporting.dart';
import '../web/compile.dart';
import 'flutter_command_runner.dart';
export '../cache.dart' show DevelopmentArtifact;
......@@ -122,6 +123,7 @@ class FlutterOptions {
static const String kFatalWarnings = 'fatal-warnings';
static const String kUseApplicationBinary = 'use-application-binary';
static const String kWebBrowserFlag = 'web-browser-flag';
static const String kWebRendererFlag = 'web-renderer';
}
/// flutter command categories for usage.
......@@ -149,17 +151,25 @@ abstract class FlutterCommand extends Command<void> {
/// The flag name for whether or not to use ipv6.
static const String ipv6Flag = 'ipv6';
/// The map used to convert web-renderer option to a List of dart-defines.
static const Map<String, Iterable<String>> _webRendererDartDefines =
<String, Iterable<String>> {
'auto': <String>[
/// Maps command line web renderer strings to the corresponding web renderer mode
static const Map<String, WebRendererMode> _webRendererModeMap =
<String, WebRendererMode> {
'auto': WebRendererMode.autoDetect,
'canvaskit': WebRendererMode.canvaskit,
'html': WebRendererMode.html,
};
/// The map used to convert web renderer mode to a List of dart-defines.
static const Map<WebRendererMode, Iterable<String>> _webRendererDartDefines =
<WebRendererMode, Iterable<String>> {
WebRendererMode.autoDetect: <String>[
'FLUTTER_WEB_AUTO_DETECT=true',
],
'canvaskit': <String>[
WebRendererMode.canvaskit: <String>[
'FLUTTER_WEB_AUTO_DETECT=false',
'FLUTTER_WEB_USE_SKIA=true',
],
'html': <String>[
WebRendererMode.html: <String>[
'FLUTTER_WEB_AUTO_DETECT=false',
'FLUTTER_WEB_USE_SKIA=false',
],
......@@ -620,7 +630,8 @@ abstract class FlutterCommand extends Command<void> {
}
void usesWebRendererOption() {
argParser.addOption('web-renderer',
argParser.addOption(
FlutterOptions.kWebRendererFlag,
defaultsTo: 'auto',
allowed: <String>['auto', 'canvaskit', 'html'],
help: 'The renderer implementation to use when building for the web.',
......@@ -1144,8 +1155,13 @@ abstract class FlutterCommand extends Command<void> {
? stringsArg(FlutterOptions.kDartDefinesOption)
: <String>[];
if (argParser.options.containsKey('web-renderer')) {
dartDefines = updateDartDefines(dartDefines, stringArgDeprecated('web-renderer')!);
WebRendererMode webRenderer = WebRendererMode.autoDetect;
if (argParser.options.containsKey(FlutterOptions.kWebRendererFlag)) {
final WebRendererMode? mappedMode = _webRendererModeMap[stringArgDeprecated(FlutterOptions.kWebRendererFlag)!];
if (mappedMode != null) {
webRenderer = mappedMode;
}
dartDefines = updateDartDefines(dartDefines, webRenderer);
}
Map<String, Object>? defineConfigJsonMap;
......@@ -1192,6 +1208,7 @@ abstract class FlutterCommand extends Command<void> {
dartDefines: dartDefines,
bundleSkSLPath: bundleSkSLPath,
dartExperiments: experiments,
webRenderer: webRenderer,
performanceMeasurementFile: performanceMeasurementFile,
dartDefineConfigJsonMap: defineConfigJsonMap,
packagesPath: packagesPath ?? globals.fs.path.absolute('.dart_tool', 'package_config.json'),
......@@ -1285,7 +1302,7 @@ abstract class FlutterCommand extends Command<void> {
/// Updates dart-defines based on [webRenderer].
@visibleForTesting
static List<String> updateDartDefines(List<String> dartDefines, String webRenderer) {
static List<String> updateDartDefines(List<String> dartDefines, WebRendererMode webRenderer) {
final Set<String> dartDefinesSet = dartDefines.toSet();
if (!dartDefines.any((String d) => d.startsWith('FLUTTER_WEB_AUTO_DETECT='))
&& dartDefines.any((String d) => d.startsWith('FLUTTER_WEB_USE_SKIA='))) {
......
......@@ -96,7 +96,13 @@ class FlutterCommandRunner extends CommandRunner<void> {
hide: !verboseHelp,
help: 'Name of a build output within the engine out directory, if you are building Flutter locally.\n'
'Use this to select a specific version of the engine if you have built multiple engine targets.\n'
'This path is relative to "--local-engine-src-path" or "--local-engine-src-out" (q.v.).');
'This path is relative to "--local-engine-src-path" (see above).');
argParser.addOption('local-web-sdk',
hide: !verboseHelp,
help: 'Name of a build output within the engine out directory, if you are building Flutter locally.\n'
'Use this to select a specific version of the web sdk if you have built multiple engine targets.\n'
'This path is relative to "--local-engine-src-path" (see above).');
if (verboseHelp) {
argParser.addSeparator('Options for testing the "flutter" tool itself:');
......@@ -216,9 +222,10 @@ class FlutterCommandRunner extends CommandRunner<void> {
// Set up the tooling configuration.
final EngineBuildPaths? engineBuildPaths = await globals.localEngineLocator?.findEnginePath(
topLevelResults['local-engine-src-path'] as String?,
topLevelResults['local-engine'] as String?,
topLevelResults['packages'] as String?,
engineSourcePath: topLevelResults['local-engine-src-path'] as String?,
localEngine: topLevelResults['local-engine'] as String?,
localWebSdk: topLevelResults['local-web-sdk'] as String?,
packagePath: topLevelResults['packages'] as String?,
);
if (engineBuildPaths != null) {
contextOverrides.addAll(<Type, Object?>{
......
......@@ -46,17 +46,26 @@ class LocalEngineLocator {
final UserMessages _userMessages;
/// Returns the engine build path of a local engine if one is located, otherwise `null`.
Future<EngineBuildPaths?> findEnginePath(String? engineSourcePath, String? localEngine, String? packagePath) async {
Future<EngineBuildPaths?> findEnginePath({String? engineSourcePath, String? localEngine, String? localWebSdk, String? packagePath}) async {
engineSourcePath ??= _platform.environment[kFlutterEngineEnvironmentVariableName];
if (engineSourcePath == null && localEngine == null && localWebSdk == null && packagePath == null) {
return null;
}
if (engineSourcePath == null && localEngine != null) {
if (engineSourcePath == null) {
try {
engineSourcePath = _findEngineSourceByLocalEngine(localEngine);
if (localEngine != null) {
engineSourcePath = _findEngineSourceByBuildPath(localEngine);
}
if (localWebSdk != null) {
engineSourcePath ??= _findEngineSourceByBuildPath(localWebSdk);
}
engineSourcePath ??= await _findEngineSourceByPackageConfig(packagePath);
} on FileSystemException catch (e) {
_logger.printTrace('Local engine auto-detection file exception: $e');
engineSourcePath = null;
}
// If engineSourcePath is still not set, try to determine it by flutter root.
engineSourcePath ??= _tryEnginePath(
_fileSystem.path.join(_fileSystem.directory(_flutterRoot).parent.path, 'engine', 'src'),
......@@ -72,9 +81,9 @@ class LocalEngineLocator {
if (engineSourcePath != null) {
_logger.printTrace('Local engine source at $engineSourcePath');
return _findEngineBuildPath(localEngine, engineSourcePath);
return _findEngineBuildPath(localEngine, localWebSdk, engineSourcePath);
}
if (localEngine != null) {
if (localEngine != null || localWebSdk != null) {
throwToolExit(
_userMessages.runnerNoEngineSrcDir(
kFlutterEnginePackageName,
......@@ -86,15 +95,15 @@ class LocalEngineLocator {
return null;
}
String? _findEngineSourceByLocalEngine(String localEngine) {
String? _findEngineSourceByBuildPath(String buildPath) {
// When the local engine is an absolute path to a variant inside the
// out directory, parse the engine source.
// --local-engine /path/to/cache/builder/src/out/host_debug_unopt
if (_fileSystem.path.isAbsolute(localEngine)) {
final Directory localEngineDirectory = _fileSystem.directory(localEngine);
final Directory outDirectory = localEngineDirectory.parent;
if (_fileSystem.path.isAbsolute(buildPath)) {
final Directory buildDirectory = _fileSystem.directory(buildPath);
final Directory outDirectory = buildDirectory.parent;
final Directory srcDirectory = outDirectory.parent;
if (localEngineDirectory.existsSync() && outDirectory.basename == 'out' && srcDirectory.basename == 'src') {
if (buildDirectory.existsSync() && outDirectory.basename == 'out' && srcDirectory.basename == 'src') {
_logger.printTrace('Parsed engine source from local engine as ${srcDirectory.path}.');
return srcDirectory.path;
}
......@@ -167,26 +176,38 @@ class LocalEngineLocator {
return 'host_$tmpBasename';
}
EngineBuildPaths _findEngineBuildPath(String? localEngine, String enginePath) {
if (localEngine == null) {
throwToolExit(_userMessages.runnerLocalEngineRequired, exitCode: 2);
EngineBuildPaths _findEngineBuildPath(String? localEngine, String? localWebSdk, String enginePath) {
if (localEngine == null && localWebSdk == null) {
throwToolExit(_userMessages.runnerLocalEngineOrWebSdkRequired, exitCode: 2);
}
final String engineBuildPath = _fileSystem.path.normalize(_fileSystem.path.join(enginePath, 'out', localEngine));
if (!_fileSystem.isDirectorySync(engineBuildPath)) {
throwToolExit(_userMessages.runnerNoEngineBuild(engineBuildPath), exitCode: 2);
String? engineBuildPath;
String? engineHostBuildPath;
if (localEngine != null) {
engineBuildPath = _fileSystem.path.normalize(_fileSystem.path.join(enginePath, 'out', localEngine));
if (!_fileSystem.isDirectorySync(engineBuildPath)) {
throwToolExit(_userMessages.runnerNoEngineBuild(engineBuildPath), exitCode: 2);
}
final String basename = _fileSystem.path.basename(engineBuildPath);
final String hostBasename = _getHostEngineBasename(basename);
engineHostBuildPath = _fileSystem.path.normalize(
_fileSystem.path.join(_fileSystem.path.dirname(engineBuildPath), hostBasename),
);
if (!_fileSystem.isDirectorySync(engineHostBuildPath)) {
throwToolExit(_userMessages.runnerNoEngineBuild(engineHostBuildPath), exitCode: 2);
}
}
final String basename = _fileSystem.path.basename(engineBuildPath);
final String hostBasename = _getHostEngineBasename(basename);
final String engineHostBuildPath = _fileSystem.path.normalize(
_fileSystem.path.join(_fileSystem.path.dirname(engineBuildPath), hostBasename),
);
if (!_fileSystem.isDirectorySync(engineHostBuildPath)) {
throwToolExit(_userMessages.runnerNoEngineBuild(engineHostBuildPath), exitCode: 2);
String? webSdkPath;
if (localWebSdk != null) {
webSdkPath = _fileSystem.path.normalize(_fileSystem.path.join(enginePath, 'out', localWebSdk));
if (!_fileSystem.isDirectorySync(webSdkPath)) {
throwToolExit(_userMessages.runnerNoWebSdk(webSdkPath), exitCode: 2);
}
}
return EngineBuildPaths(targetEngine: engineBuildPath, hostEngine: engineHostBuildPath);
return EngineBuildPaths(targetEngine: engineBuildPath, webSdk: webSdkPath, hostEngine: engineHostBuildPath);
}
String? _tryEnginePath(String enginePath) {
......
......@@ -188,7 +188,7 @@ class FlutterWebPlatform extends PlatformPlugin {
/// The require js binary.
File get _requireJs => _fileSystem.file(_fileSystem.path.join(
_artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath).path,
_artifacts!.getArtifactPath(Artifact.engineDartSdkPath, platform: TargetPlatform.web_javascript),
'lib',
'dev_compiler',
'kernel',
......@@ -198,7 +198,7 @@ class FlutterWebPlatform extends PlatformPlugin {
/// The ddc to dart stack trace mapper.
File get _stackTraceMapper => _fileSystem.file(_fileSystem.path.join(
_artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath).path,
_artifacts!.getArtifactPath(Artifact.engineDartSdkPath, platform: TargetPlatform.web_javascript),
'lib',
'dev_compiler',
'web',
......
......@@ -50,22 +50,29 @@ class WebTestCompiler {
required BuildInfo buildInfo,
}) async {
LanguageVersion languageVersion = LanguageVersion(2, 8);
HostArtifact platformDillArtifact = HostArtifact.webPlatformSoundKernelDill;
late final String platformDillName;
// TODO(zanderso): to support autodetect this would need to partition the source code into a
// a sound and unsound set and perform separate compilations.
// a sound and unsound set and perform separate compilations
final List<String> extraFrontEndOptions = List<String>.of(buildInfo.extraFrontEndOptions);
if (buildInfo.nullSafetyMode == NullSafetyMode.unsound || buildInfo.nullSafetyMode == NullSafetyMode.autodetect) {
platformDillArtifact = HostArtifact.webPlatformKernelDill;
platformDillName = 'ddc_outline.dill';
if (!extraFrontEndOptions.contains('--no-sound-null-safety')) {
extraFrontEndOptions.add('--no-sound-null-safety');
}
} else if (buildInfo.nullSafetyMode == NullSafetyMode.sound) {
languageVersion = currentLanguageVersion(_fileSystem, Cache.flutterRoot!);
platformDillName = 'ddc_outline_sound.dill';
if (!extraFrontEndOptions.contains('--sound-null-safety')) {
extraFrontEndOptions.add('--sound-null-safety');
}
}
final String platformDillPath = _fileSystem.path.join(
getWebPlatformBinariesDirectory(_artifacts, buildInfo.webRenderer).path,
platformDillName
);
final Directory outputDirectory = _fileSystem.directory(testOutputDir)
..createSync(recursive: true);
final List<File> generatedFiles = <File>[];
......@@ -116,9 +123,7 @@ class WebTestCompiler {
initializeFromDill: cachedKernelPath,
targetModel: TargetModel.dartdevc,
extraFrontEndOptions: extraFrontEndOptions,
platformDill: _artifacts
.getHostArtifact(platformDillArtifact)
.absolute.uri.toString(),
platformDill: platformDillPath,
dartDefines: buildInfo.dartDefines,
librariesSpec: _artifacts.getHostArtifact(HostArtifact.flutterWebLibrariesJson).uri.toString(),
packagesPath: buildInfo.packagesPath,
......
......@@ -50,42 +50,44 @@ Future<void> buildWeb(
final Status status = globals.logger.startProgress('Compiling $target for the Web...');
final Stopwatch sw = Stopwatch()..start();
try {
final BuildResult result = await globals.buildSystem.build(WebServiceWorker(globals.fs, globals.cache), Environment(
projectDir: globals.fs.currentDirectory,
outputDir: outputDirectory,
buildDir: flutterProject.directory
.childDirectory('.dart_tool')
.childDirectory('flutter_build'),
defines: <String, String>{
kTargetFile: target,
kHasWebPlugins: hasWebPlugins.toString(),
kCspMode: csp.toString(),
if (baseHref != null)
kBaseHref : baseHref,
kSourceMapsEnabled: sourceMaps.toString(),
kNativeNullAssertions: nativeNullAssertions.toString(),
if (serviceWorkerStrategy != null)
kServiceWorkerStrategy: serviceWorkerStrategy,
if (dart2jsOptimization != null)
kDart2jsOptimization: dart2jsOptimization,
kDart2jsDumpInfo: dumpInfo.toString(),
kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
...buildInfo.toBuildSystemEnvironment(),
},
artifacts: globals.artifacts!,
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
platform: globals.platform,
usage: globals.flutterUsage,
cacheDir: globals.cache.getRoot(),
engineVersion: globals.artifacts!.isLocalEngine
? null
: globals.flutterVersion.engineRevision,
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
// Web uses a different Dart plugin registry.
// https://github.com/flutter/flutter/issues/80406
generateDartPluginRegistry: false,
final BuildResult result = await globals.buildSystem.build(
WebServiceWorker(globals.fs, globals.cache, buildInfo.webRenderer),
Environment(
projectDir: globals.fs.currentDirectory,
outputDir: outputDirectory,
buildDir: flutterProject.directory
.childDirectory('.dart_tool')
.childDirectory('flutter_build'),
defines: <String, String>{
kTargetFile: target,
kHasWebPlugins: hasWebPlugins.toString(),
kCspMode: csp.toString(),
if (baseHref != null)
kBaseHref : baseHref,
kSourceMapsEnabled: sourceMaps.toString(),
kNativeNullAssertions: nativeNullAssertions.toString(),
if (serviceWorkerStrategy != null)
kServiceWorkerStrategy: serviceWorkerStrategy,
if (dart2jsOptimization != null)
kDart2jsOptimization: dart2jsOptimization,
kDart2jsDumpInfo: dumpInfo.toString(),
kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
...buildInfo.toBuildSystemEnvironment(),
},
artifacts: globals.artifacts!,
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
platform: globals.platform,
usage: globals.flutterUsage,
cacheDir: globals.cache.getRoot(),
engineVersion: globals.artifacts!.isLocalEngine
? null
: globals.flutterVersion.engineRevision,
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
// Web uses a different Dart plugin registry.
// https://github.com/flutter/flutter/issues/80406
generateDartPluginRegistry: false,
));
if (!result.success) {
for (final ExceptionMeasurement measurement in result.exceptions.values) {
......
......@@ -215,11 +215,11 @@ void _writeGeneratedFlutterConfig(
'FLUTTER_TARGET': target,
...buildInfo.toEnvironmentConfig(),
};
final Artifacts artifacts = globals.artifacts!;
if (artifacts is LocalEngineArtifacts) {
final String engineOutPath = artifacts.engineOutPath;
final LocalEngineInfo? localEngineInfo = globals.artifacts?.localEngineInfo;
if (localEngineInfo != null) {
final String engineOutPath = localEngineInfo.engineOutPath;
environment['FLUTTER_ENGINE'] = globals.fs.path.dirname(globals.fs.path.dirname(engineOutPath));
environment['LOCAL_ENGINE'] = artifacts.localEngineName;
environment['LOCAL_ENGINE'] = localEngineInfo.localEngineName;
}
writeGeneratedCmakeConfig(Cache.flutterRoot!, windowsProject, buildInfo, environment);
}
......
......@@ -92,7 +92,7 @@ void main() {
);
final AnalysisServer server = AnalysisServer(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartSdkPath),
<String>[tempDir.path],
fileSystem: fileSystem,
platform: platform,
......@@ -132,7 +132,7 @@ void main() {
);
final AnalysisServer server = AnalysisServer(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartSdkPath),
<String>[tempDir.path],
fileSystem: fileSystem,
platform: platform,
......@@ -159,7 +159,7 @@ void main() {
const String contents = "StringBuffer bar = StringBuffer('baz');";
tempDir.childFile('main.dart').writeAsStringSync(contents);
final AnalysisServer server = AnalysisServer(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartSdkPath).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartSdkPath),
<String>[tempDir.path],
fileSystem: fileSystem,
platform: platform,
......@@ -185,13 +185,13 @@ void main() {
<FakeCommand>[
FakeCommand(
command: const <String>[
'HostArtifact.engineDartSdkPath/bin/dart',
'Artifact.engineDartSdkPath/bin/dart',
'--disable-dart-dev',
'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'Artifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'--disable-server-feature-completion',
'--disable-server-feature-search',
'--sdk',
'HostArtifact.engineDartSdkPath',
'Artifact.engineDartSdkPath',
],
stdin: IOSink(stdin.sink),
),
......@@ -228,13 +228,13 @@ void main() {
<FakeCommand>[
FakeCommand(
command: const <String>[
'HostArtifact.engineDartSdkPath/bin/dart',
'Artifact.engineDartSdkPath/bin/dart',
'--disable-dart-dev',
'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'Artifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'--disable-server-feature-completion',
'--disable-server-feature-search',
'--sdk',
'HostArtifact.engineDartSdkPath',
'Artifact.engineDartSdkPath',
],
stdin: IOSink(stdin.sink),
stdout: '''
......@@ -281,13 +281,13 @@ void main() {
<FakeCommand>[
FakeCommand(
command: const <String>[
'HostArtifact.engineDartSdkPath/bin/dart',
'Artifact.engineDartSdkPath/bin/dart',
'--disable-dart-dev',
'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'Artifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'--disable-server-feature-completion',
'--disable-server-feature-search',
'--sdk',
'HostArtifact.engineDartSdkPath',
'Artifact.engineDartSdkPath',
],
stdin: IOSink(stdin.sink),
stdout: '''
......
......@@ -88,13 +88,13 @@ void main() {
const FakeCommand(
// artifact paths are from Artifacts.test() and stable
command: <String>[
'HostArtifact.engineDartSdkPath/bin/dart',
'Artifact.engineDartSdkPath/bin/dart',
'--disable-dart-dev',
'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'Artifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'--disable-server-feature-completion',
'--disable-server-feature-search',
'--sdk',
'HostArtifact.engineDartSdkPath',
'Artifact.engineDartSdkPath',
],
exitCode: SIGABRT,
stderr: stderr,
......
......@@ -195,7 +195,7 @@ void main() {
processManager.addCommand(
const FakeCommand(
command: <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'format',
'/.dart_tool/flutter_gen/gen_l10n/app_localizations_en.dart',
'/.dart_tool/flutter_gen/gen_l10n/app_localizations.dart',
......@@ -241,7 +241,7 @@ format: true
processManager.addCommand(
const FakeCommand(
command: <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'format',
'/.dart_tool/flutter_gen/gen_l10n/app_localizations_en.dart',
'/.dart_tool/flutter_gen/gen_l10n/app_localizations.dart',
......
......@@ -29,6 +29,7 @@ import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:flutter_tools/src/web/compile.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart';
......@@ -673,35 +674,35 @@ void main() {
});
test('auto web-renderer with no dart-defines', () {
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'auto');
dartDefines = FlutterCommand.updateDartDefines(dartDefines, WebRendererMode.autoDetect);
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=true']);
});
test('canvaskit web-renderer with no dart-defines', () {
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'canvaskit');
dartDefines = FlutterCommand.updateDartDefines(dartDefines, WebRendererMode.canvaskit);
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=true']);
});
test('html web-renderer with no dart-defines', () {
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'html');
dartDefines = FlutterCommand.updateDartDefines(dartDefines, WebRendererMode.html);
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=false']);
});
test('auto web-renderer with existing dart-defines', () {
dartDefines = <String>['FLUTTER_WEB_USE_SKIA=false'];
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'auto');
dartDefines = FlutterCommand.updateDartDefines(dartDefines, WebRendererMode.autoDetect);
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=true']);
});
test('canvaskit web-renderer with no dart-defines', () {
dartDefines = <String>['FLUTTER_WEB_USE_SKIA=false'];
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'canvaskit');
dartDefines = FlutterCommand.updateDartDefines(dartDefines, WebRendererMode.canvaskit);
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=true']);
});
test('html web-renderer with no dart-defines', () {
dartDefines = <String>['FLUTTER_WEB_USE_SKIA=true'];
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'html');
dartDefines = FlutterCommand.updateDartDefines(dartDefines, WebRendererMode.html);
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=false']);
});
});
......
......@@ -1180,7 +1180,7 @@ void main() {
final String original = file.readAsStringSync();
final Process process = await Process.start(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
<String>['format', '--output=show', file.path],
workingDirectory: projectDir.path,
);
......@@ -1277,7 +1277,7 @@ void main() {
final String original = file.readAsStringSync();
final Process process = await Process.start(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
<String>['format', '--output=show', file.path],
workingDirectory: projectDir.path,
);
......@@ -3138,7 +3138,7 @@ Future<void> _analyzeProject(String workingDir, { List<String> expectedFailures
];
final ProcessResult exec = await Process.run(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
args,
workingDirectory: workingDir,
);
......@@ -3195,7 +3195,7 @@ Future<void> _getPackages(Directory workingDir) async {
// While flutter test does get packages, it doesn't write version
// files anymore.
await Process.run(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
<String>[
flutterToolsSnapshotPath,
'packages',
......@@ -3224,7 +3224,7 @@ Future<void> _runFlutterTest(Directory workingDir, { String? target }) async {
];
final ProcessResult exec = await Process.run(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
args,
workingDirectory: workingDir.path,
);
......
......@@ -83,7 +83,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
......@@ -121,7 +121,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
......@@ -160,7 +160,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
......@@ -200,7 +200,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
......@@ -242,7 +242,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
......@@ -284,7 +284,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
......@@ -338,7 +338,7 @@ void main() {
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
......
......@@ -79,7 +79,7 @@ void main() {
artifacts = Artifacts.test();
fileSystem = MemoryFileSystem.test();
logger = BufferLogger.test();
dartPath = artifacts.getHostArtifact(HostArtifact.engineDartBinary).path;
dartPath = artifacts.getArtifactPath(Artifact.engineDartBinary);
constFinderPath = artifacts.getArtifactPath(Artifact.constFinder);
fontSubsetPath = artifacts.getArtifactPath(Artifact.fontSubset);
......
......@@ -53,7 +53,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......@@ -99,7 +99,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......@@ -145,7 +145,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......@@ -191,7 +191,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......@@ -240,7 +240,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......@@ -289,7 +289,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......@@ -341,7 +341,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......@@ -391,7 +391,7 @@ void main() {
logger: logger,
processManager: FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: const <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......
......@@ -30,7 +30,7 @@ void main() {
late FakeProcessManager fakeProcessManager;
const List<String> frontendServerCommand = <String>[
'HostArtifact.engineDartBinary',
'Artifact.engineDartBinary',
'--disable-dart-dev',
'Artifact.frontendServerSnapshotForEngineDartSdk',
'--sdk-root',
......
......@@ -1943,7 +1943,7 @@ flutter:
expect(residentCompiler.targetModel, TargetModel.dartdevc);
expect(residentCompiler.sdkRoot,
'${globals.artifacts!.getHostArtifact(HostArtifact.flutterWebSdk).path}/');
expect(residentCompiler.platformDill, 'file:///HostArtifact.webPlatformKernelDill');
expect(residentCompiler.platformDill, 'file:///HostArtifact.webPlatformKernelFolder/ddc_outline.dill');
}, overrides: <Type, Generator>{
Artifacts: () => Artifacts.test(),
FileSystem: () => MemoryFileSystem.test(),
......@@ -1974,7 +1974,7 @@ flutter:
expect(residentCompiler.targetModel, TargetModel.dartdevc);
expect(residentCompiler.sdkRoot,
'${globals.artifacts!.getHostArtifact(HostArtifact.flutterWebSdk).path}/');
expect(residentCompiler.platformDill, 'file:///HostArtifact.webPlatformSoundKernelDill');
expect(residentCompiler.platformDill, 'file:///HostArtifact.webPlatformKernelFolder/ddc_outline_sound.dill');
}, overrides: <Type, Generator>{
Artifacts: () => Artifacts.test(),
FileSystem: () => MemoryFileSystem.test(),
......
......@@ -43,7 +43,7 @@ void main() {
);
expect(
await localEngineLocator.findEnginePath(null, 'ios_debug', null),
await localEngineLocator.findEnginePath(localEngine: 'ios_debug'),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/host_debug',
targetEngine: '/arbitrary/engine/src/out/ios_debug',
......@@ -58,7 +58,7 @@ void main() {
.writeAsStringSync('sky_engine:file:///symlink/src/out/ios_debug/gen/dart-pkg/sky_engine/lib/');
expect(
await localEngineLocator.findEnginePath(null, 'ios_debug', null),
await localEngineLocator.findEnginePath(localEngine: 'ios_debug'),
matchesEngineBuildPaths(
hostEngine: '/symlink/src/out/host_debug',
targetEngine: '/symlink/src/out/ios_debug',
......@@ -84,7 +84,7 @@ void main() {
);
expect(
await localEngineLocator.findEnginePath('$kArbitraryEngineRoot/src', 'ios_debug', null),
await localEngineLocator.findEnginePath(engineSourcePath: '$kArbitraryEngineRoot/src', localEngine: 'ios_debug'),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/host_debug',
targetEngine: '/arbitrary/engine/src/out/ios_debug',
......@@ -111,7 +111,7 @@ void main() {
);
expect(
await localEngineLocator.findEnginePath(null, localEngine.path, null),
await localEngineLocator.findEnginePath(localEngine: localEngine.path),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/host_debug',
targetEngine: '/arbitrary/engine/src/out/ios_debug',
......@@ -137,7 +137,7 @@ void main() {
);
expect(
await localEngineLocator.findEnginePath(null, localEngine.path, null),
await localEngineLocator.findEnginePath(localEngine: localEngine.path),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/host_debug',
targetEngine: '/arbitrary/engine/src/out/host_debug',
......@@ -162,7 +162,7 @@ void main() {
);
expect(
await localEngineLocator.findEnginePath(null, localEngine.path, null),
await localEngineLocator.findEnginePath(localEngine: localEngine.path),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/host_debug_unopt_arm64',
targetEngine: '/arbitrary/engine/src/out/host_debug_unopt_arm64',
......@@ -185,7 +185,7 @@ void main() {
);
await expectToolExitLater(
localEngineLocator.findEnginePath(null, localEngine.path, null),
localEngineLocator.findEnginePath(localEngine: localEngine.path),
contains('No Flutter engine build found at /arbitrary/engine/src/out/host_debug'),
);
});
......@@ -214,7 +214,7 @@ void main() {
);
expect(
await localEngineLocator.findEnginePath(null, 'ios_debug', null),
await localEngineLocator.findEnginePath(localEngine: 'ios_debug'),
matchesEngineBuildPaths(
hostEngine: 'flutter/engine/src/out/host_debug',
targetEngine: 'flutter/engine/src/out/ios_debug',
......@@ -236,7 +236,7 @@ void main() {
);
await expectToolExitLater(
localEngineLocator.findEnginePath(null, '/path/to/nothing', null),
localEngineLocator.findEnginePath(localEngine: '/path/to/nothing'),
contains('Unable to detect local Flutter engine src directory'),
);
});
......@@ -260,7 +260,7 @@ void main() {
);
expect(
await localWasmEngineLocator.findEnginePath(null, localWasmEngine.path, null),
await localWasmEngineLocator.findEnginePath(localEngine: localWasmEngine.path),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/wasm_whatever',
targetEngine: '/arbitrary/engine/src/out/wasm_whatever',
......@@ -278,7 +278,7 @@ void main() {
);
expect(
await localWebEngineLocator.findEnginePath(null, localWebEngine.path, null),
await localWebEngineLocator.findEnginePath(localEngine: localWebEngine.path),
matchesEngineBuildPaths(
hostEngine: '/arbitrary/engine/src/out/web_whatever',
targetEngine: '/arbitrary/engine/src/out/web_whatever',
......@@ -286,6 +286,34 @@ void main() {
);
expect(webLogger.traceText, contains('Local engine source at /arbitrary/engine/src'));
});
test('returns null without throwing if nothing is specified', () async {
final LocalEngineLocator localWebEngineLocator = LocalEngineLocator(
fileSystem: MemoryFileSystem.test(),
flutterRoot: 'flutter/flutter',
logger: BufferLogger.test(),
userMessages: UserMessages(),
platform: FakePlatform(environment: <String, String>{}),
);
final EngineBuildPaths? paths = await localWebEngineLocator.findEnginePath();
expect(paths, isNull);
});
test('throws if nothing is specified but the FLUTTER_ENGINE environment variable is set', () async {
final LocalEngineLocator localWebEngineLocator = LocalEngineLocator(
fileSystem: MemoryFileSystem.test(),
flutterRoot: 'flutter/flutter',
logger: BufferLogger.test(),
userMessages: UserMessages(),
platform: FakePlatform(environment: <String, String>{'FLUTTER_ENGINE': 'blah'}),
);
await expectToolExitLater(
localWebEngineLocator.findEnginePath(),
contains('Unable to detect a Flutter engine build directory in blah'),
);
});
}
Matcher matchesEngineBuildPaths({
......
......@@ -9,6 +9,7 @@ import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/create.dart';
import 'package:flutter_tools/src/dart/pub.dart';
......@@ -412,7 +413,7 @@ Future<void> _analyzeEntity(FileSystemEntity target) async {
];
final ProcessResult exec = await Process.run(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartBinary, platform: TargetPlatform.web_javascript),
args,
workingDirectory: target is Directory ? target.path : target.dirname,
);
......@@ -451,7 +452,7 @@ Future<void> _runFlutterSnapshot(List<String> flutterCommandArgs, Directory work
];
final ProcessResult exec = await Process.run(
globals.artifacts!.getHostArtifact(HostArtifact.engineDartBinary).path,
globals.artifacts!.getArtifactPath(Artifact.engineDartBinary, platform: TargetPlatform.web_javascript),
args,
workingDirectory: workingDir.path,
);
......
......@@ -19,8 +19,8 @@ void main() {
setUp(() async {
fileSystem = MemoryFileSystem.test();
fileSystem.directory('HostArtifact.flutterWebSdk').createSync();
fileSystem.file('HostArtifact.webPlatformKernelDill').createSync();
fileSystem.file('HostArtifact.webPlatformSoundKernelDill').createSync();
fileSystem.file('HostArtifact.webPlatformDDCKernelDill').createSync();
fileSystem.file('HostArtifact.webPlatformDDCSoundKernelDill').createSync();
fileSystem.file('HostArtifact.flutterWebLibrariesJson').createSync();
final SdkWebConfigurationProvider provider =
......@@ -34,8 +34,8 @@ void main() {
testWithoutContext('is correct', () {
expect(configuration.sdkDirectory, 'HostArtifact.flutterWebSdk');
expect(configuration.unsoundSdkSummaryPath, 'HostArtifact.webPlatformKernelDill');
expect(configuration.soundSdkSummaryPath, 'HostArtifact.webPlatformSoundKernelDill');
expect(configuration.unsoundSdkSummaryPath, 'HostArtifact.webPlatformDDCKernelDill');
expect(configuration.soundSdkSummaryPath, 'HostArtifact.webPlatformDDCSoundKernelDill');
expect(configuration.librariesPath, 'HostArtifact.flutterWebLibrariesJson');
expect(configuration.compilerWorkerPath, isNull);
});
......
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