Unverified Commit 529b919f authored by Kevin Moore's avatar Kevin Moore Committed by GitHub

tool-web-wasm: make wasm-opt an "option" instead of a "flag" (#126035)

Allows controlling a broader set of variables than just on/off.

Also make wasm-opt "full" the default
parent 5a80f8d6
......@@ -294,14 +294,16 @@ class Dart2WasmTarget extends Dart2WebTarget {
final File optimizedOutput = environment.buildDir.childFile('main.dart.wasm');
final List<String> optimizeArgs = <String>[
wasmOptBinary,
'-all',
'--all-features',
'--closed-world',
'-tnh',
'--traps-never-happen',
'-O3',
'--type-ssa',
'--gufa',
'-O3',
'--type-merging',
if (compilerConfig.wasmOpt == WasmOptLevel.debug)
'--debuginfo',
outputWasmFile.path,
'-o',
optimizedOutput.path,
......
......@@ -103,12 +103,13 @@ class BuildWebCommand extends BuildSubCommand {
negatable: false,
hide: !featureFlags.isFlutterWebWasmEnabled,
);
argParser.addFlag(
argParser.addOption(
'wasm-opt',
help:
'Optimize output wasm using the Binaryen (https://github.com/WebAssembly/binaryen) tool.\n'
'Increases the build time, but will yield a smaller, faster output.',
negatable: false,
'Optimize output wasm using the Binaryen (https://github.com/WebAssembly/binaryen) tool.',
defaultsTo: WasmOptLevel.defaultValue.cliName,
allowed: WasmOptLevel.values.map<String>((WasmOptLevel e) => e.cliName),
allowedHelp: CliEnum.allowedHelp(WasmOptLevel.values),
hide: !featureFlags.isFlutterWebWasmEnabled,
);
}
......@@ -143,7 +144,7 @@ class BuildWebCommand extends BuildSubCommand {
}
compilerConfig = WasmCompilerConfig(
omitTypeChecks: boolArg('omit-type-checks'),
runWasmOpt: boolArg('wasm-opt'),
wasmOpt: WasmOptLevel.values.byName(stringArg('wasm-opt')!),
);
} else {
compilerConfig = JsCompilerConfig(
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../base/utils.dart';
abstract class WebCompilerConfig {
const WebCompilerConfig();
......@@ -134,7 +136,7 @@ class JsCompilerConfig extends WebCompilerConfig {
class WasmCompilerConfig extends WebCompilerConfig {
const WasmCompilerConfig({
required this.omitTypeChecks,
required this.runWasmOpt,
required this.wasmOpt,
});
/// Creates a new [WasmCompilerConfig] from build system environment values.
......@@ -144,28 +146,30 @@ class WasmCompilerConfig extends WebCompilerConfig {
Map<String, String> defines) =>
WasmCompilerConfig(
omitTypeChecks: defines[kOmitTypeChecks] == 'true',
runWasmOpt: defines[kRunWasmOpt] == 'true',
wasmOpt: WasmOptLevel.values.byName(defines[kRunWasmOpt]!),
);
/// Build environment for [omitTypeChecks].
static const String kOmitTypeChecks = 'WasmOmitTypeChecks';
/// Build environment for [runWasmOpt].
/// Build environment for [wasmOpt].
static const String kRunWasmOpt = 'RunWasmOpt';
/// If `omit-type-checks` should be passed to `dart2wasm`.
final bool omitTypeChecks;
/// Run wasm-opt on the resulting module.
final bool runWasmOpt;
final WasmOptLevel wasmOpt;
@override
bool get isWasm => true;
bool get runWasmOpt => wasmOpt == WasmOptLevel.full || wasmOpt == WasmOptLevel.debug;
@override
Map<String, String> toBuildSystemEnvironment() => <String, String>{
kOmitTypeChecks: omitTypeChecks.toString(),
kRunWasmOpt: runWasmOpt.toString(),
kRunWasmOpt: wasmOpt.name,
};
List<String> toCommandOptions() => <String>[
......@@ -182,3 +186,21 @@ class WasmCompilerConfig extends WebCompilerConfig {
entry.key: entry.value,
};
}
enum WasmOptLevel implements CliEnum {
full,
debug,
none;
static const WasmOptLevel defaultValue = WasmOptLevel.full;
@override
String get cliName => name;
@override
String get helpText => switch(this) {
WasmOptLevel.none => 'wasm-opt is not run. Fastest build; bigger, slower output.',
WasmOptLevel.debug => 'Similar to `${WasmOptLevel.full.name}, but member names are preserved. Debugging is easier, but size is a bit bigger.',
WasmOptLevel.full => 'wasm-opt is run. Build time is slower, but output is smaller and faster.',
};
}
......@@ -24,7 +24,7 @@ import '../../../src/testbed.dart';
const List<String> _kDart2jsLinuxArgs = <String>[
'Artifact.engineDartBinary.TargetPlatform.web_javascript',
'--disable-dart-dev',
'--disable-dart-dev',
'Artifact.dart2jsSnapshot.TargetPlatform.web_javascript',
'--platform-binaries=HostArtifact.webPlatformKernelFolder',
'--invoker=flutter_tool',
......@@ -46,6 +46,18 @@ const List<String> _kDart2WasmLinuxArgs = <String> [
'HostArtifact.flutterWebLibrariesJson',
];
const List<String> _kWasmOptLinuxArgrs = <String> [
'Artifact.wasmOptBinary.TargetPlatform.web_javascript',
'--all-features',
'--closed-world',
'--traps-never-happen',
'-O3',
'--type-ssa',
'--gufa',
'-O3',
'--type-merging',
];
/// The result of calling `.parent` on a Memory directory pointing to
/// `'Artifact.engineDartSdkPath.TargetPlatform.web_javascript'`.
const String _kDartSdkRoot = '.';
......@@ -759,10 +771,12 @@ void main() {
test('Dart2WasmTarget invokes dart2wasm with dart defines', () => testbed.run(() async {
environment.defines[kBuildMode] = 'profile';
environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.defaultValue.name;
environment.defines[kDartDefines] = encodeDartDefines(<String>['FOO=bar', 'BAZ=qux']);
final File depFile = environment.buildDir.childFile('dart2wasm.d');
final File outputJsFile = environment.buildDir.childFile('main.dart.unopt.mjs');
processManager.addCommand(FakeCommand(
command: <String>[
..._kDart2WasmLinuxArgs,
......@@ -771,21 +785,38 @@ void main() {
'-DBAZ=qux',
'--depfile=${depFile.absolute.path}',
environment.buildDir.childFile('main.dart').absolute.path,
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
],
onRun: () => outputJsFile..createSync()..writeAsStringSync('foo'))
);
processManager.addCommand(FakeCommand(
command: <String>[
..._kWasmOptLinuxArgrs,
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
'-o',
environment.buildDir.childFile('main.dart.wasm').absolute.path,
])
);
await Dart2WasmTarget(WebRendererMode.canvaskit).build(environment);
expect(outputJsFile.existsSync(), isFalse);
final File movedJsFile = environment.buildDir.childFile('main.dart.mjs');
expect(movedJsFile.existsSync(), isTrue);
expect(movedJsFile.readAsStringSync(), 'foo');
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
}));
test('Dart2WasmTarget invokes dart2wasm with omit checks', () => testbed.run(() async {
environment.defines[kBuildMode] = 'release';
environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.defaultValue.name;
environment.defines[WasmCompilerConfig.kOmitTypeChecks] = 'true';
final File depFile = environment.buildDir.childFile('dart2wasm.d');
final File outputJsFile = environment.buildDir.childFile('main.dart.unopt.mjs');
processManager.addCommand(FakeCommand(
command: <String>[
..._kDart2WasmLinuxArgs,
......@@ -793,18 +824,33 @@ void main() {
'--omit-type-checks',
'--depfile=${depFile.absolute.path}',
environment.buildDir.childFile('main.dart').absolute.path,
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
],
onRun: () => outputJsFile..createSync()..writeAsStringSync('foo'))
);
processManager.addCommand(FakeCommand(
command: <String>[
..._kWasmOptLinuxArgrs,
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
'-o',
environment.buildDir.childFile('main.dart.wasm').absolute.path,
])
);
await Dart2WasmTarget(WebRendererMode.canvaskit).build(environment);
expect(outputJsFile.existsSync(), isFalse);
final File movedJsFile = environment.buildDir.childFile('main.dart.mjs');
expect(movedJsFile.existsSync(), isTrue);
expect(movedJsFile.readAsStringSync(), 'foo');
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
}));
test('Dart2WasmTarget invokes dart2wasm and wasm-opt when RunWasmOpt is enabled', () => testbed.run(() async {
test('Dart2WasmTarget invokes dart2wasm and wasm-opt with debug info in wasmopt debug mode', () => testbed.run(() async {
environment.defines[kBuildMode] = 'release';
environment.defines[WasmCompilerConfig.kRunWasmOpt] = 'true';
environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.debug.name;
final File depFile = environment.buildDir.childFile('dart2wasm.d');
......@@ -820,15 +866,8 @@ void main() {
processManager.addCommand(FakeCommand(
command: <String>[
'Artifact.wasmOptBinary.TargetPlatform.web_javascript',
'-all',
'--closed-world',
'-tnh',
'-O3',
'--type-ssa',
'--gufa',
'-O3',
'--type-merging',
..._kWasmOptLinuxArgrs,
'--debuginfo',
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
'-o',
environment.buildDir.childFile('main.dart.wasm').absolute.path,
......@@ -844,11 +883,33 @@ void main() {
ProcessManager: () => processManager,
}));
test('Dart2WasmTarget invokes dart2wasm (but not wasm-opt) with wasm-opt none option', () => testbed.run(() async {
environment.defines[kBuildMode] = 'debug';
environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.none.name;
final File depFile = environment.buildDir.childFile('dart2wasm.d');
final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
processManager.addCommand(FakeCommand(
command: <String>[
..._kDart2WasmLinuxArgs,
'-Ddart.vm.product=true',
'--depfile=${depFile.absolute.path}',
environment.buildDir.childFile('main.dart').absolute.path,
environment.buildDir.childFile('main.dart.wasm').absolute.path,
], onRun: () => outputJsFile..createSync()..writeAsStringSync('foo')));
await Dart2WasmTarget(WebRendererMode.canvaskit).build(environment);
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
}));
test('Dart2WasmTarget with skwasm renderer adds extra flags', () => testbed.run(() async {
environment.defines[kBuildMode] = 'release';
environment.defines[WasmCompilerConfig.kRunWasmOpt] = WasmOptLevel.defaultValue.name;
final File depFile = environment.buildDir.childFile('dart2wasm.d');
final File outputJsFile = environment.buildDir.childFile('main.dart.unopt.mjs');
processManager.addCommand(FakeCommand(
command: <String>[
..._kDart2WasmLinuxArgs,
......@@ -857,6 +918,16 @@ void main() {
'--shared-memory-max-pages=32768',
'--depfile=${depFile.absolute.path}',
environment.buildDir.childFile('main.dart').absolute.path,
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
],
onRun: () => outputJsFile..createSync()..writeAsStringSync('foo'))
);
processManager.addCommand(FakeCommand(
command: <String>[
..._kWasmOptLinuxArgrs,
environment.buildDir.childFile('main.dart.unopt.wasm').absolute.path,
'-o',
environment.buildDir.childFile('main.dart.wasm').absolute.path,
])
);
......
......@@ -47,7 +47,7 @@ void main() {
'HasWebPlugins': 'false',
'ServiceWorkerStrategy': ServiceWorkerStrategy.offlineFirst.cliName,
'WasmOmitTypeChecks': 'false',
'RunWasmOpt': 'false',
'RunWasmOpt': 'none',
'BuildMode': 'debug',
'DartObfuscation': 'false',
'TrackWidgetCreation': 'true',
......@@ -73,7 +73,7 @@ void main() {
ServiceWorkerStrategy.offlineFirst,
compilerConfig: const WasmCompilerConfig(
omitTypeChecks: false,
runWasmOpt: false
wasmOpt: WasmOptLevel.none,
),
);
......
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