diff --git a/pkgs/native_assets_builder/CHANGELOG.md b/pkgs/native_assets_builder/CHANGELOG.md index 5c0c915aa..1f61e0a23 100644 --- a/pkgs/native_assets_builder/CHANGELOG.md +++ b/pkgs/native_assets_builder/CHANGELOG.md @@ -1,5 +1,6 @@ -## 0.3.3-wip +## 0.4.0-wip +- **Breaking change**: Split out the `KernelAsset`s from normal `Asset`s. - Bump `package:native_assets_cli` to path dependency. ## 0.3.2 diff --git a/pkgs/native_assets_builder/lib/native_assets_builder.dart b/pkgs/native_assets_builder/lib/native_assets_builder.dart index aa8c1971d..9dfa400af 100644 --- a/pkgs/native_assets_builder/lib/native_assets_builder.dart +++ b/pkgs/native_assets_builder/lib/native_assets_builder.dart @@ -3,5 +3,5 @@ // BSD-style license that can be found in the LICENSE file. export 'package:native_assets_builder/src/build_runner/build_runner.dart'; -export 'package:native_assets_builder/src/model/asset.dart'; +export 'package:native_assets_builder/src/model/kernel_assets.dart'; export 'package:native_assets_builder/src/package_layout/package_layout.dart'; diff --git a/pkgs/native_assets_builder/lib/src/model/asset.dart b/pkgs/native_assets_builder/lib/src/model/asset.dart deleted file mode 100644 index f98cf7de2..000000000 --- a/pkgs/native_assets_builder/lib/src/model/asset.dart +++ /dev/null @@ -1,73 +0,0 @@ -// 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. - -import 'package:native_assets_cli/native_assets_cli_internal.dart'; - -import '../utils/yaml.dart'; - -/// Asset at absolute path [uri]. -class AssetRelativePath implements AssetPath { - final Uri uri; - - AssetRelativePath(this.uri); - - // Never used in native_assets_cli, but the interface must be implemented. - @override - Map toYaml() => throw UnimplementedError(); -} - -extension AssetIterable on Iterable { - Iterable whereLinkMode(LinkMode linkMode) => - where((e) => e.linkMode == linkMode); - - Map> get assetsPerTarget { - final result = >{}; - for (final asset in this) { - final assets = result[asset.target] ?? []; - assets.add(asset); - result[asset.target] = assets; - } - return result; - } - - Map>> toDartConst() => { - for (final entry in assetsPerTarget.entries) - entry.key.toString(): _combineMaps(entry.value - .map((e) => { - e.id: _toDartConst(e.path), - }) - .toList()) - }; - - Map toNativeAssetsFileEncoding() => { - 'format-version': [1, 0, 0], - 'native-assets': toDartConst(), - }; - - String toNativeAssetsFile() => yamlEncode(toNativeAssetsFileEncoding()); -} - -List _toDartConst(AssetPath path) { - switch (path) { - case AssetAbsolutePath _: - return ['absolute', path.uri.toFilePath()]; - case AssetRelativePath _: - return ['relative', path.uri.toFilePath()]; - case AssetSystemPath _: - return ['system', path.uri.toFilePath()]; - case AssetInProcess _: - return ['process']; - default: - assert(path is AssetInExecutable); - return ['executable']; - } -} - -Map _combineMaps(Iterable> maps) { - final result = {}; - for (final map in maps) { - result.addAll(map); - } - return result; -} diff --git a/pkgs/native_assets_builder/lib/src/model/kernel_assets.dart b/pkgs/native_assets_builder/lib/src/model/kernel_assets.dart new file mode 100644 index 000000000..11638ff03 --- /dev/null +++ b/pkgs/native_assets_builder/lib/src/model/kernel_assets.dart @@ -0,0 +1,143 @@ +// 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. + +/// Library defining the `native_assets.yaml` format for embedding in a Dart +/// kernel file. +/// +/// The `native_assets.yaml` embedded in a kernel file has a different format +/// from the assets passed in the `build_output.yaml` from individual native +/// assets builds. This library defines the format of the former so that it +/// can be reused in `package:dartdev` and `package:flutter_tools`. +/// +/// The format should be consistent with `pkg/vm/lib/native_assets/` in the +/// Dart SDK. +library kernel_native_assets; + +import 'package:native_assets_cli/native_assets_cli_internal.dart'; + +import '../utils/yaml.dart'; + +class KernelAssets { + final List assets; + + KernelAssets(this.assets); + + String toNativeAssetsFile() { + final assetsPerTarget = >{}; + for (final asset in assets) { + final assets = assetsPerTarget[asset.target] ?? []; + assets.add(asset); + assetsPerTarget[asset.target] = assets; + } + + final yamlContents = { + 'format-version': [1, 0, 0], + 'native-assets': { + for (final entry in assetsPerTarget.entries) + entry.key.toString(): { + for (final e in entry.value) e.id: e.path.toYaml(), + } + }, + }; + + return yamlEncode(yamlContents); + } +} + +class KernelAsset { + final String id; + final Target target; + final KernelAssetPath path; + + KernelAsset({ + required this.id, + required this.target, + required this.path, + }); +} + +abstract class KernelAssetPath { + List toYaml(); +} + +/// Asset at absolute path [uri] on the target device where Dart is run. +class KernelAssetAbsolutePath implements KernelAssetPath { + final Uri uri; + + KernelAssetAbsolutePath(this.uri); + + static const _pathTypeValue = 'absolute'; + + @override + List toYaml() => [_pathTypeValue, uri.toFilePath()]; +} + +/// Asset at relative path [uri], relative to the 'dart file' executed. +/// +/// The 'dart file' executed can be one of the following: +/// +/// 1. The `.dart` file when executing `dart path/to/script.dart`. +/// 2. The `.kernel` file when executing from a kernel file. +/// 3. The `.aotsnapshot` file when executing from an AOT snapshot with the Dart +/// AOT runtime. +/// 4. The executable when executing a Dart app compiled with `dart compile exe` +/// to a single file. +/// +/// Note when writing your own embedder, make sure the `Dart_CreateIsolateGroup` +/// or similar calls set up the `script_uri` parameter correctly to ensure +/// relative path resolution works. +class KernelAssetRelativePath implements KernelAssetPath { + final Uri uri; + + KernelAssetRelativePath(this.uri); + + static const _pathTypeValue = 'relative'; + + @override + List toYaml() => [_pathTypeValue, uri.toFilePath()]; +} + +/// Asset is avaliable on the system `PATH`. +/// +/// [uri] only contains a file name. +class KernelAssetSystemPath implements KernelAssetPath { + final Uri uri; + + KernelAssetSystemPath(this.uri); + + static const _pathTypeValue = 'system'; + + @override + List toYaml() => [_pathTypeValue, uri.toFilePath()]; +} + +/// Asset is loaded in the process and symbols are available through +/// `DynamicLibrary.process()`. +class KernelAssetInProcess implements KernelAssetPath { + KernelAssetInProcess._(); + + static final KernelAssetInProcess _singleton = KernelAssetInProcess._(); + + factory KernelAssetInProcess() => _singleton; + + static const _pathTypeValue = 'process'; + + @override + List toYaml() => [_pathTypeValue]; +} + +/// Asset is embedded in executable and symbols are available through +/// `DynamicLibrary.executable()`. +class KernelAssetInExecutable implements KernelAssetPath { + KernelAssetInExecutable._(); + + static final KernelAssetInExecutable _singleton = KernelAssetInExecutable._(); + + factory KernelAssetInExecutable() => _singleton; + + static const _pathTypeValue = 'executable'; + + @override + List toYaml() => [_pathTypeValue]; +} diff --git a/pkgs/native_assets_builder/pubspec.yaml b/pkgs/native_assets_builder/pubspec.yaml index e4fa2e12d..f3b227cd3 100644 --- a/pkgs/native_assets_builder/pubspec.yaml +++ b/pkgs/native_assets_builder/pubspec.yaml @@ -1,7 +1,7 @@ name: native_assets_builder description: >- This package is the backend that invokes top-level `build.dart` scripts. -version: 0.3.3-wip +version: 0.4.0-wip repository: https://github.com/dart-lang/native/tree/main/pkgs/native_assets_builder environment: diff --git a/pkgs/native_assets_builder/test/model/asset_test.dart b/pkgs/native_assets_builder/test/model/kernel_assets_test.dart similarity index 63% rename from pkgs/native_assets_builder/test/model/asset_test.dart rename to pkgs/native_assets_builder/test/model/kernel_assets_test.dart index 0272a790a..8b8e92b6b 100644 --- a/pkgs/native_assets_builder/test/model/asset_test.dart +++ b/pkgs/native_assets_builder/test/model/kernel_assets_test.dart @@ -4,9 +4,8 @@ // ignore_for_file: undefined_hidden_name -import 'package:native_assets_builder/src/model/asset.dart'; -import 'package:native_assets_cli/native_assets_cli_internal.dart' - hide AssetIterable, AssetRelativePath; +import 'package:native_assets_builder/src/model/kernel_assets.dart'; +import 'package:native_assets_cli/native_assets_cli_internal.dart'; import 'package:test/test.dart'; void main() { @@ -15,50 +14,43 @@ void main() { final foo3Uri = Uri(path: 'libfoo3.so'); final barUri = Uri(path: 'path/to/libbar.a'); final blaUri = Uri(path: 'path/with spaces/bla.dll'); - final assets = [ - Asset( + final assets = KernelAssets([ + KernelAsset( id: 'foo', - path: AssetAbsolutePath(fooUri), + path: KernelAssetAbsolutePath(fooUri), target: Target.androidX64, - linkMode: LinkMode.dynamic, ), - Asset( + KernelAsset( id: 'foo2', - path: AssetRelativePath(foo2Uri), + path: KernelAssetRelativePath(foo2Uri), target: Target.androidX64, - linkMode: LinkMode.dynamic, ), - Asset( + KernelAsset( id: 'foo3', - path: AssetSystemPath(foo3Uri), + path: KernelAssetSystemPath(foo3Uri), target: Target.androidX64, - linkMode: LinkMode.dynamic, ), - Asset( + KernelAsset( id: 'foo4', - path: AssetInExecutable(), + path: KernelAssetInExecutable(), target: Target.androidX64, - linkMode: LinkMode.dynamic, ), - Asset( + KernelAsset( id: 'foo5', - path: AssetInProcess(), + path: KernelAssetInProcess(), target: Target.androidX64, - linkMode: LinkMode.dynamic, ), - Asset( + KernelAsset( id: 'bar', - path: AssetAbsolutePath(barUri), + path: KernelAssetAbsolutePath(barUri), target: Target.linuxArm64, - linkMode: LinkMode.static, ), - Asset( + KernelAsset( id: 'bla', - path: AssetAbsolutePath(blaUri), + path: KernelAssetAbsolutePath(blaUri), target: Target.windowsX64, - linkMode: LinkMode.dynamic, ), - ]; + ]); final assetsDartEncoding = '''format-version: - 1 @@ -92,13 +84,4 @@ native-assets: final fileContents = assets.toNativeAssetsFile(); expect(fileContents, assetsDartEncoding); }); - - test('List whereLinkMode', () async { - final assets2 = assets.whereLinkMode(LinkMode.dynamic); - expect(assets2.length, 6); - }); - - test('satisfy coverage', () async { - expect(() => assets[1].toYaml(), throwsUnimplementedError); - }); }