Skip to content

Commit

Permalink
Support compiling to wasm in build_web_compilers (#3727)
Browse files Browse the repository at this point in the history
Add `dart2wasm` as a compiler option for `build_web_compilers`.
  • Loading branch information
simolus3 committed Sep 4, 2024
1 parent 59a8aa6 commit 1b33ba9
Show file tree
Hide file tree
Showing 26 changed files with 500 additions and 70 deletions.
28 changes: 28 additions & 0 deletions _test/build.dart2wasm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
targets:
$default:
builders:
build_web_compilers:entrypoint:
options:
compiler: dart2wasm
dart2wasm_args:
- --enable-asserts
- -O0
release_options:
compiler: dart2wasm
dart2wasm_args:
- --enable-asserts
- -O4
generate_for:
- web/main.dart
- web/sub/main.dart
- test/configurable_uri_test.dart
- test/configurable_uri_test.dart.browser_test.dart
- test/hello_world_test.dart
- test/hello_world_test.dart.browser_test.dart
- test/hello_world_deferred_test.dart
- test/hello_world_deferred_test.dart.browser_test.dart
- test/hello_world_custom_html_test.dart
- test/hello_world_custom_html_test.dart.browser_test.dart
- test/other_test.dart.browser_test.dart
- test/sub-dir/subdir_test.dart
- test/sub-dir/subdir_test.dart.browser_test.dart
6 changes: 6 additions & 0 deletions _test/dart_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ timeout: 16x
# package.
concurrency: 1

tags:
integration:
# This tag is used for integration tests - we don't need special options at the
# moment, but want to avoid warnings from the test runner about using undefined
# targets.

override_platforms:
chrome:
settings:
Expand Down
4 changes: 2 additions & 2 deletions _test/lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:html';
import 'package:web/web.dart';

void startApp({String? text}) {
text ??= 'Hello World!';
var component = DivElement()..text = text;
var component = HTMLDivElement()..text = text;
document.body!.append(component);
}
2 changes: 1 addition & 1 deletion _test/pkgs/provides_builder/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: provides_builder
resolution: workspace
environment:
sdk: ^3.5.0
sdk: ^3.6.0-165.0.dev
publish_to: none

dependencies:
Expand Down
30 changes: 28 additions & 2 deletions _test/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
name: _test
publish_to: none
resolution: workspace
# This package can't be part of the workspace because it needs to use the local
# build_web_compilers, which also isn't part of the workspace. See the top-
# level pubspec for details.
#resolution: workspace

environment:
sdk: ^3.5.0
sdk: ^3.6.0-165.0.dev

dependencies:
web: ^1.0.0

dev_dependencies:
analyzer: any
Expand All @@ -15,9 +21,29 @@ dev_dependencies:
build_runner_core: any
build_test: any
build_web_compilers: any
dart_flutter_team_lints: ^3.1.0
io: ^1.0.0
path: ^1.8.0
provides_builder:
path: pkgs/provides_builder/
test: ^1.16.0
test_descriptor: ^2.0.1
test_process: ^2.0.0

dependency_overrides:
build:
path: ../build
build_config:
path: ../build_config
build_modules:
path: ../build_modules
build_resolvers:
path: ../build_resolvers
build_runner:
path: ../build_runner
build_runner_core:
path: ../build_runner_core
build_test:
path: ../build_test
build_web_compilers:
path: ../build_web_compilers
3 changes: 2 additions & 1 deletion _test/test/common/message_export.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

export 'message.dart'
if (dart.library.io) 'message_io.dart'
if (dart.library.html) 'message_html.dart';
if (dart.library.html) 'message_html.dart'
if (dart.library.js_interop) 'message_js_without_html.dart';
5 changes: 5 additions & 0 deletions _test/test/common/message_js_without_html.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

String get message => 'Hello World from WebAssembly!';
12 changes: 8 additions & 4 deletions _test/test/common/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,18 +167,22 @@ Future<TestProcess> _runTests(String executable, List<String> scriptArgs,
List<String>? buildArgs,
List<String>? testArgs}) async {
usePrecompiled ??= true;
testArgs ??= [];
testArgs.addAll(['-p', 'chrome', '-r', 'expanded']);
if (usePrecompiled) {
var args = scriptArgs.toList()
..add('test')
..add('--verbose')
..addAll(buildArgs ?? [])
..add('--')
..addAll(testArgs);
..addAll([
...?testArgs,
'-p',
'chrome',
'-r',
'expanded',
]);
return TestProcess.start(executable, args);
} else {
var args = ['run', 'test', '--pub-serve', '8081', ...testArgs];
var args = ['run', 'test', '--pub-serve', '8081', ...?testArgs];
return TestProcess.start('dart', args);
}
}
Expand Down
15 changes: 13 additions & 2 deletions _test/test/configurable_uri_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import 'package:test/test.dart';

import 'common/message.dart'
if (dart.library.io) 'common/message_io.dart'
if (dart.library.html) 'common/message_html.dart';
if (dart.library.html) 'common/message_html.dart'
if (dart.library.js_interop) 'common/message_js_without_html.dart';

import 'common/message_export.dart' as exported;

Expand All @@ -19,7 +20,17 @@ void main() {
test('exports', () {
expect(exported.message, contains('Javascript'));
});
}, testOn: 'browser');
}, testOn: 'js');

group('wasm', () {
test('imports', () {
expect(message, contains('WebAssembly'));
});

test('exports', () {
expect(exported.message, contains('WebAssembly'));
});
}, testOn: 'dart2wasm');

group('vm', () {
test('imports', () {
Expand Down
75 changes: 75 additions & 0 deletions _test/test/dart2wasm_integration_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@TestOn('vm')
@Tags(['integration'])
library;

import 'dart:async';

import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;

import 'common/utils.dart';

// This doesn't actually change anything since we're using precompiled tests,
// but it gets the compiler selector in tests right.
const _testArgs = ['-c', 'dart2wasm'];

void main() {
group('Can run tests using dart2wasm', () {
test('via build.yaml config flag', () async {
await expectTestsPass(
usePrecompiled: true,
buildArgs: [
'--config=dart2wasm',
'--output=${d.sandbox}',
],
testArgs: _testArgs,
);
await _expectWasCompiledWithDart2Wasm();
}, onPlatform: {'windows': const Skip('flaky on windows')});

test('via --define flag', () async {
await expectTestsPass(
usePrecompiled: true,
buildArgs: [
'--define',
'build_web_compilers:entrypoint=compiler=dart2wasm',
'--define',
'build_web_compilers:entrypoint=dart2wasm_args='
'["--enable-asserts", "-E--enable-experimental-ffi"]',
'--output=${d.sandbox}',
],
testArgs: _testArgs,
);
await _expectWasCompiledWithDart2Wasm();
}, onPlatform: {'windows': const Skip('flaky on windows')});

test('via --release mode', () async {
await expectTestsPass(
usePrecompiled: true,
buildArgs: [
'--release',
'--config=dart2wasm',
'--output=${d.sandbox}',
],
testArgs: _testArgs,
);
await _expectWasCompiledWithDart2Wasm();
}, onPlatform: {'windows': const Skip('flaky on windows')});
});
}

Future<void> _expectWasCompiledWithDart2Wasm() async {
await d.dir(
'test',
[
d.file(
'hello_world_deferred_test.dart.browser_test.wasm',
anything,
),
],
).validate();
}
16 changes: 15 additions & 1 deletion _test/test/goldens/generated_build_script.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,22 @@ final _builders = <_i1.BuilderApplication>[
appliesBuilders: const [
r'build_web_compilers:ddc_modules',
r'build_web_compilers:dart2js_modules',
r'build_web_compilers:dart2wasm_modules',
r'build_web_compilers:dart_source_cleanup',
],
),
_i1.apply(
r'build_web_compilers:dart2wasm_modules',
[
_i3.dart2wasmMetaModuleBuilder,
_i3.dart2wasmMetaModuleCleanBuilder,
_i3.dart2wasmModuleBuilder,
],
_i1.toNoneByDefault(),
isOptional: true,
hideOutput: true,
appliesBuilders: const [r'build_modules:module_cleanup'],
),
_i1.apply(
r'build_web_compilers:dart2js_modules',
[
Expand Down Expand Up @@ -124,7 +137,8 @@ final _builders = <_i1.BuilderApplication>[
r'dart2js_args': <dynamic>[r'--minify']
}),
defaultDevOptions: const _i7.BuilderOptions(<String, dynamic>{
r'dart2js_args': <dynamic>[r'--enable-asserts']
r'dart2wasm_args': <dynamic>[r'--enable-asserts'],
r'dart2js_args': <dynamic>[r'--enable-asserts'],
}),
defaultReleaseOptions:
const _i7.BuilderOptions(<String, dynamic>{r'compiler': r'dart2js'}),
Expand Down
3 changes: 1 addition & 2 deletions _test/test/hello_world_custom_html_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
@TestOn('browser')
library;

import 'dart:html';

import 'package:test/test.dart';
import 'package:web/web.dart';

void main() {
test('can use custom html', () {
Expand Down
7 changes: 4 additions & 3 deletions _test/test/hello_world_deferred_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
@TestOn('browser')
library;

import 'dart:html';
import 'dart:js_interop';

import 'package:_test/app.dart';
import 'package:test/test.dart';
import 'package:web/web.dart';

import 'common/message.dart' deferred as m;

void main() {
setUp(startApp);

tearDown(() {
document.body!.innerHtml = '';
document.body!.innerHTML = ''.toJS;
});

test('hello world', () async {
await m.loadLibrary();
expect(document.body?.text, contains(m.message));
expect(document.body?.innerText, contains(m.message));
});
}
7 changes: 4 additions & 3 deletions _test/test/hello_world_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
@TestOn('browser')
library;

import 'dart:html';
import 'dart:js_interop';

import 'package:_test/app.dart';
import 'package:test/test.dart';
import 'package:web/web.dart';

//import_anchor

Expand All @@ -18,11 +19,11 @@ void main() {
setUp(startApp);

tearDown(() {
document.body!.innerHtml = '';
document.body!.innerHTML = ''.toJS;
});

test('hello world', () {
expect(document.body!.text, contains(message));
expect(document.body!.innerText, contains(message));
});

test('failing test', skip: 'Expected failure', () {
Expand Down
4 changes: 3 additions & 1 deletion build_web_compilers/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
## 4.0.12-wip

- Bump the min sdk to 3.5.0.
- Account for dartdevc snapshot in the Dart SDK changing to an AOT snapshot.
- Support compiling to WebAssembly by using `dart2wasm` as a value for the
compiler option.
- Bump the min sdk to 3.6.0-165.0.dev.

## 4.0.11

Expand Down
Loading

0 comments on commit 1b33ba9

Please sign in to comment.