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