Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build_web_compilers/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.4.6

- Add build options to customize the SDK used for compiling to js and wasm.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this documented anywhere? How would one use it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently not, but I'd like to.
Where would be a good place to document this? I think this shouldn't be too visible (so not in Readme) since it's quite a special case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevmoo I added this as a details section to the readme.


## 4.4.5

- Updating DDC's bootstrapper to be consistent with the rest of the ecosystem.
Expand Down
27 changes: 27 additions & 0 deletions build_web_compilers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,33 @@ targets:

In this case, you need to use another builder or a predefined loader instead.

### Advanced SDK Customization

The following options allow you to customize the Dart SDK used for compiling to
js and wasm. They are intended for advanced use cases and should be used with
caution.

<details>
<summary>Expand to see configuration options.</summary>

```yaml
global_options:
build_web_compilers:ddc:
options:
use-ui-libraries: false
platform-sdk: /path/to/platform_sdk/
ddc-kernel-path: relative/path/to/kernel_summary
libraries-path: /path/to/libraries.json
build_web_compilers:entrypoint:
options:
use-ui-libraries: false
libraries-path: /path/to/libraries.json
build_web_compilers:sdk_js:
options:
use-prebuilt-sdk-from-path: /path/to/prebuilt/sdk_js/
```
</details>

### Configuring -D environment variables

dartdevc is a modular compiler, so in order to ensure consistent builds
Expand Down
2 changes: 1 addition & 1 deletion build_web_compilers/lib/build_web_compilers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ export 'src/common.dart'
symbolsExtension;
export 'src/dev_compiler_builder.dart' show DevCompilerBuilder;
export 'src/platforms.dart'
show dart2jsPlatform, dart2wasmPlatform, ddcPlatform;
show dart2jsPlatform, dart2wasmPlatform, ddcPlatform, initializePlatforms;
export 'src/web_entrypoint_builder.dart'
show WebCompiler, WebEntrypointBuilder, ddcBootstrapExtension;
108 changes: 94 additions & 14 deletions build_web_compilers/lib/builders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import 'src/web_entrypoint_marker_builder.dart';

// Shared entrypoint builder
Builder webEntrypointBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
_ensureSameDdcHotReloadOptions(options);
return WebEntrypointBuilder.fromOptions(options);
}

Builder webEntrypointMarkerBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
_ensureSameDdcHotReloadOptions(options);
return WebEntrypointMarkerBuilder(
usesWebHotReload: _readWebHotReloadOption(options),
Expand All @@ -28,16 +30,19 @@ Builder webEntrypointMarkerBuilder(BuilderOptions options) {

// DDC related builders
Builder ddcMetaModuleBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
_ensureSameDdcHotReloadOptions(options);
return MetaModuleBuilder.forOptions(ddcPlatform, options);
}

Builder ddcMetaModuleCleanBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
_ensureSameDdcHotReloadOptions(options);
return MetaModuleCleanBuilder(ddcPlatform);
}

Builder ddcModuleBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
_ensureSameDdcHotReloadOptions(options);
return ModuleBuilder(
ddcPlatform,
Expand All @@ -47,6 +52,7 @@ Builder ddcModuleBuilder(BuilderOptions options) {

Builder ddcBuilder(BuilderOptions options) {
validateOptions(options.config, _supportedOptions, 'build_web_compilers:ddc');
_ensureSamePlatformOptions(options);
_ensureSameDdcHotReloadOptions(options);
_ensureSameDdcOptions(options);

Expand All @@ -60,9 +66,11 @@ Builder ddcBuilder(BuilderOptions options) {
emitDebugSymbols: _readEmitDebugSymbolsOption(options),
canaryFeatures: _readCanaryOption(options),
ddcModules: _readWebHotReloadOption(options),
sdkKernelPath: sdkDdcKernelPath,
trackUnusedInputs: _readTrackInputsCompilerOption(options),
platform: ddcPlatform,
sdkKernelPath: _readDdcKernelPathOption(options),
librariesPath: _readLibrariesPathOption(options),
platformSdk: _readPlatformSdkOption(options),
environment: _readEnvironmentOption(options),
);
}
Expand All @@ -71,16 +79,19 @@ final ddcKernelExtension = '.ddc.dill';

Builder ddcKernelBuilder(BuilderOptions options) {
validateOptions(options.config, _supportedOptions, 'build_web_compilers:ddc');
_ensureSamePlatformOptions(options);
_ensureSameDdcHotReloadOptions(options);
_ensureSameDdcOptions(options);

return KernelBuilder(
summaryOnly: true,
sdkKernelPath: sdkDdcKernelPath,
sdkKernelPath: _readDdcKernelPathOption(options),
outputExtension: ddcKernelExtension,
platform: ddcPlatform,
librariesPath: _readLibrariesPathOption(options),
useIncrementalCompiler: _readUseIncrementalCompilerOption(options),
trackUnusedInputs: _readTrackInputsCompilerOption(options),
platformSdk: _readPlatformSdkOption(options),
);
}

Expand All @@ -93,26 +104,44 @@ Builder sdkJsCompile(BuilderOptions options) {
canaryFeatures:
_readWebHotReloadOption(options) || _readCanaryOption(options),
usesWebHotReload: _readWebHotReloadOption(options),
usePrebuiltSdkFromPath: _readUsePrebuiltSdkFromPathOption(options),
);
}

// Dart2js related builders
Builder dart2jsMetaModuleBuilder(BuilderOptions options) =>
MetaModuleBuilder.forOptions(dart2jsPlatform, options);
Builder dart2jsMetaModuleCleanBuilder(BuilderOptions _) =>
MetaModuleCleanBuilder(dart2jsPlatform);
Builder dart2jsModuleBuilder(BuilderOptions _) =>
ModuleBuilder(dart2jsPlatform);
Builder dart2jsMetaModuleBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
return MetaModuleBuilder.forOptions(dart2jsPlatform, options);
}

Builder dart2jsMetaModuleCleanBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
return MetaModuleCleanBuilder(dart2jsPlatform);
}

Builder dart2jsModuleBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
return ModuleBuilder(dart2jsPlatform);
}

PostProcessBuilder dart2jsArchiveExtractor(BuilderOptions options) =>
Dart2JsArchiveExtractor.fromOptions(options);

// Dart2wasm related builders
Builder dart2wasmMetaModuleBuilder(BuilderOptions options) =>
MetaModuleBuilder.forOptions(dart2wasmPlatform, options);
Builder dart2wasmMetaModuleCleanBuilder(BuilderOptions _) =>
MetaModuleCleanBuilder(dart2wasmPlatform);
Builder dart2wasmModuleBuilder(BuilderOptions _) =>
ModuleBuilder(dart2wasmPlatform);
Builder dart2wasmMetaModuleBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
return MetaModuleBuilder.forOptions(dart2wasmPlatform, options);
}

Builder dart2wasmMetaModuleCleanBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
return MetaModuleCleanBuilder(dart2wasmPlatform);
}

Builder dart2wasmModuleBuilder(BuilderOptions options) {
_ensureSamePlatformOptions(options);
return ModuleBuilder(dart2wasmPlatform);
}

// General purpose builders
PostProcessBuilder dartSourceCleanup(BuilderOptions options) =>
Expand Down Expand Up @@ -170,6 +199,27 @@ void _ensureSameDdcHotReloadOptions(BuilderOptions options) {
}
}

void _ensureSamePlatformOptions(BuilderOptions options) {
final useUiLibraries = _readUseUiLibrariesOption(options);
if (_lastUseUiLibrariesValue == null) {
initializePlatforms(useUiLibraries);
_lastUseUiLibrariesValue = useUiLibraries;
} else if (_lastUseUiLibrariesValue != useUiLibraries) {
throw ArgumentError(
'`use-ui-libraries` must be configured the same across the '
'following builders: build_web_compilers:ddc, '
'build_web_compilers|entrypoint, '
'build_web_compilers|entrypoint_marker, '
'build_web_compilers|ddc, '
'build_web_compilers|ddc_modules, '
'build_web_compilers|dart2js_modules, '
'build_web_compilers|dart2wasm_modules.'
'\n\nPlease use the `global_options` section in '
'`build.yaml` or the `--define` flag to set global options.',
);
}
}

bool _readUseIncrementalCompilerOption(BuilderOptions options) {
return options.config[_useIncrementalCompilerOption] as bool? ?? true;
}
Expand All @@ -194,20 +244,46 @@ bool _readWebHotReloadOption(BuilderOptions options) {
return options.config[_webHotReloadOption] as bool? ?? false;
}

bool _readUseUiLibrariesOption(BuilderOptions options) {
return options.config[_useUiLibrariesOption] as bool? ?? false;
}

String _readDdcKernelPathOption(BuilderOptions options) {
return options.config[_ddcKernelPathOption] as String? ?? sdkDdcKernelPath;
}

String? _readLibrariesPathOption(BuilderOptions options) {
return options.config[_librariesPathOption] as String?;
}

String? _readPlatformSdkOption(BuilderOptions options) {
return options.config[_platformSdkOption] as String?;
}

String? _readUsePrebuiltSdkFromPathOption(BuilderOptions options) {
return options.config[_usePrebuiltSdkFromPathOption] as String?;
}

Map<String, String> _readEnvironmentOption(BuilderOptions options) {
final environment = options.config[_environmentOption] as Map? ?? const {};
return environment.map((key, value) => MapEntry('$key', '$value'));
}

Map<String, dynamic>? _previousDdcConfig;
bool? _lastWebHotReloadValue;
bool? _lastUseUiLibrariesValue;
const _useIncrementalCompilerOption = 'use-incremental-compiler';
const _generateFullDillOption = 'generate-full-dill';
const _emitDebugSymbolsOption = 'emit-debug-symbols';
const _canaryOption = 'canary';
const _trackUnusedInputsCompilerOption = 'track-unused-inputs';
const _environmentOption = 'environment';
const _webHotReloadOption = 'web-hot-reload';
const _useUiLibrariesOption = 'use-ui-libraries';
const _ddcKernelPathOption = 'ddc-kernel-path';
const _librariesPathOption = 'libraries-path';
const _platformSdkOption = 'platform-sdk';
const _usePrebuiltSdkFromPathOption = 'use-prebuilt-sdk-from-path';

const _supportedOptions = [
_environmentOption,
Expand All @@ -217,4 +293,8 @@ const _supportedOptions = [
_canaryOption,
_trackUnusedInputsCompilerOption,
_webHotReloadOption,
_useUiLibrariesOption,
_ddcKernelPathOption,
_librariesPathOption,
_platformSdkOption,
];
11 changes: 9 additions & 2 deletions build_web_compilers/lib/src/dart2js_bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ Future<void> bootstrapDart2Js(
required bool? nativeNullAssertions,
required bool onlyCompiler,
String entrypointExtension = jsEntrypointExtension,
String? librariesPath,
bool unsafeAllowUnsupportedModules = false,
}) => _resourcePool.withResource(
() => _bootstrapDart2Js(
buildStep,
dart2JsArgs,
nativeNullAssertions: nativeNullAssertions,
onlyCompiler: onlyCompiler,
entrypointExtension: entrypointExtension,
librariesPath: librariesPath,
unsafeAllowUnsupportedModules: unsafeAllowUnsupportedModules,
),
);

Expand All @@ -44,6 +48,8 @@ Future<void> _bootstrapDart2Js(
required bool? nativeNullAssertions,
required bool onlyCompiler,
required String entrypointExtension,
String? librariesPath,
bool unsafeAllowUnsupportedModules = false,
}) async {
final dartEntrypointId = buildStep.inputId;
final moduleId = dartEntrypointId.changeExtension(
Expand All @@ -59,7 +65,7 @@ Future<void> _bootstrapDart2Js(
try {
allDeps = (await module.computeTransitiveDependencies(
buildStep,
throwIfUnsupported: true,
throwIfUnsupported: !unsafeAllowUnsupportedModules,
))..add(module);
} on UnsupportedModules catch (e) {
final librariesString = (await e.exactLibraries(buildStep).toList())
Expand Down Expand Up @@ -97,7 +103,8 @@ $librariesString
: dartUri.path.substring(1),
) +
entrypointExtension;
final librariesSpec = p.joinAll([sdkDir, 'lib', 'libraries.json']);
final librariesSpec =
librariesPath ?? p.joinAll([sdkDir, 'lib', 'libraries.json']);
_validateUserArgs(dart2JsArgs);
args =
dart2JsArgs.toList()..addAll([
Expand Down
13 changes: 8 additions & 5 deletions build_web_compilers/lib/src/dart2wasm_bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,25 @@ final class Dart2WasmBootstrapResult {
Future<Dart2WasmBootstrapResult> bootstrapDart2Wasm(
BuildStep buildStep,
List<String> additionalArguments,
String javaScriptModuleExtension,
) async {
String javaScriptModuleExtension, {
bool unsafeAllowUnsupportedModules = false,
}) async {
return await _resourcePool.withResource(
() => _bootstrapDart2Wasm(
buildStep,
additionalArguments,
javaScriptModuleExtension,
unsafeAllowUnsupportedModules: unsafeAllowUnsupportedModules,
),
);
}

Future<Dart2WasmBootstrapResult> _bootstrapDart2Wasm(
BuildStep buildStep,
List<String> additionalArguments,
String javaScriptModuleExtension,
) async {
String javaScriptModuleExtension, {
bool unsafeAllowUnsupportedModules = false,
}) async {
final dartEntrypointId = buildStep.inputId;
final moduleId = dartEntrypointId.changeExtension(
moduleExtension(dart2wasmPlatform),
Expand All @@ -75,7 +78,7 @@ Future<Dart2WasmBootstrapResult> _bootstrapDart2Wasm(
try {
allDeps = (await module.computeTransitiveDependencies(
buildStep,
throwIfUnsupported: true,
throwIfUnsupported: !unsafeAllowUnsupportedModules,
))..add(module);
} on UnsupportedModules catch (e) {
final librariesString = (await e.exactLibraries(buildStep).toList())
Expand Down
11 changes: 7 additions & 4 deletions build_web_compilers/lib/src/dev_compiler_bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@ final stackTraceMapperPath =
/// available to the app by making them inputs of this build action.
Future<void> bootstrapDdc(
BuildStep buildStep, {
DartPlatform? platform,
Iterable<AssetId> requiredAssets = const [],
String entrypointExtension = jsEntrypointExtension,
required bool? nativeNullAssertions,
bool usesWebHotReload = false,
bool unsafeAllowUnsupportedModules = false,
}) async {
platform = ddcPlatform;
// Ensures that the sdk resources are built and available.
await _ensureResources(buildStep, requiredAssets);

final dartEntrypointId = buildStep.inputId;
final moduleId = buildStep.inputId.changeExtension(moduleExtension(platform));
final moduleId = buildStep.inputId.changeExtension(
moduleExtension(ddcPlatform),
);
final module = Module.fromJson(
json.decode(await buildStep.readAsString(moduleId)) as Map<String, dynamic>,
);
Expand All @@ -56,6 +57,7 @@ Future<void> bootstrapDdc(
module,
buildStep,
computeStronglyConnectedComponents: !usesWebHotReload,
throwIfUnsupported: !unsafeAllowUnsupportedModules,
);
} on UnsupportedModules catch (e) {
final librariesString = (await e.exactLibraries(buildStep).toList())
Expand Down Expand Up @@ -251,11 +253,12 @@ Future<List<AssetId>> _ensureTransitiveJsModules(
Module module,
BuildStep buildStep, {
bool computeStronglyConnectedComponents = true,
bool throwIfUnsupported = true,
}) async {
// Collect all the modules this module depends on, plus this module.
final transitiveDeps = await module.computeTransitiveDependencies(
buildStep,
throwIfUnsupported: true,
throwIfUnsupported: throwIfUnsupported,
computeStronglyConnectedComponents: computeStronglyConnectedComponents,
);

Expand Down
Loading